X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Ftime%2Fdatetime.cpp;h=86238863282340996339071236f51b4a212e193f;hb=48c4fc071cb96dc7ed1da8f89894ad5c27eaa48c;hp=4c109758eb0e95d8b191d50152866856bbe48b46;hpb=1d05ea78e94897160f978f6103c5f4acf7fb43d3;p=libs%2Fcore.git diff --git a/source/time/datetime.cpp b/source/time/datetime.cpp index 4c10975..8623886 100644 --- a/source/time/datetime.cpp +++ b/source/time/datetime.cpp @@ -1,18 +1,26 @@ -/* $Id$ */ +/* $Id$ + +This file is part of libmspcore +Copyright © 2006 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include #include #include #include "../core/except.h" #include "datetime.h" #include "timestamp.h" +#include "units.h" using namespace std; namespace { -inline bool is_leap_year(int32_t y) +inline bool is_leap_year(int y) { return y%4==0 && (y%100 || y%400==0); } -inline uint8_t month_days(int32_t y, uint8_t m) +inline unsigned char month_days(int y, unsigned char m) { switch(m) { @@ -43,57 +51,35 @@ inline int cmp_(T a, T b) namespace Msp { namespace Time { -DateTime::DateTime(const TimeStamp &ts): - year(1970), - month(1), - mday(1), - hour(0), - minute(0), - second(0), - usec(0) +DateTime::DateTime(const TimeStamp &ts) { - add_raw(ts.raw()); + init(ts); } -DateTime::DateTime(int32_t y, uint8_t m, uint8_t d): - year(y), - month(m), - mday(d), - hour(0), - minute(0), - second(0), - usec(0) +DateTime::DateTime(const TimeStamp &ts, const TimeZone &tz) { - validate(); + init(ts); + convert_timezone(tz); } -DateTime::DateTime(int32_t y, uint8_t m, uint8_t d, uint8_t h, uint8_t n, uint8_t s): - year(y), - month(m), - mday(d), - hour(h), - minute(n), - second(s), - usec(0) +DateTime::DateTime(int y, unsigned char m, unsigned char d) { - validate(); + init(y, m, d, 0, 0, 0, 0); } -DateTime::DateTime(int32_t y, uint8_t m, uint8_t d, uint8_t h, uint8_t n, uint8_t s, uint32_t u): - year(y), - month(m), - mday(d), - hour(h), - minute(n), - second(s), - usec(u) +DateTime::DateTime(int y, unsigned char m, unsigned char d, unsigned char h, unsigned char n, unsigned char s) { - validate(); + init(y, m, d, h, n, s, 0); } -void DateTime::add_days(int32_t days) +DateTime::DateTime(int y, unsigned char m, unsigned char d, unsigned char h, unsigned char n, unsigned char s, unsigned u) { - unsigned new_year=year; + init(y, m, d, h, n, s, u); +} + +void DateTime::add_days(int days) +{ + int new_year=year; /* Leap years have a 400 year cycle, so any 400 consecutive years have a constant number of days (400*365+97=146097) */ @@ -116,6 +102,7 @@ void DateTime::add_days(int32_t days) new_year+=cycles*4; // See how many non-leap-years we counted as leap years and reclaim the lost days + // XXX This breaks with negative years unsigned missed_leap_days=((year-fudge)%100+cycles*4)/100; if((year-fudge)%400+cycles*4>=400) --missed_leap_days; @@ -133,8 +120,8 @@ void DateTime::add_days(int32_t days) // We passed a leap year - decrement days if(days==0) { + days=is_leap_year(new_year-fudge)?365:364; --new_year; - days=is_leap_year(new_year)?365:364; } else --days; @@ -157,6 +144,17 @@ void DateTime::add_days(int32_t days) mday+=days; } +void DateTime::set_timezone(const TimeZone &tz) +{ + zone=tz; +} + +void DateTime::convert_timezone(const TimeZone &tz) +{ + add_raw((zone.get_offset()-tz.get_offset()).raw()); + zone=tz; +} + DateTime DateTime::operator+(const TimeDelta &td) const { DateTime dt(*this); @@ -170,6 +168,19 @@ DateTime &DateTime::operator+=(const TimeDelta &td) return *this; } +DateTime DateTime::operator-(const TimeDelta &td) const +{ + DateTime dt(*this); + dt.add_raw(-td.raw()); + return dt; +} + +DateTime &DateTime::operator-=(const TimeDelta &td) +{ + add_raw(-td.raw()); + return *this; +} + int DateTime::cmp(const DateTime &dt) const { if(int c=cmp_(year, dt.year)) @@ -192,9 +203,9 @@ int DateTime::cmp(const DateTime &dt) const TimeStamp DateTime::get_timestamp() const { if(year<-289701 || year>293641) - throw Exception("DateTime is not representable as a TimeStamp"); + throw InvalidState("DateTime is not representable as a TimeStamp"); - int64_t raw=(((hour*60LL)+minute)*60+second)*1000000+usec; + RawTime raw=(((hour*60LL)+minute)*60+second)*1000000+usec; int days=(year-1970)*365; days+=(year-1)/4-(year-1)/100+(year-1)/400-477; for(unsigned i=1; i(offs/Time::min)); + ss<<(offs(raw/86400000000LL); raw%=86400000000LL; if(raw<0) { - ++days; + --days; raw+=86400000000LL; }