Public feed #888444

Untitled

public text v1 · immutable
Raw Edit
·published 2008-02-02 03:14 UTC
rendered paste body
// --------------------
// projects/date/Date.h
// Copyright (C) 2007
// Glenn P. Downing
// --------------------

#ifndef Date_h
#define Date_h

// --------
// includes
// --------

#include <cassert>   // assert
#include <cstddef>   // size_t
#include <iostream>  // ostream
#include <stdexcept> // invalid_argument
#include <string>	 // 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) {
            // <your code>
            // 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 {

           	 // <your code>
            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) {
            // <your code>
            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) {
            // <your code>
            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) {
            // <your code>
            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