Finally! I did it! Assignment #4 is complete, and I can manipulate dates pretty effing easily now.
No doubt there is already some vastly superior date manipulation library already out there… stupid school.
Just kidding. I learned a LOT with this assignment.
#include <iostream>
using namespace std;
class Date {
private:
/*
|
\ PRIVATE DATA
|
*/
static const int EpochYear = 1752;
static const int EpochMonth = 9;
static const int EpochDay = 14;
static const int EpochDoW = 5; // must define day of week of epoch (5 = Thursday)
int epochdays; // this is the number of days since September 14, 1752
int month,day,year; // the current value of month/day/year
bool validdate;
/*
|
\ PRIVATE MEMBER FUNCTIONS
|
*/
bool isLeapYear(int year){
// check if this year is a leap year, return false if not
bool leapyear;
if ((year % 4) == 0){
if (year % 100 == 0){
leapyear = false;
if (year % 400 == 0){
leapyear = true;
}
} else {
leapyear = true;
}
} else {
leapyear = false;
}
return leapyear;
}
int daysInMonth(int m, int y){
// returns the number of days in a given month (1 = January, etc)
// invalid month/year combinations return -1
int days = -1;
int febdays = 28;
if (isLeapYear(y))
febdays = 29;
switch (m){
case 1: case 3: case 5: case 7: case 8: case 10: case 12: days = 31; break;
case 2: days = febdays; break;
case 4: case 6: case 9: case 11: days = 30; break;
default: days = -1; break;
}
return days;
}
int dayOfYear(int m, int d, int y){
// return the day of year (eg, Jan 1 = 1, Dec 1 = 365 (or 366 on leap years))
int daycount = 0; // holds number of days elapsed this year
// leap through every fully elapsed month
for (int i=1; i<m; i++){
daycount += daysInMonth(i,y);
}
// don't forget to add the elapsed days of this month
daycount += d;
return daycount;
}
int getEpochDays(int m, int d, int y){
// for a given m/d/y, return the number of days since the epoch, 9/14/1752
int daycount; // this will be count of epochdays
int thisDOY = dayOfYear(m,d,y);
int epochDOY = dayOfYear(EpochMonth,EpochDay,EpochYear);
// subtract day of year from epoch
daycount = thisDOY - epochDOY;
// add days for each fully elapsed year
while (y > EpochYear){
y--; // decrement year now to avoid overcounting leap year
if (isLeapYear(y)){
daycount += 366;
} else {
daycount += 365;
}
}
return daycount;
}
void convertEpochDays(int daysSinceEpoch, int& m, int& d, int& y){
// SHOULD NOT be using m/d/y variables to calculate!
int mm = EpochMonth;
int dd = EpochDay;
int yyyy = EpochYear;
while (daysSinceEpoch > 0){
//cout << "days left: "<< daysSinceEpoch << endl;
if (daysSinceEpoch >= 366){
// we have at least a year left
yyyy++; // increment year now to avoid taking credit for already elapsed leap day
if (isLeapYear(yyyy)){
daysSinceEpoch -= 366;
} else {
daysSinceEpoch -= 365;
}
} else if (daysSinceEpoch >= 31){
// we have 31 or more days left
if (mm == 12){
daysSinceEpoch -= daysInMonth(mm,yyyy);
mm = 1;
yyyy++;
} else {
daysSinceEpoch -= daysInMonth(mm,yyyy);
mm++;
}
} else {
// we have up to 30 days left
if (dd < daysInMonth(mm,yyyy)){
dd++;
daysSinceEpoch--;
} else if (dd == daysInMonth(mm,yyyy)){
mm++;
dd = 1;
daysSinceEpoch--;
} else {
cout << "You didn't account for something!"<< endl;
}
}
}
m = mm;
d = dd;
y = yyyy;
}
public:
// constructors
Date(){
// set default date to September 14, 1752
month = 9;
day = 14;
year = 1752;
epochdays = 0;
validdate = true;
}
Date(int m, int d, int y){
/*
| Sets date with user input, verifies if proper date is provided
\ for any problem with user input: status member function will return false
| - do not allow date prior to September 14, 1752
*/
// set defaults, assume the user is wrong about everything
month = 9;
day = 14;
year = 1752;
epochdays = 0;
validdate = false;
// month cannot be less than 1 or greater than 12
if (m >= 1 && m <= 12){
// month is valid. so far, so good
// what about days? they can less than <1 or greater than that month's days
if (d >= 1 && d <= daysInMonth(m,y)){
// date format is valid, but is it at least 9/14/1752?
if (getEpochDays(m,d,y) >= 0){
month = m;
day = d;
year = y;
epochdays = getEpochDays(m,d,y);
validdate = true;
}
}
}
}
// member functions
bool status(void){
// if date setting has any problems, returns false
return validdate;
}
bool setdate(int m, int d, int y){
/*
| Sets date with user input, verifies if proper date is provided
\ for any problem with user input, returns false, no date change made
| - do not allow date prior to September 14, 1752
*/
bool validnewdate = false; // assume invalid new date (guilty until proven innocent)
// month cannot be less than 1 or greater than 12
if (m >= 1 && m <= 12){
// month is valid. so far, so good
// what about days? they can less than <1 or greater than that month's days
if (d >= 1 && d <= daysInMonth(m,y)){
// date format is valid, but is it at least 9/14/1752?
if (getEpochDays(m,d,y) >= 0){
month = m;
day = d;
year = y;
epochdays = getEpochDays(m,d,y);
validdate = true;
validnewdate = true;
}
}
}
return validnewdate;
}
int getmonth(void) const {
// returns month if status is true (Jan=1, Feb=2, etc)
// if status is false, returns -1
if (validdate)
return month;
else
return -1;
}
int getday(void) const {
// returns day if status is true; if status is false returns -1
if (validdate)
return day;
else
return -1;
}
int getyear(void) const {
// returns year if status is true (eg: 2009,2010,1976)
// if status is false returns -1
if (validdate)
return year;
else
return -1;
}
bool advance(int i){
// adds i days to date, i may be positive or negative
// returns false if there any problems
if ((epochdays + i) >= 0){
// increment epochdays to advance date
epochdays += i;
// now that we know the new count of epochdays, set m/d/y
convertEpochDays(epochdays,month,day,year);
return true;
} else {
cerr << "Could not set date prior to September 14, 1752." << endl;
return false;
}
}
int dleft(void){
// returns days left in the year (eg, December 1st would return 30)
int daysleft;
if (validdate)
daysleft = dayOfYear(12,31,year) - dayOfYear(month,day,year);
else
daysleft = -1;
return daysleft;
}
int diff(Date d){
/*
| determine the number of day difference from argument
\ positive return value means date in argument is after class date, negative means before
| (eg; if object date is 2/3/09 and argument d is 2/6/09, function will return 3
*/
int m,dom,y,diffDays;
m = d.getmonth();
dom = d.getday();
y = d.getyear();
if (d.status())
diffDays = epochdays - getEpochDays(m,dom,y);
else
diffDays = 0; // return 0 for comparisons to invalid dates
return diffDays;
}
int dofw(void){
/*
| returns day of week (Sunday=1,Monday=2, etc)
\ NOTE: September 14th, 1752 was a Thursday (dofw = 5)
| So if (epochdays % 7) == 0 then dofw = 5; 1 then dofw = 6; etc
*/
int dayofweek;
if (validdate)
dayofweek = ((epochdays % 7) + EpochDoW);
else
dayofweek = -1;
return dayofweek;
}
};








Post a Comment