You are on page 1of 7

date, a C++ class for dates.

Bernt Arne Ødegaard


16 February 2007

This is the documentation for a C++ date class.


The date class is pretty rough. A date is stored as three integers (year, month, day). Functions for
comparing dates, incrementing dates are provided. Also calculation of time between dates.

1 Setting up.
Compile date.cc, put into library libdate.a, make library available.
Put date.h on header le path.

2 Dening dates.
Examples of date denitions
date d;
date d(19930624)
date d(24,6,1993) Note the day, month, year sequence.

3 Operations on dates.
Let d, d1, d2 be dates.
The following operations are dened:
Iteration: d++, ++d, d, d .
Logical comparisions >, >=, <, <=, ! =, ==.
Some aritmetric operations are dened, which has a meaning that may seem strange at rst, but they
are natural for usage purposes.
Adding/Subtracting x number of days from a data:
d=d1+7 gives d the date 7 days after date d1.
d=d1-7 gives d the date 7 days before date d1.
Finding the number of days between 2 dates. i=d1-d2. Here i is an integer that is the number of days
between d1 and d2. i will be negative if d1 < d2.
Example:
date d1(30,6,1993); date d2(19930610);
i = d1-d2
Gives i the value 20, the number of days between 10 jun 93 and 30 jun 93.

4 date.h
Header le that denes the class and its procedures
// le: date.h

1
// author: Bernt A Oedegaard.
#ifndef DATE H

#dene DATE H

#include <iostream>
#include <fstream>
#include <string>
using namespace std; 10

class date {
protected:
int year ;
int month ;
int day ;
public:
date();

date( const long& d);


date( const int& d, const int& m, const int& y); 20

bool valid( void) const;


int day() const;
int month() const;
int year() const;
void set day ( const int& day );
void set month ( const int& month );
void set year (const int& year ); 30

date operator ++(); // prex


date operator ++( int); // postx
date operator −−(); // prex
date operator −−(int); // postx
};

date operator +=(date&, const int&); // increment and decrement


date operator −=(date&, const int&); // (with number of days)
40
bool operator == ( const date&, const date&); // comparison operators
bool operator != (const date&, const date&);
bool operator < (const date&, const date&);
bool operator > (const date&, const date&);
bool operator <= (const date&, const date&);
bool operator >= (const date&, const date&);

ostream& operator << ( ostream& os, const date& d); // output operator
long long date( const date&); // calculations 50
date next date( const date&);
date previous date(const date&);

date operator +( const date&, const int&); // add number of days


date operator −(const date&, const int&);
date next month( const date& d); // specic incrementaiton
date add months( const date& d, const int& no months);
///////////////////////////// inline denitions ////////// 60

inline date::date(){ year = 0; month = 0; day = 0;};


inline int date::day() const { return day ; };
inline int date::month() const { return month ; };
inline int date::year() const { return year ; };

2
inline void date::set day ( const int& day) { date::day = day; };
inline void date::set month( const int& month) { date::month = month; };
inline void date::set year (const int& year) { date::year = year; };
70
#endif

5 date.cc
Implementation

/* date.cc. This is the implementaton of a date class.


* author: Bernt Arne Oedegaard
* history:
* 18 nov 95: Set const correctness
* 29 Dec 93: Use the boolean type for true/false returns.
* June 93: Created, translated my old Pascal routines.
*/
#include "date.h"
10
///////////////////////////// construction //////////
date::date( const int& d, const int& m, const int& y) {

day = d;
month = m;
if (y<100) {
if (y<25){ // the simplest possible x for Y2K, choose 2K if year < 20 (unusual
// that dates before 1930 is referred to
year = 2000+y;
} 20
else {
year = 1900+y;
};
} // assume XX is shorthand for 19XX
else { year = y;};
};

date::date( const long& date){

year = date/10000;
if (year < 100) { year = 1900+year ;}; /* assume XX is shorthand for 19XX 30
(if >2000 presumably uses all four) */
month = (date%10000)/100;
day = date%100;
}

