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.
This commit is contained in:
John Ralls 2018-12-28 16:39:02 -08:00
parent 137c920d06
commit 9fa7b7f940
7 changed files with 33 additions and 19 deletions

View File

@ -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
{

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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());

View File

@ -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) :

View File

@ -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;

View File

@ -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);
}