You have just begen your promising programming career at a consulting company know as Big Buck$ Software. For your first task, you have been asked to fix some code left by another programmer. What your fellow programmer has left is a copy of the header files for a date class and some of the methods associated with the class. Your task is to complete the class as defined by the header file and make it operational. The available code includes: main.cpp date.h date.cpp. A listing of the code is shown below.
#include <iostream.h>
#include "date.h"
int main() {
Date a(12,5,2001), b(12,5,2000), c;
c = a;
return 0;
}
#ifndef _DATE_H
#define _DATE_H
#include <iostream.h>
// a class for manipulating dates
//
// Date class represents a date in the Gregorian calendar
// works only for dates after October, 1752
//
// attempts to construct invalid dates, e.g., 15 month,
// or 38th day result in month == 1, day == 1. years aren't checked
// for validity
//
// Date() --- construct default date (today)
// Date(long int days) --- construct date given absolute # of days from
// 1 A.D., e.g., 710,347 = November 12, 1945
//
// Date(int m,int d,int y) --- constructor requires three parameters:
// month, day, year, e.g.,
// Date d(4,8,1956); initializes d to represent
// the date April 8, 1956. Full year is required
//
// void SetDate(int m,int d,int y) --- set date according to parameters:
// month, day, year, e.g.,
// d.SetDate(1,1,2000); sets date d to January
// 1 in the year 2000
//
// int Month() --- return, respectively, month, day, and year
// int Day() corresponding to date with 1 = january,
// int Year() 2 = february, ... 12 = december
//
//
// char * DayName() --- return string corresponding to day of week
// either "Monday", "Tuesday", ... "Sunday"
// char * MonthName() --- return string corresponding to month
// either "January", "February",..."December"
//
// int DaysIn() --- return number of days in month
//
//
// long int Absolute() --- returns absolute # of date assuming
// that Jan 1, 1 AD is day 1. Has property
// that Absolute() % 7 = k, where k = 0 is sunday
// k = 1 is monday, ... k = 6 is saturday
//
// char * ToString() -- returns string version of date, e.g.,
// -- d.SetDate(11,23,1963); then d.ToString()
// returns string "November 23 1963"
// char * DateAscii() -- returns ascii version of date
// (for backward compatibility)
//
// *************************************************
// arithmetic operators for dates
// *************************************************
//
// dates support some addition and subtraction operations
//
// Date d(1,1,1960); // 1960 is a leap year
// d++; // d represents January 2, 1960
// d--; // d is back to January 1, 1960
// d += 31; // d is February 1, 1960
// d -= 32; // d is December 31, 1959
// Date d2 = d + 1; // d2 is January 1, 1960
// Date d3 = 365 + d2; // d3 is December 31, 1961
// Date d4 = d - 1; // d4 is December 30, 1959
//
// *************************************************
class Date
{
public:
// constructors
Date(); // construct date with default value
Date(long int days); // construct date from absolute #
Date(int m,int d,int y); // construct date with specified value
// set date via CheckDate method
// accessor functions
int Month() const; // return month corresponding to date
int Day() const; // return day corresponding to date
int Year() const; // return year corresponding to date
int DaysIn() const; // return # of days in month
char * DayName() const; // "monday", "tuesday", ... or "sunday"
char * MonthName() const; // "january","february",... or "december"
long int Absolute() const; // number of days since 1 A.D. for date
char * ToString() const; // returns string for date in ascii
char * DateAscii() const; // returns string for date in ascii
// mutator functions
void SetDate(int m,int d,int y); // set to specified date
Date operator ++(int); // add one day, postfix operator
Date operator --(int); // subtract one day, postfix operator
Date operator ++(); // add one day, preix operator
Date operator --(); // subtract one day, prefix operator
Date& operator +=(long dx); // add dx, e.g., jan 1 + 31 = feb 1
Date& operator -=(long dx); // subtract dx, e.g., jan 1 - 1 = dec 31
bool Equal(const Date & rhs) const;
bool Less(const Date & rhs) const;
private:
int myDay; // day of week, 0-6
int myMonth; // month, 0-11
int myYear; // year in four digits, e.g., 1899
void CheckDate(int m, int d, int y); // make sure that date is valid
};
// other operators that are not part of the class
Date operator + (const Date & d, long dx); // add dx to date d
Date operator + (int dx, const Date & d); // add dx to date d
Date operator - (const Date & d, long dx); // subtract dx from date d
long operator - (const Date & lhs, const Date & rhs); // subtract dates
ostream &operator<<( ostream &output, const Date &d );
bool operator == (const Date & lhs, const Date & rhs);
bool operator != (const Date & lhs, const Date & rhs);
bool operator < (const Date & lhs, const Date & rhs);
bool operator > (const Date & lhs, const Date & rhs);
bool operator <= (const Date & lhs, const Date & rhs);
bool operator >= (const Date & lhs, const Date & rhs);
// helper methods
static bool IsLeap(int year);
static int DaysInMonth(int month,int year);
#endif
#include "date.h"
#include <time.h>
#include <iostream.h>
#include <string.h>
char * dayNames [] = {"Sunday", "Monday", "Tuesday","Wednesday",
"Thursday","Friday", "Saturday"};
char * monthNames [] = {"January","February","March","April",
"May","June","July","August",
"September","October","November","December"};
char returnString[50];
/////////////////////// constructors //////////////////////////////
Date::Date()
// postcondition: date initialized to default date (today)
{
static struct tm timeHolder;
static struct tm *date = &timeHolder;
time_t tloc;
time(&tloc);
date = localtime(&tloc);
myMonth = date->tm_mon+1;
myDay = date->tm_mday;
myYear = date->tm_year+1900; // struct tm based on 1900
}
Date::Date(long int days)
// postcondition: date initialized corresponding to absolute days
// after 1 A.D.
{
// this code is taken from "Calendrical Calculations, II"
// Reingold and Dershowitz and Clamen
// Software Practice and Experience, V. 23(4) 383-404 (april 1993)
long int prior = days - 1; // prior days
long int years400 = prior / 146097; // # of 400 year cycles
long int days400 = prior % 146097; // days NOT in years400
long int years100 = days400 / 36524; // # 100 yr. cycles not checked
long int days100 = days400 % 36524; // days NOT already included
long int years4 = days100 / 1461; // # 4 yr cycles not checked
long int days4 = days100 % 1461; // days NOT already included
long int year1 = days4 / 365; // # years not already checked
long int day1 = days4 % 365; // days NOT already included
// use "magic formula" from SP&E article
long int finalDay;
long int finalYear = 400*years400 + 100*years100 + 4*years4 + year1;
if (years100 == 4 || year1 == 4){ // December 31 of leap year
finalDay = 366;
}
else{
finalDay = day1 + 1;
finalYear += 1;
}
// now have year and day #, find month and day in month
myMonth = 1;
while (myMonth <= 12 && 0 < finalDay){
finalDay -= DaysInMonth(myMonth,finalYear);
myMonth += 1;
}
myMonth -= 1; // went one to far
finalDay += DaysInMonth(myMonth,finalYear);
myDay = finalDay;
myYear = finalYear;
}
Date::Date(int m, int d, int y)
// postcondition: date properly initialized for date m/d/y (american style)
// exception: if m isn't between 1 and 12, converted to 1
// if d out of range for month, converted to 1
{
CheckDate(m,d,y);
}
/////////////////////// accessor methods //////////////////////////////
long int Date::Absolute() const
// postcondition: returns absolute # days corresponding to Date
// assuming January 1, 1 B.C is day 1
{
int m = 1; // start in January;
int daysBefore = 0; // count # days before month
while (m < myMonth){ // tally # of days in preceding months
daysBefore += DaysInMonth(m,myYear);
m += 1;
}
long int dayYears = 365 * (myYear - 1); // days before this year
// add 1 extra day for each leap year
int leapYears = (myYear - 1) / 4; // initial # of leap years
leapYears -= (myYear - 1) / 100; // subtract years divisible by 100
leapYears += (myYear - 1) / 400; // add back years divisibly by 400
return myDay + daysBefore + dayYears + leapYears;
}
/////////////////////// mutator methods //////////////////////////////
/////////////////////// other methods //////////////////////////////
ostream &operator<<( ostream &output, const Date &d ) {
output << d.DayName() << " " << d.MonthName() << " "
<< d.Day() << ", " << d.Year();
return output; // enables cout << x << y;
}
/////////////////////// helper methods //////////////////////////////
static bool IsLeap(int year)
// postcondition: returns 1 if year is a leap year, else returns 0
{
if (year % 400 == 0){
return true;
}
else if (year % 100 == 0){
return false;
}
else if (year % 4 == 0){
return true;
}
return false;
}
static int DaysInMonth(int month,int year)
// postcondition: returns # of days in month in year
{
int days = 30;
// 30 days hath september, april, june, and november
// other months have 31 as below (except February)
if (month == 1 || month == 3 || month == 5 || month == 7 ||
month == 8 || month == 10 || month == 12){
days = 31;
}
else if (month == 2){ // treat February differently
days = 28;
if (IsLeap(year) == 1){ // add 1 for leap years
days += 1;
}
}
return days;
}