aboutsummaryrefslogtreecommitdiff
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
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.
-rw-r--r--include/datetime/date-time.h10
-rw-r--r--src/date-time.cpp77
2 files changed, 71 insertions, 16 deletions
diff --git a/include/datetime/date-time.h b/include/datetime/date-time.h
index 4be35f7..6e73ff3 100644
--- a/include/datetime/date-time.h
+++ b/include/datetime/date-time.h
@@ -38,13 +38,15 @@ public:
static DateTime NowLocal();
static DateTime Local(int years, int months, int days, int hours, int minutes, int seconds);
+ DateTime();
explicit DateTime(time_t t);
- explicit DateTime(GDateTime* in=nullptr);
- DateTime& operator=(GDateTime* in);
+ DateTime(GTimeZone* tz, GDateTime* dt);
DateTime& operator=(const DateTime& in);
DateTime to_timezone(const std::string& zone) const;
+ DateTime start_of_day() const;
+ DateTime start_of_minute() const;
+ DateTime add_days(int days) const;
DateTime add_full(int years, int months, int days, int hours, int minutes, double seconds) const;
- void reset(GDateTime* in=nullptr);
GDateTime* get() const;
GDateTime* operator()() const {return get();}
@@ -69,6 +71,8 @@ public:
bool is_set() const { return m_dt != nullptr; }
private:
+ void reset(GTimeZone*, GDateTime*);
+ std::shared_ptr<GTimeZone> m_tz;
std::shared_ptr<GDateTime> m_dt;
};
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