Skip to content

Instantly share code, notes, and snippets.

@torazuka
Created September 19, 2011 09:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save torazuka/1226229 to your computer and use it in GitHub Desktop.
Save torazuka/1226229 to your computer and use it in GitHub Desktop.
Chapter09_drill05_PPPC++
/*
『ストラウストラップのプログラミング入門』
9章ドリル5(9.7.4バージョン, constメンバ関数)
*/
#include "../../std_lib_facilities.h"
class Date{
public:
enum Month{
jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec
};
Date(int y, Month m, int d); // 日付の有効性を確認して初期化する
void add_year(int n); // Dateをn年増やす
void add_month(int n); // Dateをn月増やす
void add_day(int n); // Dateをn日増やす
void init_day(int y, Month m, int d);
Month month() const { return m; }
int day() const { return d; }
int year() const { return y; }
private:
int y; // 年
Month m;
int d; // 日
};
Date::Date(int y, Month m, int d)
{
init_day(y, m, d);
}
bool leapyear(int y)
// うるう年ならtrueを返す
{
bool result = false;
if(y % 4 == 0 && y % 100 != 0){
result = true;
}
if(y % 400 == 0){
result = true;
}
return result;
}
int get_days_in_month(int y, Date::Month m)
// その月の日数を返す
{
int result = 31;
switch(m){
case Date::feb:
result = (leapyear(y)) ? 29 : 28;
break;
case Date::apr: case Date::jun: case Date::sep: case Date::nov:
result = 30;
break;
}
return result;
}
void Date::init_day(int yy, Month mm, int dd)
// (yy, mm, dd)が有効な日付かどうかを確認する
// そうである場合はddを初期化する
{
if(yy < 1){
error("bad year");
}
if(mm < Date::jan || Date::dec < mm){
error("bad month");
}
if(dd < 1){
error("bad day");
}
if(get_days_in_month(yy, mm) < dd){
error("over day");
}
y = yy;
m = mm;
d = dd;
}
void Date::add_year(int n)
{
y += n;
}
Date::Month int_to_month(int n){
if(n < Date::jan || Date::dec < n){
error("bad month");
}
return Date::Month(n);
}
void Date::add_month(int n)
{
const int months_in_year = Date::dec;
// 月数nを現在の月に足すと、12を超える場合、翌年に繰り越す
if(months_in_year < (m + n)){
add_year(1);
add_month(n - months_in_year);
} else {
m = int_to_month(m + n);
}
}
void Date::add_day(int n)
{
int days_in_month = get_days_in_month(y, m);
// 日数nを現在の日に足すと、当月内の日数を超える場合、翌月に繰り越す
if(days_in_month < (d + n)){
add_month(1);
add_day(n - days_in_month);
} else {
d += n;
}
}
ostream& operator<<(ostream& os, const Date dd)
{
return os << '(' << dd.year()
<< ',' << dd.month()
<< ',' << dd.day() << ')';
}
void f()
{
Date today(1978, Date::jun, 25);
Date tomorrow(today.year(), today.month(), today.day());
tomorrow.add_day(1);
cout << today << '\n' << tomorrow << endl;
}
int main()
{
f();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment