gnucash maint: Implement a faster date-time serialization function.

John Ralls jralls at code.gnucash.org
Fri Jan 4 19:35:21 EST 2019


Updated	 via  https://github.com/Gnucash/gnucash/commit/9fa7b7f9 (commit)
	from  https://github.com/Gnucash/gnucash/commit/137c920d (commit)



commit 9fa7b7f94041ea69d586baa5c61e9ccf5ef9677f
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Dec 28 16:39:02 2018 -0800

    Implement a faster date-time serialization function.
    
    Has the side effect of recording all date-times in XML files in UTC
    instead of local time with a timezone.

diff --git a/libgnucash/backend/sql/gnc-sql-column-table-entry.cpp b/libgnucash/backend/sql/gnc-sql-column-table-entry.cpp
index e48c165..1c30006 100644
--- a/libgnucash/backend/sql/gnc-sql-column-table-entry.cpp
+++ b/libgnucash/backend/sql/gnc-sql-column-table-entry.cpp
@@ -448,8 +448,9 @@ GncSqlColumnTableEntryImpl<CT_TIME>::add_to_query(QofIdTypeConst obj_name,
     if (t64 > MINTIME && t64 < MAXTIME)
     {
         GncDateTime time(t64);
-        vec.emplace_back (std::make_pair (std::string{m_col_name},
-                                          time.format_zulu ("'%Y-%m-%d %H:%M:%S'")));
+        std::string timestr("'");
+        timestr += time.format_iso8601() + "'";
+        vec.emplace_back (std::make_pair (std::string{m_col_name}, timestr));
     }
     else
     {
diff --git a/libgnucash/backend/sql/gnc-transaction-sql.cpp b/libgnucash/backend/sql/gnc-transaction-sql.cpp
index 9867577..fce7f6c 100644
--- a/libgnucash/backend/sql/gnc-transaction-sql.cpp
+++ b/libgnucash/backend/sql/gnc-transaction-sql.cpp
@@ -853,7 +853,7 @@ convert_query_term_to_sql (const GncSqlBackend* sql_be, const gchar* fieldName,
             query_date_t date_data = (query_date_t)pPredData;
 
             GncDateTime time(date_data->date);
-            sql << time.format_zulu ("%Y-%m-%d %H:%M:%S");
+            sql << time.format_iso8601();
         }
         else if (strcmp (pPredData->type_name, QOF_TYPE_INT32) == 0)
         {
diff --git a/libgnucash/backend/xml/sixtp-dom-generators.cpp b/libgnucash/backend/xml/sixtp-dom-generators.cpp
index 6cdf405..4ddd0bf 100644
--- a/libgnucash/backend/xml/sixtp-dom-generators.cpp
+++ b/libgnucash/backend/xml/sixtp-dom-generators.cpp
@@ -35,6 +35,7 @@ extern "C"
 #include "sixtp-utils.h"
 
 #include <kvp-frame.hpp>
+#include <gnc-datetime.hpp>
 
 static QofLogModule log_module = GNC_MOD_IO;
 
@@ -136,13 +137,12 @@ time64_to_dom_tree (const char* tag, const time64 time)
 {
     xmlNodePtr ret;
     g_return_val_if_fail (time != INT64_MAX, NULL);
-    auto date_str = gnc_print_time64 (time, "%Y-%m-%d %H:%M:%S %q");
-    if (!date_str)
+    auto date_str = GncDateTime(time).format_iso8601();
+    if (date_str.empty())
         return NULL;
     ret = xmlNewNode (NULL, BAD_CAST tag);
     xmlNewTextChild (ret, NULL, BAD_CAST "ts:date",
-                     checked_char_cast (date_str));
-    g_free (date_str);
+                     checked_char_cast (const_cast<char*>(date_str.c_str())));
     return ret;
 }
 
diff --git a/libgnucash/engine/gnc-date.cpp b/libgnucash/engine/gnc-date.cpp
index 756d12c..cacc35f 100644
--- a/libgnucash/engine/gnc-date.cpp
+++ b/libgnucash/engine/gnc-date.cpp
@@ -1115,13 +1115,12 @@ char *
 gnc_time64_to_iso8601_buff (time64 time, char * buff)
 {
     constexpr size_t max_iso_date_length = 32;
-    const char* format = "%Y-%m-%d %H:%M:%S %q";
 
     if (! buff) return NULL;
     try
     {
         GncDateTime gncdt(time);
-        auto sstr = gncdt.format(format);
+        auto sstr = gncdt.format_iso8601();
 
         memset(buff, 0, sstr.length() + 1);
         strncpy(buff, sstr.c_str(), sstr.length());
diff --git a/libgnucash/engine/gnc-datetime.cpp b/libgnucash/engine/gnc-datetime.cpp
index 238be2d..70d9275 100644
--- a/libgnucash/engine/gnc-datetime.cpp
+++ b/libgnucash/engine/gnc-datetime.cpp
@@ -235,6 +235,7 @@ public:
     std::unique_ptr<GncDateImpl> date() const;
     std::string format(const char* format) const;
     std::string format_zulu(const char* format) const;
+    std::string format_iso8601() const;
 private:
     LDT m_time;
     static const TD time_of_day[3];
@@ -457,6 +458,14 @@ GncDateTimeImpl::format_zulu(const char* format) const
     return ss.str();
 }
 
+std::string
+GncDateTimeImpl::format_iso8601() const
+{
+    auto str = boost::posix_time::to_iso_extended_string(m_time.utc_time());
+    str[10] = ' ';
+    return str.substr(0, 19);
+}
+
 /* Member function definitions for GncDateImpl.
  */
 GncDateImpl::GncDateImpl(const std::string str, const std::string fmt) :
@@ -585,6 +594,12 @@ GncDateTime::format_zulu(const char* format) const
     return m_impl->format_zulu(format);
 }
 
+std::string
+GncDateTime::format_iso8601() const
+{
+    return m_impl->format_iso8601();
+}
+
 /* GncDate */
 GncDate::GncDate() : m_impl{new GncDateImpl} {}
 GncDate::GncDate(int year, int month, int day) :
diff --git a/libgnucash/engine/gnc-datetime.hpp b/libgnucash/engine/gnc-datetime.hpp
index 27b7e83..8f714f5 100644
--- a/libgnucash/engine/gnc-datetime.hpp
+++ b/libgnucash/engine/gnc-datetime.hpp
@@ -148,6 +148,10 @@ public:
  *  GMT (timezone Z) according to the format.
  */
     std::string format_zulu(const char* format) const;
+/** Format the GncDateTime into a gnucash-style iso8601 string in UTC.
+ *  @return a std::string in the format YYYY-MM-DD HH:MM:SS.
+ */
+    std::string format_iso8601() const;
 
 private:
     std::unique_ptr<GncDateTimeImpl> m_impl;
diff --git a/libgnucash/engine/test/test-gnc-date.c b/libgnucash/engine/test/test-gnc-date.c
index 2c38565..a1f1e9c 100644
--- a/libgnucash/engine/test/test-gnc-date.c
+++ b/libgnucash/engine/test/test-gnc-date.c
@@ -1407,20 +1407,15 @@ static gchar*
 format_timestring (time64 t, TZOffset tz)
 {
     static const unsigned tzlen = MAX_DATE_LENGTH - 26;
-    char *fmt = "%Y-%m-%d %H:%M:%S %z";
-    struct tm tm;
+    char *fmt = "%Y-%m-%d %H:%M:%S";
+    struct tm *tm;
     char buf[MAX_DATE_LENGTH + 1];
     char tzbuf[tzlen];
     memset(tzbuf, 0, sizeof(tzbuf));
-    gnc_localtime_r(&t, &tm);
-#if PLATFORM(WINDOWS)
-    strftime(tzbuf, sizeof(tzbuf), "%Z", &tm);
-#else
-    strftime(tzbuf, sizeof(tzbuf), "%z", &tm);
-#endif
+    tm = gnc_gmtime(&t);
     memset (buf, 0, sizeof(buf));
-    strftime(buf, sizeof(buf), fmt, &tm);
-
+    strftime(buf, sizeof(buf), fmt, tm);
+    free(tm);
     return g_strdup(buf);
 }
 



Summary of changes:
 libgnucash/backend/sql/gnc-sql-column-table-entry.cpp |  5 +++--
 libgnucash/backend/sql/gnc-transaction-sql.cpp        |  2 +-
 libgnucash/backend/xml/sixtp-dom-generators.cpp       |  8 ++++----
 libgnucash/engine/gnc-date.cpp                        |  3 +--
 libgnucash/engine/gnc-datetime.cpp                    | 15 +++++++++++++++
 libgnucash/engine/gnc-datetime.hpp                    |  4 ++++
 libgnucash/engine/test/test-gnc-date.c                | 15 +++++----------
 7 files changed, 33 insertions(+), 19 deletions(-)



More information about the gnucash-changes mailing list