aboutsummaryrefslogtreecommitdiff
path: root/src/date-time.cpp
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2015-03-14 21:20:30 -0500
committerCharles Kerr <charles.kerr@canonical.com>2015-03-14 21:20:30 -0500
commitdb5b700c7c116c73283019b3fbf823a23639a405 (patch)
tree4ae03eb86bb71a9453286e015fcedd00774b2bca /src/date-time.cpp
parent15ec7f61fa84a9a8b40c1c9fcfa6c2a268d3232b (diff)
downloadayatana-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/date-time.cpp')
-rw-r--r--src/date-time.cpp77
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