// -------------------- // projects/date/Date.h // Copyright (C) 2007 // Glenn P. Downing // -------------------- #ifndef Date_h #define Date_h // -------- // includes // -------- #include // assert #include // size_t #include // ostream #include // invalid_argument #include // string using namespace std; //to use string without std // ---------- // namespaces // ---------- namespace cs { namespace projects { namespace date { // ---- // Date // ---- class Date { public: // -------- // typedefs // -------- typedef std::size_t size_type; typedef long value_type; // ----------- // operator == // ----------- /** * O(1) in space * O(1) in time * @param lhs a date * @param rhs a date * @return true if lhs is equal to rhs */ friend bool operator == (const Date& lhs, const Date& rhs) { return( lhs.pday==rhs.pday && lhs.pmonth==rhs.pmonth && lhs.pyear==rhs.pyear); } // ---------- // operator < // ---------- /** * O(1) in space * O(1) in time * @param lhs a date * @param rhs a date * @return true if lhs is less than rhs */ friend bool operator < (const Date& lhs, const Date& rhs) { //cout << lhs.to_days() << " < " << rhs.to_days() << endl; return(lhs.to_days() < rhs.to_days() ); } // ---------- // operator + // ---------- /** * O(1) in space * O(1) in time * @param lhs a date * @param rhs the number of days to add (may be negative!) * @return the date resulting from adding rhs * @throws std::invalid_argument if the resulting date precedes 1 Jan 1600 */ friend Date operator + (Date lhs, value_type rhs) { return lhs += rhs;} // ---------- // operator - // ---------- /** * O(1) in space * O(1) in time * @param lhs a date * @param rhs the number of days to subtract (may be negative!) * @return the date resulting from subtracting rhs * @throws std::invalid_argument if the resulting date precedes 1 Jan 1600 */ friend Date operator - (Date lhs, value_type rhs) { return lhs -= rhs;} /** * O(1) in space * O(1) in time * @param lhs a date * @param rhs a date * @return the number of days between the dates (lhs - rhs) */ friend value_type operator - (const Date& lhs, const Date& rhs) { return 0;} // ----------- // operator << // ----------- /** * O(1) in space * O(1) in time * @param lhs an ostream * @param rhs a date * @return the ostream * output a string representation of the date (e.g. "3 Feb 2008") */ friend std::ostream& operator << (std::ostream& lhs, const Date& rhs) { // // return lhs << "3 Feb 2008";} return lhs << rhs.pday << " " << Date::month_names[rhs.pmonth] << " " << rhs.pyear; } private: //private data size_type pday; //day state The p is for private size_type pmonth; //month state size_type pyear; //year state static size_type days_in_month[]; //used to get days in month, non leap year static size_type days_in_month_ly[]; //used to get days in month, leap year static size_type days_in_month_summed[]; //used to get summed days in month, non leap year static size_type days_in_month_summed_ly[]; //used to get summed days in month, leap year static string month_names[]; //used for the string month description // ----- // valid // ----- /** * O(1) in space * O(1) in time * @return true if date is valid */ bool valid () const { // size_type ubound_day; //will hold the upper bound for day if(pyear<1600) return false; //year range check if(pmonth<1 || pmonth>12 ) return false; //month range check ubound_day = days_in_month[pmonth]; //upper bound for days in month if(pmonth==2) ubound_day += leap_year(); //add one day to feb if leap year, implict cast here from bool to size_type if(pday<1 || pday>ubound_day) return false; //day range check //we passed all the checks return true; } // ----------- // constructor // ----------- /** * O(1) in space * O(1) in time * @param days >= 0 */ Date (size_type days) { // assert(valid());} // ------- // to_days // ------- /** * O(1) in space * O(1) in time * @return the number of days since 1 Jan 1600 */ size_type to_days () const { return pday + days_in_month_summed[pmonth - 1] + (pyear-1600-1) * 365; // fix, just a rough estimate } public: // ----------- // constructor // ----------- /** * O(1) in space * O(1) in time * @param day >= 1 && <= 31 * @param month >= 1 && <= 12 * @param year >= 1600 * @throws std::invalid_argument if the resulting date is invalid */ Date (size_type day, size_type month, size_type year) { pday=day; pmonth=month; pyear=year; if (!valid()) throw std::invalid_argument("Date::Date()");} // Default copy, destructor, and copy assignment. // Date (const Date&); // ~Date (); // Date& operator = (const Date&); // ----------- // operator += // ----------- /** * O(1) in space * O(1) in time * @param days the number of days to add (may be negative!) * @return the date resulting from adding days * @throws std::invalid_argument if the resulting date precedes 1 Jan 1600 */ Date& operator += (value_type days) { // return *this;} // ----------- // operator -= // ----------- /** * O(1) in space * O(1) in time * @param days the number of days to subtract (may be negative!) * @return the date resulting from subtracting days * @throws std::invalid_argument if the resulting date precedes 1 Jan 1600 */ Date& operator -= (value_type days) { // return *this;} // --------- // leap_year // --------- /** * O(1) in space * O(1) in time * @return true if the date is in a leap year */ bool leap_year () const { return ((pyear % 4 == 0 && pyear % 100 != 0) || pyear % 400 == 0); //checks for leap year }}; //Static Declerations std::size_t Date::days_in_month[] = {0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // Non leap year std::size_t Date::days_in_month_ly[] = {0,31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // leap year std::size_t Date::days_in_month_summed[] = {0,31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; // Non leap year std::size_t Date::days_in_month_summed_ly[] = {0,31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}; // leap year string Date::month_names[]={"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; } // date } // projects } // cs #endif // Date_h