diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp index a96d3c4f3d..ab3803c131 100644 --- a/src/libqof/qof/gnc-datetime.cpp +++ b/src/libqof/qof/gnc-datetime.cpp @@ -71,6 +71,7 @@ public: void today() { m_greg = boost::gregorian::day_clock::local_day(); } ymd year_month_day() const; std::string format(const char* format) const; + std::string format_zulu(const char* format) const; private: Date m_greg; }; @@ -147,6 +148,7 @@ public: struct tm utc_tm() const { return to_tm(m_time.utc_time()); } std::unique_ptr date() const; std::string format(const char* format) const; + std::string format_zulu(const char* format) const; private: LDT m_time; }; @@ -256,6 +258,18 @@ GncDateTimeImpl::format(const char* format) const return ss.str(); } +std::string +GncDateTimeImpl::format_zulu(const char* format) const +{ + using Facet = boost::posix_time::time_facet; + std::stringstream ss; + //The stream destructor frees the facet, so it must be heap-allocated. + auto output_facet(new Facet(format)); + ss.imbue(std::locale(std::locale(), output_facet)); + ss << m_time.utc_time(); + return ss.str(); +} + /* =================== Presentation-class Implementations ====================*/ /* GncDate */ GncDate::GncDate() : m_impl{new GncDateImpl} {} @@ -337,3 +351,9 @@ GncDateTime::format(const char* format) const { return m_impl->format(format); } + +std::string +GncDateTime::format_zulu(const char* format) const +{ + return m_impl->format_zulu(format); +} diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp index 058f50c275..3942c4b2ed 100644 --- a/src/libqof/qof/gnc-datetime.hpp +++ b/src/libqof/qof/gnc-datetime.hpp @@ -157,10 +157,19 @@ public: * presented. Code letters preceded with % stand in for arguments; * most are the same as described in strftime(3), but there are a few * differences. Consult the boost::date_time documentation. - * @return a std::string containing a representation of the date - * according to the format. + * @return a std::string containing a representation of the date and time in + * the locale's time zone according to the format. */ std::string format(const char* format) const; +/** Format the GncDateTime into a std::string in GMT + * @param format: A cstr describing the way the date and time are + * presented. Code letters preceded with % stand in for arguments; + * most are the same as described in strftime(3), but there are a few + * differences. Consult the boost::date_time documentation. + * @return a std::string containing a representation of the date and time in + * GMT (timezone Z) according to the format. + */ + std::string format_zulu(const char* format) const; private: std::unique_ptr m_impl; diff --git a/src/libqof/qof/test/gtest-gnc-datetime.cpp b/src/libqof/qof/test/gtest-gnc-datetime.cpp index 9d1b3cf47b..6d378a819c 100644 --- a/src/libqof/qof/test/gtest-gnc-datetime.cpp +++ b/src/libqof/qof/test/gtest-gnc-datetime.cpp @@ -77,6 +77,13 @@ TEST(gnc_datetime_functions, test_format) EXPECT_EQ(atime.format("%d-%m-%Y"), "13-11-2045"); } +TEST(gnc_datetime_functions, test_format_zulu) +{ + GncDateTime atime(2394187200); //2045-11-13 12:00:00 Z + //Date only to finesse timezone issues. It will still fail in +12 DST. + EXPECT_EQ(atime.format_zulu("%d-%m-%Y %H:%M:%S"), "13-11-2045 12:00:00"); +} + //This is a bit convoluted because it uses GncDate's GncDateImpl constructor and year_month_day() function. There's no good way to test the former without violating the privacy of the implementation. TEST(gnc_datetime_functions, test_date) {