diff options
author | Charles Kerr <charles.kerr@canonical.com> | 2015-03-14 21:20:30 -0500 |
---|---|---|
committer | Charles Kerr <charles.kerr@canonical.com> | 2015-03-14 21:20:30 -0500 |
commit | db5b700c7c116c73283019b3fbf823a23639a405 (patch) | |
tree | 4ae03eb86bb71a9453286e015fcedd00774b2bca /src | |
parent | 15ec7f61fa84a9a8b40c1c9fcfa6c2a268d3232b (diff) | |
download | ayatana-indicator-datetime-db5b700c7c116c73283019b3fbf823a23639a405.tar.gz ayatana-indicator-datetime-db5b700c7c116c73283019b3fbf823a23639a405.tar.bz2 ayatana-indicator-datetime-db5b700c7c116c73283019b3fbf823a23639a405.zip |
Add DateTime::start_of_day() to use instead of the add_hours(-hours()) trick, which doesn't work on days when DST changes.
Implementing this requires DateTime objects to keep their own GTimeZone pointer, since the one inside GDateTime is private and can't be used for DateTime::start_of_day()'s call to g_date_time_new(). As a result the public API of DateTime changes, since we'll need a GTimeZone when constructing or assigning from a GDateTime pointer.
Diffstat (limited to 'src')
-rw-r--r-- | src/date-time.cpp | 77 |
1 files changed, 64 insertions, 13 deletions
diff --git a/src/date-time.cpp b/src/date-time.cpp index a139ea9..33b1590 100644 --- a/src/date-time.cpp +++ b/src/date-time.cpp @@ -27,42 +27,49 @@ namespace datetime { **** ***/ -DateTime::DateTime(GDateTime* gdt) +DateTime::DateTime() { - reset(gdt); } -DateTime& DateTime::operator=(GDateTime* gdt) +DateTime::DateTime(GTimeZone* gtz, GDateTime* gdt) { - reset(gdt); - return *this; + g_return_if_fail((gtz==nullptr) == (gdt==nullptr)); + + reset(gtz, gdt); } DateTime& DateTime::operator=(const DateTime& that) { + m_tz = that.m_tz; m_dt = that.m_dt; return *this; } DateTime::DateTime(time_t t) { + auto gtz = g_time_zone_new_local(); auto gdt = g_date_time_new_from_unix_local(t); - reset(gdt); + reset(gtz, gdt); + g_time_zone_unref(gtz); g_date_time_unref(gdt); } DateTime DateTime::NowLocal() { + auto gtz = g_time_zone_new_local(); auto gdt = g_date_time_new_now_local(); - DateTime dt(gdt); + DateTime dt(gtz, gdt); + g_time_zone_unref(gtz); g_date_time_unref(gdt); return dt; } DateTime DateTime::Local(int year, int month, int day, int hour, int minute, int seconds) { + auto gtz = g_time_zone_new_local(); auto gdt = g_date_time_new_local (year, month, day, hour, minute, seconds); - DateTime dt(gdt); + DateTime dt(gtz, gdt); + g_time_zone_unref(gtz); g_date_time_unref(gdt); return dt; } @@ -71,20 +78,51 @@ DateTime DateTime::to_timezone(const std::string& zone) const { auto gtz = g_time_zone_new(zone.c_str()); auto gdt = g_date_time_to_timezone(get(), gtz); - DateTime dt(gdt); + DateTime dt(gtz, gdt); g_time_zone_unref(gtz); g_date_time_unref(gdt); return dt; } +DateTime DateTime::start_of_day() const +{ + g_assert(is_set()); + g_assert(m_tz.get() != nullptr); + + int y=0, m=0, d=0; + ymd(y, m, d); + auto gdt = g_date_time_new(m_tz.get(), y, m, d, 0, 0, 0); + DateTime dt(m_tz.get(), gdt); + g_date_time_unref(gdt); + return dt; +} + +DateTime DateTime::start_of_minute() const +{ + g_assert(is_set()); + g_assert(m_tz.get() != nullptr); + + int y=0, m=0, d=0; + ymd(y, m, d); + auto gdt = g_date_time_new(m_tz.get(), y, m, d, hour(), minute(), 0); + DateTime dt(m_tz.get(), gdt); + g_date_time_unref(gdt); + return dt; +} + DateTime DateTime::add_full(int years, int months, int days, int hours, int minutes, double seconds) const { auto gdt = g_date_time_add_full(get(), years, months, days, hours, minutes, seconds); - DateTime dt(gdt); + DateTime dt(m_tz.get(), gdt); g_date_time_unref(gdt); return dt; } +DateTime DateTime::add_days(int days) const +{ + return add_full(0, 0, days, 0, 0, 0); +} + GDateTime* DateTime::get() const { g_assert(m_dt); @@ -135,12 +173,25 @@ int64_t DateTime::to_unix() const return g_date_time_to_unix(get()); } -void DateTime::reset(GDateTime* in) +void DateTime::reset(GTimeZone* gtz, GDateTime* gdt) { - if (in) + g_return_if_fail ((gdt==nullptr) == (gtz==nullptr)); // all or nothin' + + if (gtz) + { + auto deleter = [](GTimeZone* tz){g_time_zone_unref(tz);}; + m_tz = std::shared_ptr<GTimeZone>(g_time_zone_ref(gtz), deleter); + g_assert(m_tz); + } + else + { + m_tz.reset(); + } + + if (gdt) { auto deleter = [](GDateTime* dt){g_date_time_unref(dt);}; - m_dt = std::shared_ptr<GDateTime>(g_date_time_ref(in), deleter); + m_dt = std::shared_ptr<GDateTime>(g_date_time_ref(gdt), deleter); g_assert(m_dt); } else |