bool date::valid() const {


// This function will check the given date is valid or not.
// If the date is not valid then it will return the value false.
// Need some more checks on the year, though
if (year <0) return false; 40
if (month >12 | | month <1) return false;
if (day >31 | | day <1) return false;
if ((day ==31 &&
( month ==2 || month ==4 || month ==6 || month ==9 || month ==11) ) )

return false;
if ( day ==30 && month ==2) return false;
if ( year <2000){
if ((day ==29 && month ==2) && !((year −1900)%4==0)) return false;
};
if ( year >2000){ 50
if ((day ==29 && month ==2) && !((year −2000)%4==0)) return false;
};
return true;

3
};

date date::operator ++( int){ // postx operator


date d = * this;
*this = next date(d);

return d; 60
}

date date::operator ++(){ // prex operator


*this = next date(*this);
return *this;
}

date date::operator −−(int){ // postx operator, return current value


date d = * this;
*this = previous date(* this); 70
return d;
}

date date::operator −−(){ // prex operator, return new value


*this = previous date(* this);
return *this;
};

date next date( const date& d){ 80


date ndat;

if (!d.valid()) { return ndat; };

ndat=date((d.day()+1),d.month(),d.year()); if (ndat.valid()) return ndat;

ndat=date(1,(d.month()+1),d.year()); if (ndat.valid()) return ndat;


ndat = date(1,1,(d.year()+1)); return ndat;
}

date previous date( const date& d){

date ndat;

if (!d.valid()) { return ndat; }; // return zero 90


ndat = date((d.day() −1),d.month(),d.year()); if (ndat.valid()) return ndat;
ndat = date(31,(d.month()−1),d.year()); if (ndat.valid()) return ndat;

ndat = date(30,(d.month()−1),d.year()); if (ndat.valid()) return ndat;

ndat = date(29,(d.month()−1),d.year()); if (ndat.valid()) return ndat;

ndat = date(28,(d.month()−1),d.year()); if (ndat.valid()) return ndat;

ndat = date(31,12,(d.year()−1)); return ndat;


};

long long date(const date& d) {


if (d.valid()){ return d.year() * 10000 + d.month() * 100 + d.day(); }; 100
return −1;
};

ostream & operator << (ostream& os, const date& d){


if (d.valid()) { os << " " << long date(d) << " " ; }
else { os << " invalid date "; };

return os;
}

date operator + (const date& d, const int& days){ // IMPROVE! 110


if (!d.valid()){return date();};
if (days<0) {return (d−(−days));};
date d1=d;

for (int day=1;day<=days;++day){ d1=next date(d1); };

return d1;
}

date operator += (date& d, const int& days){

4
d = (d+days);

return d; 120
};

date operator − (const date& d, const int& days) {

if (!d.valid()) { return date();};


if (days<0) { return (d+(−days));};
date d1=d;

for (int day=0; day <days; ++day){ d1=previous date(d1); }; // IMPROVE!


return d1;
};
130
date operator −= (date& d, const int& days){

return (d−days);
}

date add months( const date& indate, const int& no months)

// nd date no months months earlier/later


// this is brute force, haven't gotten round to some cleverer implementation.
{
date d=indate;

// cout << d << endl; 140


if (!d.valid()) return indate;
if (no months==0) return indate;
int no years = no months/12;
if (no years!=0){ d.set year(indate.year()+no years); };

int nmonths=no months%12;


if (nmonths==0) return d;
date ndat;

if (no months>0) {
if (d.month()+nmonths<=12) { 150
ndat=date((d.day()),d.month()+nmonths,d.year());

if (ndat.valid()) return ndat;

ndat=date(d.day() −1,(d.month()+nmonths),d.year());
if (ndat.valid()) return ndat;

ndat=date(d.day() −2,(d.month()+nmonths),d.year());
if (ndat.valid()) return ndat;

ndat=date(d.day() −3,(d.month()+nmonths),d.year());
if (ndat.valid()) return ndat;

}
else { 160
ndat=date((d.day()),d.month()+nmonths −12,d.year()+1);
if (ndat.valid()) return ndat;

ndat=date((d.day() −1),d.month()+nmonths−12,d.year()+1);
if (ndat.valid()) return ndat;

ndat=date((d.day() −2),d.month()+nmonths−12,d.year()+1);
if (ndat.valid()) return ndat;

ndat=date((d.day() −3),d.month()+nmonths−12,d.year()+1);
if (ndat.valid()) return ndat;

};
} 170
else {
if (d.month()+nmonths>=1) {
ndat=date((d.day()),d.month()+nmonths,d.year());

if (ndat.valid()) return ndat;

ndat=date(d.day() −1,(d.month()+nmonths),d.year());
if (ndat.valid()) return ndat;

ndat=date(d.day() −2,(d.month()+nmonths),d.year());
if (ndat.valid()) return ndat;

ndat=date(d.day() −3,(d.month()+nmonths),d.year());
if (ndat.valid()) return ndat; 180
}
else {
ndat=date((d.day()),d.month()+nmonths+12,d.year() −1);

5
if (ndat.valid()) return ndat;

ndat=date((d.day() −1),d.month()+nmonths+12,d.year()−1);
if (ndat.valid()) return ndat;

ndat=date((d.day() −2),d.month()+nmonths+12,d.year()−1);
if (ndat.valid()) return ndat;

ndat=date((d.day() −3),d.month()+nmonths+12,d.year()−1);
if (ndat.valid()) return ndat; 190
};
};
cerr << " Error in Add month " << endl;

return indate; // something wroong if arrive here


};

