void test_DMconstants(){ Julian jDate; Gregorian gDate; for(int i = 0;i<100;i++){ jDate.add_year(1); gDate.add_year(1); TS_ASSERT_EQUALS(jDate.month_this_year(),12); TS_ASSERT_EQUALS(gDate.month_this_year(),12); } for(int i = 0;i<100;i++){ jDate += 5; gDate += 5; TS_ASSERT_EQUALS(jDate.days_per_week(),7); TS_ASSERT_EQUALS(gDate.days_per_week(),7); } }
Gregorian Gregorian::subtract_years(Gregorian const& date, year_t n) { auto y = date.year() - n; auto m = date.month(); auto d = date.day(); if (m == 2 && d == 29 && !is_gregorian_leapyear(y)) d = 28; return Gregorian(year_t(y), month_t(m), day_t(d), date.hour(), date.minute(), date.second()); }
Gregorian Gregorian::add_months(Gregorian const& date, month_t n) { /*auto m = date.month() + n; auto y = date.year() + (m - 1) / 12; m = (m - 1) % 12 + 1; auto d = gregorian_days_in_month(m, is_gregorian_leapyear(y)); if (date.day() < d) d = date.day();*/ year_t y = date.year() + n / 12; month_t m = date.month() + n % 12; auto adjust = (m - 1) / 12 + (m - 12) / 12; y = y + adjust; m = m - adjust * 12; day_t d = min(date.day(), gregorian_days_in_month(m, is_gregorian_leapyear(y))); return Gregorian(y, month_t(m), d, date.hour(), date.minute(), date.second()); }
Gregorian Gregorian::subtract_months(Gregorian const& date, month_t n) { //auto m = date.month() - n; //auto y = date.year() - (m - 1) / 12; //m = (m - 1) % 12 + 1; //auto d = gregorian_days_in_month(m, is_gregorian_leapyear(y)); //if (date.day() < d) // d = date.day(); //return Gregorian(y, month_t(m), d, date.hour(), date.minute(), date.second()); year_t y = date.year() - n / 12; month_t m = date.month() - n % 12; auto adjust = (m - 1) / 12 + (m - 12) / 12; y = y + adjust; m = m - adjust * 12; day_t d = min(date.day(), gregorian_days_in_month(m, is_gregorian_leapyear(y))); return Gregorian(y, month_t(m), d, date.hour(), date.minute(), date.second()); }
Gregorian::Gregorian(const Gregorian & g) : Date(gyear, gmonth, gday){ init(); int j_day = g.mod_julian_day(); change_date(j_day); }
inline second_t second(Gregorian const& greg) { return greg.second(); }
inline minute_t minute(Gregorian const& greg) { return greg.minute(); }
inline hour_t hour(Gregorian const& greg) { return greg.hour(); }
inline day_t day(Gregorian const& greg) { return greg.day(); }
inline month_t month(Gregorian const& greg) { return greg.month(); }
inline year_t year(Gregorian const& greg) { return greg.year(); }
int main() { using namespace lab2; // Exponera funktionalitet i namnrymden lab2 //////////////////////////////////////////////////////////// // Sätt tiden. OBS skicka inte nedanstående kod till kattis time_t mytime; time(&mytime); set_k_time(mytime); //////////////////////////////////////////////////////////// Julian tj; // ok: defaultkonstruktor ger dagens datum Gregorian gtoday; // ok för gregorian också std::cout << "Idag är det " << gtoday << std::endl; assert(tj - gtoday == 0); Gregorian tg(2006, 10, 31); // ok: sätt datum explicit // följande fungerar också: // Gregorian(2000, Gregorian::October, 31) Date &j = tj; // åtkomst av funktioner genom Dates interface Date &g = tg; Date &today = gtoday; { Julian j1; Date & d1 = j1; Julian j2(d1); Date * dp = &j2; //Julian j3(dp); } time_t tp; time(&tp); struct tm *t = gmtime(&tp); int year = t->tm_year + 1900; int month = t->tm_mon + 1; // månaderna och dagarna int day = t->tm_mday; // indexerade från ETT std::cout << "Testing constructors..." << std::endl; assert(today.year() == year && // rätt initierad today.month() == month && today.day() == day); assert(g.year() == 2006 && // rätt initierad g.month() == 10 && g.day() == 31); // obs! ettindexerade std::cout << "Testing access..." << std::endl; assert(g.days_per_week() == 7); // rätt antal dagar per vecka assert(j.days_per_week() == 7); // rätt antal dagar per vecka assert(g.days_this_month() == 31); // rätt antal dagar denna månad assert(g.months_per_year() == 12); // rätt antal månader per år assert(j.months_per_year() == 12); // rätt antal månader per år assert(g.week_day() == 2); // rätt veckodag std::cout << "Testing manipulation..." << std::endl; ++g; // prefix ökning assert(g.week_day() == 3); // rätt veckodag --g; // prefix minskning assert(g.week_day() == 2); // rätt veckodag g += 2; // lägg till två dagar assert(g.week_day() == 4); // rätt veckodag g -= 3; // dra bort tre dagar g.add_month(); // lägg till en månad g.add_month(-1); // dra bort en månad g.add_year(10); // lägg till tio år. std::cout << "Testing miscellaneous functions..." << std::endl; Julian jj(tj); // kopieringskonstruktor const Gregorian gg; gg.year(); // gg konstant, läsa går bra g = gg; // tilldelning if(g == gg || // jämförelse g != gg || // jämförelse g < gg || // jämförelse g >= gg) // jämförelse {} std::cout << "Testing boundary violations"; Gregorian temp(1900, 1, 1); Date &d = temp; // loopa över dagar och kolla att inga gränser över/underskrids for(int i = 0; i < 100000; ++i, ++d) { if(!(i % 5000)) // utskrift på framsteg { std::cout << "."; flush(std::cout); } int m[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if(d.year() >= 1900 && d.month() >= 1 && d.month() <= 12 && d.day() >= 1 && d.day() <= m[d.month() - 1]) {} else { std::cout << std::endl; std::cout << "boundary checks failed: " << std::endl; std::cout << d.year() << ", " << d.month() << ", " << d.day() << std::endl; return 1; } } std::cout << std::endl; std::cout << "Testing leap years..." << std::endl; // testa om skottåren för sekelskiften fungerar som de ska for(int y = 1958; y < 2500; y += 100) { Gregorian temp(y, 2, 28); Date &e = temp; ++e; // lägg till en dag if((y % 400 == 0 && e.day() == 29) || // skottdag (obs! ETTindexerad) (y % 400 != 0 && e.day() == 1)) // ej skottdag {} else { std::cout << std::endl << "leap day test failed: " << std::endl; std::cout << e.year() << ", " << e.month() << ", " << e.day() << std::endl; return 1; } } // Extra test from lab-pdf Gregorian ggg; Julian jjj; std::cout << "Today it is " << ggg << " gregorian and " << jjj << " julian"; assert(ggg - jjj == 0); if (ggg - jjj == 0) std::cout << ". It is the same date" << std::endl; ggg = jjj; assert(ggg - jjj == 0); if (ggg - jjj == 0) std::cout << "It is still the same date" << std::endl; std::cout << std::endl << "All tests were successful." << std::endl; // följande ska inte gå att kompilera #if 0 gg.leap_year(); // fel: kan inte komma åt protected/private medlem gg = g; // fel: kan inte tilldela konstant ++gg; // fel: kan inte ändra på en konstant #endif return 0; }
//Gregorian-- Gregorian Gregorian::operator--(int unused){ Gregorian result = *this; result.remove_day(); return result; }
//Gregorian++ Gregorian Gregorian::operator++(int unused){ Gregorian result = *this; result.add_day(); return result; }
double Hebrew::nth_kday (double n, double k) const { Gregorian g (rep_.d_year (), rep_.d_month (), rep_.d_day ()); return g.nth_kday (n, k); }
void test_GregMonOverflow(){ Gregorian gDate = Gregorian(1999,01,31); gDate.add_month(1); TS_ASSERT_EQUALS(gDate.day(),28); gDate.add_month(-1); TS_ASSERT_EQUALS(gDate.day(),28); gDate+=3; gDate.add_month(13); TS_ASSERT_EQUALS(gDate.year(),2000); TS_ASSERT_EQUALS(gDate.day(),29); gDate = Gregorian(2099,01,31); gDate.add_month(1); TS_ASSERT_EQUALS(gDate.day(),28); gDate.add_month(-1); TS_ASSERT_EQUALS(gDate.day(),28); gDate+=3; gDate.add_month(13); TS_ASSERT_EQUALS(gDate.year(),2100); TS_ASSERT_EQUALS(gDate.day(),28); }