View Single Post
Old 02-22-2005, 08:59 AM   #8 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
First things first. Learn to design a decent class first. The math behind all this is hard enough. So let's setup a decent class and then see if you can manage it from here. If not, then feel free to come back.

Date.h
Code:
#ifndef DATE_H
#define DATE_H

#include <ctime>

class Date
{
public:
  enum month
  {jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec };
  enum week_day
  { mon = 1, tue, wed, thu, fri, sat, sun  };
  static const int REFORM_YEAR;
  static const month REFORM_MONTH;
  static const unsigned REFORM_DAY_NUMBER;
public: //Ctors et al. only.
  Date();
  Date(month, int, int);
public: //Accessors only. int get_year() const;
  int get_day() const;
  month get_month() const;
public:
  static int days_in_month(month, int);
  static bool is_leap(int);
protected:
  void set_date(month, int, int);
  unsigned long calc_day_number() const;
private:
  month month_;
  int   day_;
  int   year_;
  unsigned long daynumber_;
};

/***************** inlines ***************/ inline int Date::get_year() const
{
  return year_;
}
//----------------------------------------- inline int Date::get_day() const
{
  return day_;
}
//----------------------------------------- inline Date::month Date::get_month() const
{
  return month_;
}
//----------------------------------------- #endif //DATE_H
Date.cpp
Code:
#include "Date.h" const int Date::REFORM_YEAR = 1582;
const unsigned Date::REFORM_DAY_NUMBER = 577737L;
const Date::month Date::REFORM_MONTH  = Date::oct;

//-----------------------------------------------------

Date::Date()
{
  set_date(jan, 1, 1);
}

//-----------------------------------------------------

Date::Date(month m, int d, int y)
{
  set_date(m, d, y);
}

//----------------------------------------------------- void Date::set_date(month m, int d, int y)
{
  month_ = m;
  day_   = d;
  year_  = y;
  daynumber_ = calc_day_number();
}

//---------------------------------------------------- bool Date::is_leap(int yr)
{
  if( yr % 4 ) return false;
  if( yr < REFORM_YEAR ) return true;
  if( yr % 100 ) return true;
  if( yr % 400 ) return false;
  return true;
}

//----------------------------------------------------- int Date::days_in_month(month mth, int yr)
{
  static const int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
  if( yr == REFORM_YEAR && mth == REFORM_MONTH )
  {
    return 21;
  }
  return days[mth] + (feb == mth && is_leap(yr));
}

//----------------------------------------------------- unsigned long Date::calc_day_number() const
{
  long days;
  long year  = (long)year_ - 1L;
  days = year * 365L + year / 4L - year / 100L + year / 400L;
  //Years before 1582 were all leap if it is divisible by 4. if( year > REFORM_YEAR )
  {
    days += 12;
  }
  else
  {
    days += year / 100L;
    days -= year / 400L;
  }
  for( int i = jan; i < month_; ++i )
  {
    days += days_in_month((month)i, year_);
  }
  days += day_;
  //Adjust for the 10 missing days (Oct 4 - Oct 15, 1582). if( days > REFORM_DAY_NUMBER )
  {
    days -= 10L;
  }
  
  return days;
}
main.cpp
Code:
#include "Date.h" #include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
  Date dt;
  cout << dt.get_day() << " " << dt.get_month() << " " << dt.get_year() << endl;
  
  cin.get();
  return 0;
}
The calc_day_number() method is your key to success if you want to implement the next_day() function.
Here are the global steps:
1) Implement an overloaded operator+().
2) Implement a method that calculates the total amount of days added with the number of days you want. Make it calculate the year, month and day.

For example if day_number is day_number+1, then check if the resulting day_number > refordaynumber. If it is, then add 10 days to the resulting day_number! That is because there are 10 days missing because pope Gregor XXLLLCXXX (or something) reformed it.

3) The year_ is then obviously: (int)daynumber_ / 365. Duh.
4) The day_ is INITIALLY: (int)daynumber_ % 365L. Convince your self!
5) Adjust the initial day IF resulting years_ < 1700.
6) And/Or adjust the initial day_, taking leap years into account.

Etcetera etcetera. I needed to study for this too. And now I want a break. See how far you can get. Be welcome anytime. But beware, I do not like lazy folks.
__________________
Valmont is offline   Reply With Quote