date next month( const date& d) {

return add months(d,1);

};
200

6 Testing
To see how the date class is used, here are some examples

// tst date.cc
// author: Bernt A Oedegaard
void test date simple(){

cout << "TESTING DATE SIMPLE " << endl;


cout << " construction: date(1,1,1998):" << date(1,1,1998) <<endl;
cout << " construction: date(19980101):" << date(19980101) <<endl;
cout << " increment: ++date(1,1,1998):" << ++date(1,1,1998) << endl;
cout << " decrement: --date(1,1,1998):" << −−date(1,1,1998) << endl;
date d(1,1,2006); 10
cout << "valid date(1,1,2006) ?" << date(1,1,2006).valid() << endl;
cout << "valid date(33,1,2006) ?" << date(33,1,2006).valid() << endl;
cout << "DONE TESTING DATE SIMPLE " << endl;
}

void compare dates (date d1, date d2) {

cout << " Comparing " << d1 << "and" << d2 << endl;
cout << " is" << d1 <<"equal to " << d2 ;
if (d1==d2){ cout << "YES"; } else { cout << "NO"; };
cout << endl; 20
cout << " is" << d1 <<"different from" << d2 ;

if (d1!=d2){ cout << "YES"; } else { cout << "NO"; };


cout << endl;

cout << " is" << d1 <<"less than " << d2 ;

if (d1<d2){ cout << "YES"; } else { cout << "NO"; };


cout << endl;

cout << " is" << d1 <<"greater than " << d2 ;

if (d1>d2){ cout << "YES"; } else { cout << "NO"; };


cout << endl;

}; 30

void test date comparisons (){

cout << "TESTING DATE COMPARISONS " << endl;

date d1(930725);

date d2(930810);

compare dates (d1,d2);

compare dates (d1,d1);

6
cout << "DONE TESTING DATE COMPARISONS " << endl;

};
40

void test adding subtracting date(){

cout << "TESTING DATE CHANGING " << endl;

date d(1,1,1990);

cout << " next date to " << d << " is " << next date(d) << endl;
cout << " add 25 days to " << d << " gives " << d+25 << endl;
cout << " add 125 days to " << d << " gives " << d+125 << endl;
cout << " previous date to " << d << " is " << previous date(d) << endl;
cout << " subtract 25 days from " << d << " gives " << d−25 << endl; 50
cout << " subtract 125 days from " << d << " gives " << d−125 << endl;
cout << " next month relative to " << d << " is " << next month(d) << endl;
cout << " end of month relative to " << d << " is " << end of month(d) << endl;
cout << " add 6 months relative to " << d << " is " << add months(d,6) << endl;
cout << "DONE TESTING DATE CHANGING " << endl;
};

void tst print(){

date d(1,1,2001);

cout << d << endl; 60


};

void test date() {

cout << "TESTING DATE " << endl;

test date simple();

test date comparisons();

test adding subtracting date();

tst print();

cout << "DONE TESTING DATE " << endl;

}; 70

You might also like