gnucash master: Multiple changes pushed
John Ralls
jralls at code.gnucash.org
Sat May 2 23:21:43 EDT 2015
Updated via https://github.com/Gnucash/gnucash/commit/9ea1dd0f (commit)
via https://github.com/Gnucash/gnucash/commit/280589a3 (commit)
via https://github.com/Gnucash/gnucash/commit/25be764c (commit)
via https://github.com/Gnucash/gnucash/commit/b215d629 (commit)
via https://github.com/Gnucash/gnucash/commit/9fafb612 (commit)
via https://github.com/Gnucash/gnucash/commit/48a5473b (commit)
via https://github.com/Gnucash/gnucash/commit/9fbc447f (commit)
via https://github.com/Gnucash/gnucash/commit/f87f9ca0 (commit)
via https://github.com/Gnucash/gnucash/commit/bcedeff3 (commit)
via https://github.com/Gnucash/gnucash/commit/ac515d6c (commit)
via https://github.com/Gnucash/gnucash/commit/a8028ec7 (commit)
via https://github.com/Gnucash/gnucash/commit/f46e9f02 (commit)
via https://github.com/Gnucash/gnucash/commit/db6b7d36 (commit)
via https://github.com/Gnucash/gnucash/commit/671a6ac7 (commit)
via https://github.com/Gnucash/gnucash/commit/d2f80a94 (commit)
via https://github.com/Gnucash/gnucash/commit/2dde36d0 (commit)
via https://github.com/Gnucash/gnucash/commit/d4a3d862 (commit)
via https://github.com/Gnucash/gnucash/commit/78b974ad (commit)
via https://github.com/Gnucash/gnucash/commit/ab72874e (commit)
via https://github.com/Gnucash/gnucash/commit/3f87f56e (commit)
via https://github.com/Gnucash/gnucash/commit/cbb01c94 (commit)
via https://github.com/Gnucash/gnucash/commit/e5861dc1 (commit)
via https://github.com/Gnucash/gnucash/commit/10daa27a (commit)
via https://github.com/Gnucash/gnucash/commit/01f5a9c0 (commit)
via https://github.com/Gnucash/gnucash/commit/307c08e2 (commit)
via https://github.com/Gnucash/gnucash/commit/09356976 (commit)
via https://github.com/Gnucash/gnucash/commit/d0ae8c37 (commit)
via https://github.com/Gnucash/gnucash/commit/d0b916c6 (commit)
via https://github.com/Gnucash/gnucash/commit/5a378e1e (commit)
via https://github.com/Gnucash/gnucash/commit/197d43f4 (commit)
via https://github.com/Gnucash/gnucash/commit/327ef838 (commit)
via https://github.com/Gnucash/gnucash/commit/e938b39f (commit)
via https://github.com/Gnucash/gnucash/commit/4f90e4e0 (commit)
via https://github.com/Gnucash/gnucash/commit/99efb5d4 (commit)
via https://github.com/Gnucash/gnucash/commit/23687ee2 (commit)
via https://github.com/Gnucash/gnucash/commit/eb3bafed (commit)
via https://github.com/Gnucash/gnucash/commit/ae11e350 (commit)
via https://github.com/Gnucash/gnucash/commit/154911e2 (commit)
via https://github.com/Gnucash/gnucash/commit/32852ec4 (commit)
via https://github.com/Gnucash/gnucash/commit/83f2627b (commit)
via https://github.com/Gnucash/gnucash/commit/6fd68c3c (commit)
via https://github.com/Gnucash/gnucash/commit/9f2d3843 (commit)
via https://github.com/Gnucash/gnucash/commit/fb6992f3 (commit)
via https://github.com/Gnucash/gnucash/commit/23d4e4a5 (commit)
via https://github.com/Gnucash/gnucash/commit/c7ca7850 (commit)
via https://github.com/Gnucash/gnucash/commit/a07c78e5 (commit)
via https://github.com/Gnucash/gnucash/commit/6c6153b5 (commit)
via https://github.com/Gnucash/gnucash/commit/6673128b (commit)
via https://github.com/Gnucash/gnucash/commit/19f64ad3 (commit)
via https://github.com/Gnucash/gnucash/commit/2061026f (commit)
via https://github.com/Gnucash/gnucash/commit/d98ddd12 (commit)
via https://github.com/Gnucash/gnucash/commit/280b7223 (commit)
via https://github.com/Gnucash/gnucash/commit/5983df7a (commit)
via https://github.com/Gnucash/gnucash/commit/45170bb5 (commit)
from https://github.com/Gnucash/gnucash/commit/15a0d5d2 (commit)
commit 9ea1dd0facc1e1a8283c92ce619d52a4493900cd
Merge: 15a0d5d 280589a
Author: John Ralls <jralls at ceridwen.us>
Date: Sat May 2 17:40:33 2015 -0700
Merge branch 'boost-date'
First merge, which replaces GDateTime with GncDateTime. GncDateTime is
implemented as a PImpl to a wrapper class for boost::date_time. A skeleton
implementation of GncDate is included. More work on that will go into the
next merge.
commit 280589a33ebebc541c4bf2928cf0573bf1ce94ce
Author: John Ralls <jralls at ceridwen.us>
Date: Sat May 2 17:35:09 2015 -0700
Adjust some tests for 64-bit.
The libc time functions are apparently not too smart about applying
timezones to date-times, using the current TZ info rather than the
one that applies to the date.
Formatting is a bit variable as well when localization is applied,
so test with the locale format when appropriate.
diff --git a/src/libqof/qof/test/test-gnc-date.c b/src/libqof/qof/test/test-gnc-date.c
index 396deb9..d62f352 100644
--- a/src/libqof/qof/test/test-gnc-date.c
+++ b/src/libqof/qof/test/test-gnc-date.c
@@ -206,6 +206,7 @@ test_gnc_gmtime (void)
g_assert (time == NULL);
continue;
}
+
g_assert_cmpint (time->tm_year, ==, answers[ind].tm_year);
g_assert_cmpint (time->tm_mon, ==, answers[ind].tm_mon);
g_assert_cmpint (time->tm_mday, ==, answers[ind].tm_mday);
@@ -250,6 +251,12 @@ test_gnc_mktime (void)
for (ind = 0; ind < G_N_ELEMENTS (time); ind++)
{
time64 secs = gnc_mktime (&time[ind]);
+#if !PLATFORM(WINDOWS)
+ //The 64-bit timezone database uses local time for some
+ //timezones before 1900, which screws up the offset.
+ if (time[ind].tm_year < 0 && sizeof(time_t) == sizeof(int64_t))
+ continue;
+#endif
g_assert_cmpint (secs, ==, ans[ind] - offset);
}
@@ -674,27 +681,23 @@ test_timespecCanonicalDayTime (void)
const time64 secs = 8 * 3600 + 43 * 60 + 11;
const time64 secs1 = 23 * sec_per_yr + 5 * sec_per_mo + 11 * sec_per_day + 8 * 3600 + 43 * 60 + 11;
const time64 secs2 = 21 * sec_per_yr + 11 * sec_per_mo + 19 * sec_per_day + 21 * 3600 + 9 * 60 + 48;
- const time64 secs3 = 72 * sec_per_yr + 2 * sec_per_mo + 26 * sec_per_day + 12 * 60;
+
Timespec t0 = { secs, 0 };
Timespec ta = { secs1, 0 };
Timespec tb = { secs2, 0 };
- Timespec tc = { secs3, 0 };
Timespec n0 = compute_noon_of_day (&t0);
Timespec na = compute_noon_of_day (&ta);
Timespec nb = compute_noon_of_day (&tb);
- Timespec nc = compute_noon_of_day (&tc);
Timespec r0 = timespecCanonicalDayTime (t0);
Timespec ra = timespecCanonicalDayTime (ta);
Timespec rb = timespecCanonicalDayTime (tb);
- Timespec rc = timespecCanonicalDayTime (tc);
g_assert_cmpint (n0.tv_sec, ==, r0.tv_sec);
g_assert_cmpint (na.tv_sec, ==, ra.tv_sec);
g_assert_cmpint (nb.tv_sec, ==, rb.tv_sec);
- if (sizeof(time_t) >= sizeof(time64))
- g_assert_cmpint (nc.tv_sec, ==, rc.tv_sec);
+
}
/* gnc_date_get_last_mday
@@ -965,116 +968,125 @@ qof_print_date_buff (char * buff, size_t len, time64 t)// C: 3 in 1 Local: 2:0:
static void
test_qof_print_date_buff (void)
{
- gchar buff[MAX_DATE_LENGTH];
+ gchar buff[MAX_DATE_LENGTH], ans[MAX_DATE_LENGTH];
gchar *locale = g_strdup (setlocale (LC_TIME, NULL));
- time64 tm1 = 154440000; //1974-11-23 12:00:00
- time64 tm2 = -281188800; //1961-02-02 12:00:00
- time64 tm3 = 2381227200LL; //2045-06-16 12:00:00
+ time64 time1 = 154440000; //1974-11-23 12:00:00
+ time64 time2 = -281188800; //1961-02-02 12:00:00
+ time64 time3 = 2381227200LL; //2045-06-16 12:00:00
+ struct tm tm1 = {0, 0, 12, 23, 10, 74};
+ struct tm tm2 = {0, 0, 12, 2, 1, 61};
+ struct tm tm3 = {0, 0, 12, 16, 5, 145};
qof_date_format_set (QOF_DATE_FORMAT_UK);
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm1),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time1),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "23/11/1974");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm2),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time2),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "02/02/1961");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm3),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time3),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "16/06/2045");
qof_date_format_set (QOF_DATE_FORMAT_CE);
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm1),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time1),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "23.11.1974");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm2),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time2),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "02.02.1961");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm3),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time3),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "16.06.2045");
qof_date_format_set (QOF_DATE_FORMAT_US);
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm1),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time1),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "11/23/1974");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm2),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time2),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "02/02/1961");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm3),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time3),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "06/16/2045");
qof_date_format_set (QOF_DATE_FORMAT_ISO);
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm1),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time1),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "1974-11-23");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm2),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time2),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "1961-02-02");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm3),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time3),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "2045-06-16");
qof_date_format_set (QOF_DATE_FORMAT_LOCALE);
test_gnc_setlocale (LC_TIME, "en_US");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm1),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time1),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "11/23/1974");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm2),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time2),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "02/02/1961");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm3),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time3),
==, strlen (buff));
g_assert_cmpstr (buff, ==, "06/16/2045");
test_gnc_setlocale (LC_TIME, "en_GB");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm1),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time1),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, "23/11/1974");
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm1);
+ g_assert_cmpstr (buff, ==, ans);
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm2),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time2),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, "02/02/1961");
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm2);
+ g_assert_cmpstr (buff, ==, ans);
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm3),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time3),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, "16/06/2045");
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm3);
+ g_assert_cmpstr (buff, ==, ans);
test_gnc_setlocale (LC_TIME, "fr_FR");
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm1),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time1),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, "23.11.1974");
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm1);
+ g_assert_cmpstr (buff, ==, ans);
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm2),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time2),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, "02.02.1961");
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm2);
+ g_assert_cmpstr (buff, ==, ans);
memset ((gpointer)buff, 0, sizeof (buff));
- g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm3),
+ g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), time3),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, "16.06.2045");
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm3);
+ g_assert_cmpstr (buff, ==, ans);
setlocale (LC_TIME, locale);
g_free (locale);
@@ -1240,46 +1252,58 @@ static void
test_qof_print_date (void)
{
gchar *locale = g_strdup (setlocale (LC_TIME, NULL));
-
- time64 tm1 = 154440000; //1974-11-23 12:00:00
- time64 tm2 = -281188800; //1961-02-02 12:00:00
- time64 tm3 = 2381227200LL; //2045-06-16 12:00:00
+ char ans[MAX_DATE_LENGTH];
+ time64 time1 = 154440000; //1974-11-23 12:00:00
+ time64 time2 = -281188800; //1961-02-02 12:00:00
+ time64 time3 = 2381227200LL; //2045-06-16 12:00:00
+ struct tm tm1 = {0, 0, 12, 23, 10, 74};
+ struct tm tm2 = {0, 0, 12, 2, 1, 61};
+ struct tm tm3 = {0, 0, 12, 16, 5, 145};
qof_date_format_set (QOF_DATE_FORMAT_UK);
- test_assert_qof_print_date (tm1, "23/11/1974");
- test_assert_qof_print_date_outside_range (tm2, "02/02/1961");
- test_assert_qof_print_date_outside_range (tm3, "16/06/2045");
+ test_assert_qof_print_date (time1, "23/11/1974");
+ test_assert_qof_print_date_outside_range (time2, "02/02/1961");
+ test_assert_qof_print_date_outside_range (time3, "16/06/2045");
qof_date_format_set (QOF_DATE_FORMAT_CE);
- test_assert_qof_print_date (tm1, "23.11.1974");
- test_assert_qof_print_date_outside_range (tm2, "02.02.1961");
- test_assert_qof_print_date_outside_range (tm3, "16.06.2045");
+ test_assert_qof_print_date (time1, "23.11.1974");
+ test_assert_qof_print_date_outside_range (time2, "02.02.1961");
+ test_assert_qof_print_date_outside_range (time3, "16.06.2045");
qof_date_format_set (QOF_DATE_FORMAT_US);
- test_assert_qof_print_date (tm1, "11/23/1974");
- test_assert_qof_print_date_outside_range (tm2, "02/02/1961");
- test_assert_qof_print_date_outside_range (tm3, "06/16/2045");
+ test_assert_qof_print_date (time1, "11/23/1974");
+ test_assert_qof_print_date_outside_range (time2, "02/02/1961");
+ test_assert_qof_print_date_outside_range (time3, "06/16/2045");
qof_date_format_set (QOF_DATE_FORMAT_ISO);
- test_assert_qof_print_date (tm1, "1974-11-23");
- test_assert_qof_print_date_outside_range (tm2, "1961-02-02");
- test_assert_qof_print_date_outside_range (tm3, "2045-06-16");
+ test_assert_qof_print_date (time1, "1974-11-23");
+ test_assert_qof_print_date_outside_range (time2, "1961-02-02");
+ test_assert_qof_print_date_outside_range (time3, "2045-06-16");
qof_date_format_set (QOF_DATE_FORMAT_LOCALE);
test_gnc_setlocale (LC_TIME, "en_US");
- test_assert_qof_print_date (tm1,"11/23/1974");
- test_assert_qof_print_date_outside_range (tm2, "02/02/1961");
- test_assert_qof_print_date_outside_range (tm3, "06/16/2045");
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm1);
+ test_assert_qof_print_date (time1,ans);
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm2);
+ test_assert_qof_print_date_outside_range (time2, ans);
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm3);
+ test_assert_qof_print_date_outside_range (time3, ans);
test_gnc_setlocale (LC_TIME, "en_GB");
- test_assert_qof_print_date (tm1, "23/11/1974");
- test_assert_qof_print_date_outside_range (tm2, "02/02/1961");
- test_assert_qof_print_date_outside_range (tm3, "16/06/2045");
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm1);
+ test_assert_qof_print_date (time1, ans);
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm2);
+ test_assert_qof_print_date_outside_range (time2, ans);
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm3);
+ test_assert_qof_print_date_outside_range (time3, ans);
test_gnc_setlocale (LC_TIME, "fr_FR");
- test_assert_qof_print_date (tm1, "23.11.1974");
- test_assert_qof_print_date_outside_range (tm2, "02.02.1961");
- test_assert_qof_print_date_outside_range (tm3, "16.06.2045");
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm1);
+ test_assert_qof_print_date (time1, ans);
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm2);
+ test_assert_qof_print_date_outside_range (time2, ans);
+ strftime(ans, MAX_DATE_LENGTH, GNC_D_FMT, &tm3);
+ test_assert_qof_print_date_outside_range (time3,ans);
setlocale (LC_TIME, locale);
g_free (locale);
commit 25be764cb0bf869db908ad5f5c99853849a6f13b
Author: John Ralls <jralls at ceridwen.us>
Date: Sat May 2 14:59:45 2015 -0700
Replace boost::posix_date::from_time_t().
It silently converts a 64-bit time_t to 32-bits.
diff --git a/src/libqof/qof/gnc-timezone.cpp b/src/libqof/qof/gnc-timezone.cpp
index 4cbe8ad..7cc3b56 100644
--- a/src/libqof/qof/gnc-timezone.cpp
+++ b/src/libqof/qof/gnc-timezone.cpp
@@ -550,11 +550,18 @@ TimeZoneProvider::TimeZoneProvider(const std::string& tzname) : zone_vector {}
{return !tz.info.isdst;});
auto last_time = ptime();
DSTRule::DSTRule last_rule;
+ using boost::gregorian::date;
+ using boost::posix_time::ptime;
+ using boost::posix_time::time_duration;
for (auto txi = parser.transitions.begin();
txi != parser.transitions.end(); ++txi)
{
auto this_info = parser.tzinfo.begin() + txi->index;
- auto this_time = boost::posix_time::from_time_t(txi->timestamp);
+//Can't use boost::posix_date::from_time_t() constructor because it
+//silently casts the time_t to an int32_t.
+ auto this_time = ptime(date(1970, 1, 1),
+ time_duration(txi->timestamp / 3600, 0,
+ txi->timestamp % 3600));
auto this_year = this_time.date().year();
//Initial case
if (last_time.is_not_a_date_time())
commit b215d6292511af5899a71434807351209d63cd87
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Apr 30 16:09:40 2015 -0700
Replace 'using make_week_num' with a macro; gcc-4.8 can't do that kind of alias.
diff --git a/src/libqof/qof/gnc-timezone.cpp b/src/libqof/qof/gnc-timezone.cpp
index 693c321..4cbe8ad 100644
--- a/src/libqof/qof/gnc-timezone.cpp
+++ b/src/libqof/qof/gnc-timezone.cpp
@@ -129,12 +129,13 @@ windows_tz_names (HKEY key)
return time_zone_names (std_name, std_name, dlt_name, dlt_name);
}
+#define make_week_num(x) static_cast<boost::date_time::nth_kday_of_month<boost::gregorian::date>::week_num>(x)
+
static TZ_Ptr
zone_from_regtzi (const RegTZI& regtzi, time_zone_names names)
{
using ndate = boost::gregorian::nth_day_of_the_week_in_month;
using nth_day_rule = boost::local_time::nth_day_of_the_week_in_month_dst_rule;
- using make_week_num = static_cast<boost::date_time::nth_kday_of_month<boost::gregorian::date>::week_num>;
duration std_off (0, regtzi.StandardBias - regtzi.Bias, 0);
duration dlt_off (0, regtzi.DaylightBias, 0);
@@ -225,8 +226,6 @@ TimeZoneProvider::load_windows_classic_tz (HKEY key, time_zone_names names)
RegCloseKey (key);
}
-TimeZoneProvider::TimeZoneProvider () : TimeZoneProvider ("")) {}
-
TimeZoneProvider::TimeZoneProvider (const std::string& identifier) :
zone_vector ()
{
commit 9fafb612830d35de0f8c7d9cfffd2ca050116e86
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Apr 30 16:08:24 2015 -0700
Restore #include strptime.h, needed on MinGW.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 9bb5b1d..5db07db 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -38,7 +38,9 @@ extern "C"
#ifdef HAVE_LANGINFO_D_FMT
# include <langinfo.h>
#endif
-
+#ifndef HAVE_STRPTIME
+#include <strptime.h>
+#endif
#ifdef G_OS_WIN32
# include <windows.h>
#endif
commit 48a5473bbb4a3ad0bdd6c7343c56463cae3294ec
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Apr 30 16:06:28 2015 -0700
Add BOOST_LDFLAGS so that libboost_date_time can be found in MinGW.
diff --git a/src/libqof/qof/Makefile.am b/src/libqof/qof/Makefile.am
index 99b4fe1..7350398 100644
--- a/src/libqof/qof/Makefile.am
+++ b/src/libqof/qof/Makefile.am
@@ -11,7 +11,7 @@ libgnc_qof_la_LDFLAGS= \
libgnc_qof_common_libs = \
$(GLIB_LIBS) \
$(REGEX_LIBS) \
- -lboost_date_time \
+ $(BOOST_LDFLAGS) -lboost_date_time \
$(top_builddir)/lib/libc/libc-missing.la
libgnc_qof_la_LIBADD = $(libgnc_qof_common_libs)
commit 9fbc447f74e8090431bdd317c5688fb116c270fe
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Apr 30 12:23:25 2015 -0700
Some gcc don't like having a struct ymd and a ymd() member function.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 52f1d51..9bb5b1d 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -1400,7 +1400,7 @@ GDate* gnc_g_date_new_today ()
{
GncDate gncd;
gncd.today();
- auto ymd = gncd.ymd();
+ auto ymd = gncd.year_month_day();
auto month = static_cast<GDateMonth>(ymd.month);
auto result = g_date_new_dmy (ymd.day, month, ymd.year);
g_assert(g_date_valid (result));
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index db54d88..7f8a6d4 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -64,13 +64,13 @@ public:
GncDateImpl(Date d) : m_greg(d) {}
void today() { m_greg = boost::gregorian::day_clock::local_day(); }
- ymd ymd() const;
+ ymd year_month_day() const;
private:
Date m_greg;
};
ymd
-GncDateImpl::ymd() const
+GncDateImpl::year_month_day() const
{
auto boost_ymd = m_greg.year_month_day();
return {boost_ymd.year, boost_ymd.month.as_number(), boost_ymd.day};
@@ -229,9 +229,9 @@ GncDate::today()
}
ymd
-GncDate::ymd() const
+GncDate::year_month_day() const
{
- return m_impl->ymd();
+ return m_impl->year_month_day();
}
GncDateTime::GncDateTime() : m_impl(new GncDateTimeImpl) {}
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index 3127804..04d48b5 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -68,7 +68,7 @@ public:/** Construct a GncDate representing the current day.
/** Get the year, month, and day from the date as a ymd.
@return ymd struct
*/
- ymd ymd() const;
+ ymd year_month_day() const;
/** Test that the Date has an implementation. */
bool isnull (void) { return m_impl == nullptr; }
diff --git a/src/libqof/qof/test/gtest-gnc-datetime.cpp b/src/libqof/qof/test/gtest-gnc-datetime.cpp
index da47b0c..2f6e000 100644
--- a/src/libqof/qof/test/gtest-gnc-datetime.cpp
+++ b/src/libqof/qof/test/gtest-gnc-datetime.cpp
@@ -77,12 +77,12 @@ TEST(gnc_datetime_functions, test_format)
EXPECT_EQ(atime.format("%d-%m-%Y"), "13-11-2045");
}
-//This is a bit convoluted because it uses GncDate's GncDateImpl constructor and ymd() function. There's no good way to test the former without violating the privacy of the implementation.
+//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)
{
GncDateTime atime(2394187200); //2045-11-13 12:00:00 Z
GncDate gncd = std::move(atime.date());
- auto ymd = gncd.ymd();
+ auto ymd = gncd.year_month_day();
EXPECT_EQ(ymd.year, 2045);
EXPECT_EQ(ymd.month, 11);
EXPECT_EQ(ymd.day, 13);
commit f87f9ca02d63e4011c48205d1721d4170fb4ac34
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 28 17:54:05 2015 -0700
gnc_date_today from GncDate.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index e0a689d..52f1d51 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -98,14 +98,14 @@ gnc_tm_free (struct tm* time)
struct tm*
gnc_localtime (const time64 *secs)
{
- auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm)));
- if (gnc_localtime_r (secs, time) == NULL)
- {
- gnc_tm_free (time);
- return NULL;
- }
- return time;
+ auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm)));
+ if (gnc_localtime_r (secs, time) == NULL)
+ {
+ gnc_tm_free (time);
+ return NULL;
}
+ return time;
+}
struct tm*
gnc_localtime_r (const time64 *secs, struct tm* time)
@@ -123,17 +123,17 @@ gnc_localtime_r (const time64 *secs, struct tm* time)
static void
normalize_time_component (int *inner, int *outer, unsigned int divisor,
- int base)
+ int base)
{
while (*inner < base)
{
- --(*outer);
- *inner += divisor;
+ --(*outer);
+ *inner += divisor;
}
while (*inner > static_cast<gint>(divisor))
{
- ++(*outer);
- *inner -= divisor;
+ ++(*outer);
+ *inner -= divisor;
}
}
@@ -165,16 +165,16 @@ normalize_struct_tm (struct tm* time)
// auto month_in_range = []int (int m){ return (m + 12) % 12; }
while (time->tm_mday < 1)
{
- normalize_month (&(--time->tm_mon), &year);
- last_day = gnc_date_get_last_mday (time->tm_mon, year);
- time->tm_mday += last_day;
+ normalize_month (&(--time->tm_mon), &year);
+ last_day = gnc_date_get_last_mday (time->tm_mon, year);
+ time->tm_mday += last_day;
}
last_day = gnc_date_get_last_mday (time->tm_mon, year);
while (time->tm_mday > last_day)
{
- time->tm_mday -= last_day;
- normalize_month(&(++time->tm_mon), &year);
- last_day = gnc_date_get_last_mday (time->tm_mon, year);
+ time->tm_mday -= last_day;
+ normalize_month(&(++time->tm_mon), &year);
+ last_day = gnc_date_get_last_mday (time->tm_mon, year);
}
time->tm_year = year - 1900;
}
@@ -484,8 +484,8 @@ gnc_gdate_range_check (GDate *gd)
int year;
if (!g_date_valid (gd))
{
- g_date_set_dmy (gd, 1, G_DATE_JANUARY, 1970);
- return;
+ g_date_set_dmy (gd, 1, G_DATE_JANUARY, 1970);
+ return;
}
year = g_date_get_year (gd);
// Adjust the GDate to fit in the range of GDateTime.
@@ -677,7 +677,7 @@ qof_print_date_dmy_buff (char * buff, size_t len, int day, int month, int year)
tm_str.tm_mday = day;
tm_str.tm_mon = month - 1; /* tm_mon = 0 through 11 */
tm_str.tm_year = year - 1900; /* this is what the standard
- says, it's not a Y2K thing */
+ says, it's not a Y2K thing */
gnc_tm_set_day_start (&tm_str);
t = gnc_mktime (&tm_str);
@@ -708,7 +708,7 @@ qof_print_date_buff (char * buff, size_t len, time64 t)
size_t actual;
if (!buff) return 0 ;
if (!gnc_localtime_r(&bt, &theTime))
- return 0;
+ return 0;
actual = qof_print_date_dmy_buff (buff, len,
theTime.tm_mday,
@@ -807,7 +807,7 @@ qof_scan_date_internal (const char *buff, int *day, int *month, int *year,
if (which_format == QOF_DATE_FORMAT_UTC)
{
if (strptime(buff, QOF_UTC_DATE_FORMAT, &utc)
- || strptime (buff, "%Y-%m-%d", &utc))
+ || strptime (buff, "%Y-%m-%d", &utc))
{
*day = utc.tm_mday;
*month = utc.tm_mon + 1;
@@ -1245,13 +1245,13 @@ gnc_date_timestamp (void)
Timespec
gnc_iso8601_to_timespec_gmt(const char *cstr)
{
- time64 time;
+ time64 time;
if (!cstr) return {0, 0};
try
- {
+ {
GncDateTime gncdt(cstr);
return {static_cast<time64>(gncdt), 0};
- }
+ }
catch(...)
{
return {0, 0};
@@ -1398,10 +1398,10 @@ GDate timespec_to_gdate (Timespec ts)
GDate* gnc_g_date_new_today ()
{
-
- auto pdt = boost::posix_time::second_clock::local_time();
- auto ymd = pdt.date().year_month_day();
- auto month = static_cast<GDateMonth>(ymd.month.as_number());
+ GncDate gncd;
+ gncd.today();
+ auto ymd = gncd.ymd();
+ auto month = static_cast<GDateMonth>(ymd.month);
auto result = g_date_new_dmy (ymd.day, month, ymd.year);
g_assert(g_date_valid (result));
return result;
@@ -1420,7 +1420,7 @@ gnc_tm_get_day_start (struct tm *tm, time64 time_val)
{
/* Get the equivalent time structure */
if (!gnc_localtime_r(&time_val, tm))
- return;
+ return;
gnc_tm_set_day_start(tm);
}
@@ -1429,7 +1429,7 @@ gnc_tm_get_day_end (struct tm *tm, time64 time_val)
{
/* Get the equivalent time structure */
if (!gnc_localtime_r(&time_val, tm))
- return;
+ return;
gnc_tm_set_day_end(tm);
}
commit bcedeff3ba2f8aee847d84deeffaeee2fa74c844
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 28 17:53:35 2015 -0700
Fix the string constructor to apply the timezone correctly.
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index 20c78c4..db54d88 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -43,7 +43,7 @@ using time64 = int64_t;
static const TimeZoneProvider tzp;
// For converting to/from POSIX time.
static const PTime unix_epoch (Date(1970, boost::gregorian::Jan, 1),
- boost::posix_time::seconds(0));
+ boost::posix_time::seconds(0));
static const TZ_Ptr utc_zone(new boost::local_time::posix_time_zone("UTC-0"));
/* To ensure things aren't overly screwed up by setting the nanosecond clock for boost::date_time. Don't do it, though, it doesn't get us anything and slows down the date/time library. */
@@ -60,7 +60,7 @@ class GncDateImpl
public:
GncDateImpl(): m_greg(unix_epoch.date()) {}
GncDateImpl(const int year, const int month, const int day) :
- m_greg(year, static_cast<Month>(month), day) {}
+ m_greg(year, static_cast<Month>(month), day) {}
GncDateImpl(Date d) : m_greg(d) {}
void today() { m_greg = boost::gregorian::day_clock::local_day(); }
@@ -83,15 +83,15 @@ LDT_from_unix_local(const time64 time)
{
try
{
- PTime temp(unix_epoch.date(),
- boost::posix_time::hours(time / 3600) +
- boost::posix_time::seconds(time % 3600));
- auto tz = tzp.get(temp.date().year());
- return LDT(temp, tz);
+ PTime temp(unix_epoch.date(),
+ boost::posix_time::hours(time / 3600) +
+ boost::posix_time::seconds(time % 3600));
+ auto tz = tzp.get(temp.date().year());
+ return LDT(temp, tz);
}
catch(boost::gregorian::bad_year)
{
- throw(std::invalid_argument("Time value is outside the supported year range."));
+ throw(std::invalid_argument("Time value is outside the supported year range."));
}
}
@@ -100,15 +100,15 @@ LDT_from_struct_tm(const struct tm tm)
{
try
{
- auto tdate = boost::gregorian::date_from_tm(tm);
- auto tdur = boost::posix_time::time_duration(tm.tm_hour, tm.tm_min,
- tm.tm_sec, 0);
- auto tz = tzp.get(tdate.year());
- return LDT(PTime(tdate, tdur), tz);
+ auto tdate = boost::gregorian::date_from_tm(tm);
+ auto tdur = boost::posix_time::time_duration(tm.tm_hour, tm.tm_min,
+ tm.tm_sec, 0);
+ auto tz = tzp.get(tdate.year());
+ return LDT(PTime(tdate, tdur), tz);
}
catch(boost::gregorian::bad_year)
{
- throw(std::invalid_argument("Time value is outside the supported year range."));
+ throw(std::invalid_argument("Time value is outside the supported year range."));
}
}
@@ -144,21 +144,28 @@ GncDateTimeImpl::GncDateTimeImpl(const std::string str) :
auto tzpos = str.find_first_of("+-", str.find(":"));
if (tzpos != str.npos)
{
- string tzstr = "XXX" + str.substr(tzpos);
- if (tzstr.length() > 6 && tzstr[6] != ':') //6 for XXXsHH, s is + or -
- tzstr.insert(6, ":");
- if (tzstr.length() > 9 && tzstr[9] != ':') //9 for XXXsHH:MM
- tzstr.insert(9, ":");
- tzptr.reset(new PTZ(tzstr));
- if (str[tzpos - 1] == ' ') --tzpos;
+ string tzstr = "XXX" + str.substr(tzpos);
+ if (tzstr.length() > 6 && tzstr[6] != ':') //6 for XXXsHH, s is + or -
+ tzstr.insert(6, ":");
+ if (tzstr.length() > 9 && tzstr[9] != ':') //9 for XXXsHH:MM
+ tzstr.insert(9, ":");
+ tzptr.reset(new PTZ(tzstr));
+ if (str[tzpos - 1] == ' ') --tzpos;
}
else
{
- tzptr = utc_zone;
+ tzptr = utc_zone;
+ }
+ try
+ {
+ auto pdt = boost::posix_time::time_from_string(str.substr(0, tzpos));
+ m_time = LDT(pdt.date(), pdt.time_of_day(), tzptr,
+ LDTBase::NOT_DATE_TIME_ON_ERROR);
+ }
+ catch(boost::gregorian::bad_year)
+ {
+ throw(std::invalid_argument("The date string was outside of the supported year range."));
}
-
- auto pdt = boost::posix_time::time_from_string(str.substr(0, tzpos));
- m_time = LDT(pdt, tzptr);
}
GncDateTimeImpl::operator time64() const
commit ac515d6ce25491df1cff9df64bd357655873dc8a
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 28 17:47:47 2015 -0700
Stop testing fractional seconds.
We don't use them in real code, so the new implementation isn't going to
support them.
diff --git a/src/engine/test-core/test-engine-stuff.c b/src/engine/test-core/test-engine-stuff.c
index 2073afe..857e9b2 100644
--- a/src/engine/test-core/test-engine-stuff.c
+++ b/src/engine/test-core/test-engine-stuff.c
@@ -224,20 +224,7 @@ get_random_timespec(void)
while (ret->tv_sec <= 0)
ret->tv_sec = rand();
- if (zero_nsec)
- ret->tv_nsec = 0;
- else
- {
- ret->tv_nsec = rand();
-
- if (usec_resolution)
- {
- ret->tv_nsec = MIN (ret->tv_nsec, 999999999);
- ret->tv_nsec /= 1000;
- ret->tv_nsec *= 1000;
- }
- }
-
+ ret->tv_nsec = 0;
return ret;
}
diff --git a/src/engine/test/test-date.c b/src/engine/test/test-date.c
index 9397486..492975a 100644
--- a/src/engine/test/test-date.c
+++ b/src/engine/test/test-date.c
@@ -325,7 +325,7 @@ run_test (void)
check_time (ts, do_print);
ts.tv_sec = 1162088421;
- ts.tv_nsec = 12548000;
+ ts.tv_nsec = 0;
check_time (ts, do_print);
ts.tv_sec = 325659000 - 6500;
@@ -337,15 +337,15 @@ run_test (void)
check_time (ts, do_print);
ts.tv_sec = 1603591171;
- ts.tv_nsec = 595311000;
+ ts.tv_nsec = 0;
check_time (ts, do_print);
ts.tv_sec = 1738909365;
- ts.tv_nsec = 204102000;
+ ts.tv_nsec = 0;
check_time (ts, do_print);
ts.tv_sec = 1603591171;
- ts.tv_nsec = 595311000;
+ ts.tv_nsec = 0;
check_time (ts, do_print);
ts.tv_sec = 1143943200 - 1;
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 0375b2a..e0a689d 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -1246,12 +1246,11 @@ Timespec
gnc_iso8601_to_timespec_gmt(const char *cstr)
{
time64 time;
- uint32_t nsecs;
if (!cstr) return {0, 0};
try
{
GncDateTime gncdt(cstr);
- return {static_cast<time64>(gncdt), gncdt.nsecs()};
+ return {static_cast<time64>(gncdt), 0};
}
catch(...)
{
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index 40ac1a6..20c78c4 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -126,7 +126,6 @@ public:
operator struct tm() const;
void now() { m_time = boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year())); }
long offset() const;
- long nsecs() const;
struct tm utc_tm() const { return to_tm(m_time.utc_time()); }
std::unique_ptr<GncDateImpl> date() const;
std::string format(const char* format) const;
@@ -186,12 +185,6 @@ GncDateTimeImpl::offset() const
return offset.total_seconds();
}
-long
-GncDateTimeImpl::nsecs() const
-{
- return (m_time.utc_time() - unix_epoch).ticks() % ticks_per_second;
-}
-
std::unique_ptr<GncDateImpl>
GncDateTimeImpl::date() const
{
@@ -265,12 +258,6 @@ GncDateTime::offset() const
return m_impl->offset();
}
-long
-GncDateTime::nsecs() const
-{
- return m_impl->nsecs();
-}
-
struct tm
GncDateTime::utc_tm() const
{
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index 46dd83d..3127804 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -131,11 +131,6 @@ public:
* is negative.
*/
long offset()const;
-/** Obtain the fractional seconds from the GncDateTime
- * @return Fractional seconds, represented as nanoseconds, associated
- * with the time.
- */
- long nsecs() const;
/** Obtain a struct tm representing the time in UTC.
* @return struct tm
*/
diff --git a/src/libqof/qof/test/test-gnc-date.c b/src/libqof/qof/test/test-gnc-date.c
index 93f9943..396deb9 100644
--- a/src/libqof/qof/test/test-gnc-date.c
+++ b/src/libqof/qof/test/test-gnc-date.c
@@ -93,7 +93,7 @@ static void setup (FixtureA *f, gconstpointer pData)
f->off_zulu = (TZOffset){0, 0};
f->off_05w = (TZOffset){-5, 0};
f->off_0840e = (TZOffset){8, 40};
- f->ts1 = (Timespec){607009407, 345678000}; //1989-3-27 13:43:27.345678 Z
+ f->ts1 = (Timespec){607009407, 0}; //1989-3-27 13:43:27 Z
f->ts2 = (Timespec){1604748079, 0}; //2020-11-7 06:21:19 -05:00
f->ts3 = (Timespec){1341398864, 0}; //2012-07-04 19:27:44 +08:40
f->ts4 = (Timespec){-261104801, 0}; //1961-09-22 17:53:19 -05:00
@@ -1590,7 +1590,7 @@ test_gnc_iso8601_to_timespec_gmt (FixtureA *f, gconstpointer pData)
g_assert_cmpint (t.tv_sec, ==, 0);
g_assert_cmpint (t.tv_nsec, ==, 0);
- t = gnc_iso8601_to_timespec_gmt ("1989-03-27 13:43:27.345678");
+ t = gnc_iso8601_to_timespec_gmt ("1989-03-27 13:43:27");
g_assert_cmpint (t.tv_sec, ==, f->ts1.tv_sec);
/* MinGW has some precision issues in the last microsecond digit */
#ifdef G_OS_WIN32
commit a8028ec7f28dee132dfedeae240822902d993957
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 28 17:05:35 2015 -0700
Remove aliases and boost::date_time construction functions from gnc-date.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 830e608..0375b2a 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -53,13 +53,6 @@ extern "C"
#define N_(string) string //So that xgettext will find it
-using Date = boost::gregorian::date;
-using Month = boost::gregorian::greg_month;
-using PTime = boost::posix_time::ptime;
-using LDT = boost::local_time::local_date_time;
-using Duration = boost::posix_time::time_duration;
-using LDTBase = boost::local_time::local_date_time_base<PTime, boost::date_time::time_zone_base<PTime, char>>;
-
#ifdef HAVE_LANGINFO_D_FMT
# define GNC_D_FMT (nl_langinfo (D_FMT))
# define GNC_D_T_FMT (nl_langinfo (D_T_FMT))
@@ -95,56 +88,6 @@ static int dateCompletionBackMonths = 6;
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = QOF_MOD_ENGINE;
-// Default constructor Initializes to the current locale.
-static const TimeZoneProvider tzp;
-// For converting to/from POSIX time.
-static const PTime unix_epoch (Date(1970, boost::gregorian::Jan, 1),
- boost::posix_time::seconds(0));
-/* To ensure things aren't overly screwed up by setting the nanosecond clock for boost::date_time. Don't do it, though, it doesn't get us anything and slows down the date/time library. */
-#ifndef BOOST_DATE_TIME_HAS_NANOSECONDS
-static constexpr auto ticks_per_second = INT64_C(1000000);
-#else
-static constexpr auto ticks_per_second = INT64_C(1000000000);
-#endif
-static LDT
-gnc_get_LDT(int year, int month, int day, int hour, int minute, int seconds)
-{
- Date date(year, static_cast<Month>(month), day);
- Duration time(hour, minute, seconds);
- auto tz = tzp.get(year);
- return LDT(date, time, tz, LDTBase::NOT_DATE_TIME_ON_ERROR);
-}
-
-static LDT
-LDT_from_unix_local(const time64 time)
-{
- PTime temp(unix_epoch.date(),
- boost::posix_time::hours(time / 3600) +
- boost::posix_time::seconds(time % 3600));
- auto tz = tzp.get(temp.date().year());
- return LDT(temp, tz);
-}
-
-template<typename T>
-static time64
-time64_from_date_time(T time)
-{
- auto duration = time - unix_epoch;
- auto secs = duration.ticks();
- secs /= ticks_per_second;
- return secs;
-}
-
-template<>
-time64
-time64_from_date_time<LDT>(LDT time)
-{
- auto duration = time.utc_time() - unix_epoch;
- auto secs = duration.ticks();
- secs /= ticks_per_second;
- return secs;
-}
-
/****************** Posix Replacement Functions ***************************/
void
gnc_tm_free (struct tm* time)
commit f46e9f023c3fe8356ee745c32b65f3a265311684
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 28 17:04:09 2015 -0700
Print functions to GncDateTime.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 7cb4270..830e608 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -397,14 +397,8 @@ gnc_date_string_to_monthformat(const char *fmt_str, GNCDateMonthFormat *format)
char*
gnc_print_time64(time64 time, const char* format)
{
- using Facet = boost::local_time::local_time_facet;
- auto date_time = LDT_from_unix_local(time);
- 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 << date_time;
- auto sstr = ss.str();
+ GncDateTime gncdt(time);
+ auto sstr = gncdt.format(format);
//ugly C allocation so that the ptr can be freed at the other end
char* cstr = static_cast<char*>(malloc(sstr.length() + 1));
memset(cstr, 0, sstr.length() + 1);
@@ -1308,45 +1302,18 @@ gnc_date_timestamp (void)
Timespec
gnc_iso8601_to_timespec_gmt(const char *cstr)
{
- using std::string;
- using PTZ = boost::local_time::posix_time_zone;
-
- if (!cstr) return {0, 0};
-// try
- {
- string str(cstr);
- if (str.empty())
- return {0, 0};
time64 time;
uint32_t nsecs;
- auto tzpos = str.find_first_of("+-", str.find(":"));
- if (tzpos != str.npos)
- {
- string tzstr = "XXX" + str.substr(tzpos);
- if (tzstr.length() > 6 && tzstr[6] != ':') //6 for XXXsHH, s is + or -
- tzstr.insert(6, ":");
- if (tzstr.length() > 9 && tzstr[9] != ':') //9 for XXXsHH:MM
- tzstr.insert(9, ":");
- TZ_Ptr tzp(new PTZ(tzstr));
- if (str[tzpos - 1] == ' ') --tzpos;
- auto pdt = boost::posix_time::time_from_string(str.substr(0, tzpos));
- LDT ldt(pdt.date(), pdt.time_of_day(), tzp,
- LDTBase::NOT_DATE_TIME_ON_ERROR);
- time = time64_from_date_time(ldt);
- nsecs = (ldt.utc_time() - unix_epoch).ticks() % ticks_per_second;
- }
- else
+ if (!cstr) return {0, 0};
+ try
{
- auto pdt = boost::posix_time::time_from_string(str);
- time = time64_from_date_time(pdt);
- nsecs = (pdt - unix_epoch).ticks() % ticks_per_second;
+ GncDateTime gncdt(cstr);
+ return {static_cast<time64>(gncdt), gncdt.nsecs()};
}
- return {time, static_cast<int32_t>(nsecs) * INT32_C(1000)};
+ catch(...)
+ {
+ return {0, 0};
}
-// catch(...)
- // {
-// return {0, 0};
-// }
}
/********************************************************************\
@@ -1360,15 +1327,8 @@ gnc_timespec_to_iso8601_buff (Timespec ts, char * buff)
if (! buff) return NULL;
- using Facet = boost::local_time::local_time_facet;
- auto date_time = LDT_from_unix_local(ts.tv_sec);
- date_time = date_time + boost::posix_time::microseconds(ts.tv_nsec / 1000);
- 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 << date_time;
- auto sstr = ss.str();
+ GncDateTime gncdt(ts.tv_sec);
+ auto sstr = gncdt.format(format);
memset(buff, 0, sstr.length() + 1);
strncpy(buff, sstr.c_str(), sstr.length());
commit db6b7d368e7d111a0354dbdee493ea4dcaaaae69
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 28 16:49:01 2015 -0700
gnc_time to GncDateTime.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 672eb51..7cb4270 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -292,11 +292,12 @@ gnc_ctime (const time64 *secs)
time64
gnc_time (time64 *tbuf)
{
- auto pdt = boost::posix_time::second_clock::universal_time();
- auto secs = time64_from_date_time(pdt);
- if (tbuf != NULL)
- *tbuf = secs;
- return secs;
+ GncDateTime gncdt;
+ gncdt.now();
+ auto time = static_cast<time64>(gncdt);
+ if (tbuf != NULL)
+ *tbuf = time;
+ return time;
}
gdouble
commit 671a6ac75e45a76f06a7d35aa62a07e2bbe200de
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 28 16:44:59 2015 -0700
Remove extraneous try block.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 847e255..672eb51 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -155,8 +155,6 @@ gnc_tm_free (struct tm* time)
struct tm*
gnc_localtime (const time64 *secs)
{
- try
- {
auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm)));
if (gnc_localtime_r (secs, time) == NULL)
{
@@ -165,11 +163,6 @@ gnc_localtime (const time64 *secs)
}
return time;
}
- catch(std::invalid_argument)
- {
- return NULL;
- }
-}
struct tm*
gnc_localtime_r (const time64 *secs, struct tm* time)
commit d2f80a94076602e9d4597f55d1f9fdaeaa3d7213
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 28 15:23:26 2015 -0700
gnc_mktime and gnc_timegm with GncDateTime.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 4f357a1..847e255 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -155,20 +155,34 @@ gnc_tm_free (struct tm* time)
struct tm*
gnc_localtime (const time64 *secs)
{
- auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm)));
- if (gnc_localtime_r (secs, time) == NULL)
+ try
+ {
+ auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm)));
+ if (gnc_localtime_r (secs, time) == NULL)
+ {
+ gnc_tm_free (time);
+ return NULL;
+ }
+ return time;
+ }
+ catch(std::invalid_argument)
{
- gnc_tm_free (time);
return NULL;
}
- return time;
}
struct tm*
gnc_localtime_r (const time64 *secs, struct tm* time)
{
- *time = static_cast<struct tm>(GncDateTime(*secs));
- return time;
+ try
+ {
+ *time = static_cast<struct tm>(GncDateTime(*secs));
+ return time;
+ }
+ catch(std::invalid_argument)
+ {
+ return NULL;
+ }
}
static void
@@ -232,34 +246,48 @@ normalize_struct_tm (struct tm* time)
struct tm*
gnc_gmtime (const time64 *secs)
{
- auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm)));
- GncDateTime gncdt(*secs);
- *time = static_cast<struct tm>(gncdt);
- auto gmtoff = gncdt.offset();
- time->tm_hour -= gmtoff / 3600;
- time->tm_min -= (gmtoff % 3600 / 60);
- time->tm_sec -= gmtoff % 60;
- normalize_struct_tm(time);
- return time;
+ try
+ {
+ auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm)));
+ GncDateTime gncdt(*secs);
+ *time = gncdt.utc_tm();
+ return time;
+ }
+ catch(std::invalid_argument)
+ {
+ return NULL;
+ }
+
}
time64
gnc_mktime (struct tm* time)
{
- normalize_struct_tm (time);
- auto ldt = gnc_get_LDT (time->tm_year + 1900, time->tm_mon + 1,
- time->tm_mday, time->tm_hour, time->tm_min,
- time->tm_sec);
- return time64_from_date_time(ldt);
+ try
+ {
+ normalize_struct_tm (time);
+ GncDateTime gncdt(*time);
+ return static_cast<time64>(gncdt) - gncdt.offset();
+ }
+ catch(std::invalid_argument)
+ {
+ return 0;
+ }
}
time64
gnc_timegm (struct tm* time)
{
- auto newtime = *time;
- normalize_struct_tm(time);
- auto pdt = boost::posix_time::ptime_from_tm(*time);
- return time64_from_date_time(pdt);
+ try
+ {
+ normalize_struct_tm(time);
+ return static_cast<time64>(GncDateTime(*time));
+ }
+ catch(std::invalid_argument)
+ {
+ return 0;
+ }
+
}
char*
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index 8d2f097..40ac1a6 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -81,21 +81,35 @@ GncDateImpl::ymd() const
static LDT
LDT_from_unix_local(const time64 time)
{
- PTime temp(unix_epoch.date(),
- boost::posix_time::hours(time / 3600) +
- boost::posix_time::seconds(time % 3600));
- auto tz = tzp.get(temp.date().year());
- return LDT(temp, tz);
+ try
+ {
+ PTime temp(unix_epoch.date(),
+ boost::posix_time::hours(time / 3600) +
+ boost::posix_time::seconds(time % 3600));
+ auto tz = tzp.get(temp.date().year());
+ return LDT(temp, tz);
+ }
+ catch(boost::gregorian::bad_year)
+ {
+ throw(std::invalid_argument("Time value is outside the supported year range."));
+ }
}
static LDT
LDT_from_struct_tm(const struct tm tm)
{
- auto tdate = boost::gregorian::date_from_tm(tm);
- auto tdur = boost::posix_time::time_duration(tm.tm_hour, tm.tm_min,
- tm.tm_sec, 0);
- auto tz = tzp.get(tdate.year());
- return LDT(PTime(tdate, tdur), tz);
+ try
+ {
+ auto tdate = boost::gregorian::date_from_tm(tm);
+ auto tdur = boost::posix_time::time_duration(tm.tm_hour, tm.tm_min,
+ tm.tm_sec, 0);
+ auto tz = tzp.get(tdate.year());
+ return LDT(PTime(tdate, tdur), tz);
+ }
+ catch(boost::gregorian::bad_year)
+ {
+ throw(std::invalid_argument("Time value is outside the supported year range."));
+ }
}
class GncDateTimeImpl
@@ -113,6 +127,7 @@ public:
void now() { m_time = boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year())); }
long offset() const;
long nsecs() const;
+ struct tm utc_tm() const { return to_tm(m_time.utc_time()); }
std::unique_ptr<GncDateImpl> date() const;
std::string format(const char* format) const;
private:
@@ -157,7 +172,11 @@ GncDateTimeImpl::operator time64() const
GncDateTimeImpl::operator struct tm() const
{
- return to_tm(m_time);
+ struct tm time = to_tm(m_time);
+#if HAVE_STRUCT_TM_GMTOFF
+ time.tm_gmtoff = offset();
+#endif
+ return time;
}
long
@@ -252,6 +271,12 @@ GncDateTime::nsecs() const
return m_impl->nsecs();
}
+struct tm
+GncDateTime::utc_tm() const
+{
+ return m_impl->utc_tm();
+}
+
GncDate
GncDateTime::date() const
{
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index e2fe6a7..46dd83d 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -123,8 +123,7 @@ public:
void now();
/** Cast the GncDateTime to a time64, seconds from the POSIX epoch. */
explicit operator time64() const;
-/** Cast the GncDateTime to a struct tm. Timezone and offset fields
- * are not filled.
+/** Cast the GncDateTime to a struct tm. Timezone field isn't filled.
*/
explicit operator struct tm() const;
/** Obtain the UTC offset in seconds
@@ -137,6 +136,10 @@ public:
* with the time.
*/
long nsecs() const;
+/** Obtain a struct tm representing the time in UTC.
+ * @return struct tm
+ */
+ struct tm utc_tm() const;
/** Obtain the date from the time, as a GncDate, in the current timezone.
* @return GncDate represented by the GncDateTime.
*/
commit 2dde36d0154b10a7310f5eac52aa3c9a24bf5ed6
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 28 15:13:13 2015 -0700
Do locality and gmtime with GncDateTime.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 0623203..4f357a1 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -47,6 +47,9 @@ extern "C"
#include "gnc-date.h"
#include "gnc-date-p.h"
#include "gnc-datetime.hpp"
+#include "gnc-timezone.hpp"
+#define BOOST_ERROR_CODE_HEADER_ONLY
+#include <boost/date_time/local_time/local_time.hpp>
#define N_(string) string //So that xgettext will find it
@@ -164,37 +167,7 @@ gnc_localtime (const time64 *secs)
struct tm*
gnc_localtime_r (const time64 *secs, struct tm* time)
{
- try
- {
- auto ldt = LDT_from_unix_local(*secs);
- *time = boost::local_time::to_tm(ldt);
-#ifdef HAVE_STRUCT_TM_GMTOFF
- auto offset = ldt.zone()->base_utc_offset();
- if (ldt.is_dst())
- offset += ldt.zone()->dst_offset();
- time->tm_gmtoff = offset.total_seconds();
-#endif
- }
- catch(boost::gregorian::bad_year)
- {
- return NULL; //Yeah, it should be nullptr, but this is a C-linkage func.
- }
- return time;
-}
-
-struct tm*
-gnc_gmtime (const time64 *secs)
-{
- auto time = static_cast<struct tm*>(calloc(1, sizeof (struct tm)));
- try {
- PTime pdt(unix_epoch.date(), boost::posix_time::hours(*secs / 3600) +
- boost::posix_time::seconds(*secs % 3600));
- *time = boost::posix_time::to_tm(pdt);
- }
- catch(boost::gregorian::bad_year)
- {
- return NULL; //Yeah, it should be nullptr, but this is a C-linkage func.
- }
+ *time = static_cast<struct tm>(GncDateTime(*secs));
return time;
}
@@ -256,6 +229,20 @@ normalize_struct_tm (struct tm* time)
time->tm_year = year - 1900;
}
+struct tm*
+gnc_gmtime (const time64 *secs)
+{
+ auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm)));
+ GncDateTime gncdt(*secs);
+ *time = static_cast<struct tm>(gncdt);
+ auto gmtoff = gncdt.offset();
+ time->tm_hour -= gmtoff / 3600;
+ time->tm_min -= (gmtoff % 3600 / 60);
+ time->tm_sec -= gmtoff % 60;
+ normalize_struct_tm(time);
+ return time;
+}
+
time64
gnc_mktime (struct tm* time)
{
commit d4a3d862cf693060d606f1017325858896db76fc
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 28 14:19:00 2015 -0700
Include gnc-datetime.hpp in gnc-date.cpp.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index db6f22e..0623203 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -31,6 +31,7 @@ extern "C"
#include "config.h"
#include <glib.h>
#include <libintl.h>
+#include <stdlib.h>
#include "platform.h"
#include "qof.h"
@@ -45,9 +46,8 @@ extern "C"
#include "gnc-date.h"
#include "gnc-date-p.h"
-//#include "gnc-datetime.hpp"
+#include "gnc-datetime.hpp"
-#include "gnc-timezone.hpp"
#define N_(string) string //So that xgettext will find it
using Date = boost::gregorian::date;
commit 78b974ad79b4ec1acbf81247d0ec08e24b3dc94d
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 28 14:08:02 2015 -0700
Add gnc-datetime.cpp to the build.
diff --git a/src/libqof/qof/Makefile.am b/src/libqof/qof/Makefile.am
index bae92cc..99b4fe1 100644
--- a/src/libqof/qof/Makefile.am
+++ b/src/libqof/qof/Makefile.am
@@ -27,7 +27,8 @@ libgnc_qof_la_SOURCES = \
gnc-int128.cpp \
gnc-numeric.cpp \
gnc-rational.cpp \
- gnc-timezone.cpp \
+ gnc-timezone.cpp \
+ gnc-datetime.cpp \
guid.cpp \
kvp-util.cpp \
kvp_frame.cpp \
@@ -55,6 +56,7 @@ qofinclude_HEADERS = \
gnc-numeric.h \
gnc-rational.hpp \
gnc-timezone.hpp \
+ gnc-datetime.hpp \
guid.h \
kvp-util-p.h \
kvp-util.h \
commit ab72874ec14844398588c24cf9a9054540248d26
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 28 10:06:18 2015 -0700
Add GncDate and GncDateTime constructors and accessors:
GncDateImpl constructor and ymd accessor for GncDate
Std::string constructor and nsecs and GDate accessors for GncDateTime.
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index c41bec5..8d2f097 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -44,6 +44,7 @@ static const TimeZoneProvider tzp;
// For converting to/from POSIX time.
static const PTime unix_epoch (Date(1970, boost::gregorian::Jan, 1),
boost::posix_time::seconds(0));
+static const TZ_Ptr utc_zone(new boost::local_time::posix_time_zone("UTC-0"));
/* To ensure things aren't overly screwed up by setting the nanosecond clock for boost::date_time. Don't do it, though, it doesn't get us anything and slows down the date/time library. */
#ifndef BOOST_DATE_TIME_HAS_NANOSECONDS
@@ -63,10 +64,18 @@ public:
GncDateImpl(Date d) : m_greg(d) {}
void today() { m_greg = boost::gregorian::day_clock::local_day(); }
+ ymd ymd() const;
private:
Date m_greg;
};
+ymd
+GncDateImpl::ymd() const
+{
+ auto boost_ymd = m_greg.year_month_day();
+ return {boost_ymd.year, boost_ymd.month.as_number(), boost_ymd.day};
+}
+
/** Private implementation of GncDateTime. See the documentation for that class.
*/
static LDT
@@ -95,6 +104,7 @@ public:
GncDateTimeImpl() : m_time(unix_epoch, tzp.get(unix_epoch.date().year())) {}
GncDateTimeImpl(const time64 time) : m_time(LDT_from_unix_local(time)) {}
GncDateTimeImpl(const struct tm tm) : m_time(LDT_from_struct_tm(tm)) {}
+ GncDateTimeImpl(const std::string str);
GncDateTimeImpl(PTime&& pt) : m_time(pt, tzp.get(pt.date().year())) {}
GncDateTimeImpl(LDT&& ldt) : m_time(ldt) {}
@@ -102,11 +112,41 @@ public:
operator struct tm() const;
void now() { m_time = boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year())); }
long offset() const;
+ long nsecs() const;
+ std::unique_ptr<GncDateImpl> date() const;
std::string format(const char* format) const;
private:
LDT m_time;
};
+GncDateTimeImpl::GncDateTimeImpl(const std::string str) :
+ m_time(unix_epoch, utc_zone)
+{
+ if (str.empty()) return;
+
+ using std::string;
+ using PTZ = boost::local_time::posix_time_zone;
+ TZ_Ptr tzptr;
+ auto tzpos = str.find_first_of("+-", str.find(":"));
+ if (tzpos != str.npos)
+ {
+ string tzstr = "XXX" + str.substr(tzpos);
+ if (tzstr.length() > 6 && tzstr[6] != ':') //6 for XXXsHH, s is + or -
+ tzstr.insert(6, ":");
+ if (tzstr.length() > 9 && tzstr[9] != ':') //9 for XXXsHH:MM
+ tzstr.insert(9, ":");
+ tzptr.reset(new PTZ(tzstr));
+ if (str[tzpos - 1] == ' ') --tzpos;
+ }
+ else
+ {
+ tzptr = utc_zone;
+ }
+
+ auto pdt = boost::posix_time::time_from_string(str.substr(0, tzpos));
+ m_time = LDT(pdt, tzptr);
+}
+
GncDateTimeImpl::operator time64() const
{
auto duration = m_time.utc_time() - unix_epoch;
@@ -127,6 +167,18 @@ GncDateTimeImpl::offset() const
return offset.total_seconds();
}
+long
+GncDateTimeImpl::nsecs() const
+{
+ return (m_time.utc_time() - unix_epoch).ticks() % ticks_per_second;
+}
+
+std::unique_ptr<GncDateImpl>
+GncDateTimeImpl::date() const
+{
+ return std::unique_ptr<GncDateImpl>(new GncDateImpl(m_time.local_time().date()));
+}
+
std::string
GncDateTimeImpl::format(const char* format) const
{
@@ -143,19 +195,33 @@ GncDateTimeImpl::format(const char* format) const
GncDate::GncDate() : m_impl{new GncDateImpl} {}
GncDate::GncDate(int year, int month, int day) :
m_impl(new GncDateImpl(year, month, day)) {}
+GncDate::GncDate(std::unique_ptr<GncDateImpl> impl) :
+ m_impl(std::move(impl)) {}
+GncDate::GncDate(GncDate&&) = default;
GncDate::~GncDate() = default;
+GncDate&
+GncDate::operator=(GncDate&&) = default;
+
void
GncDate::today()
{
m_impl->today();
}
+ymd
+GncDate::ymd() const
+{
+ return m_impl->ymd();
+}
+
GncDateTime::GncDateTime() : m_impl(new GncDateTimeImpl) {}
GncDateTime::GncDateTime(const time64 time) :
m_impl(new GncDateTimeImpl(time)) {}
GncDateTime::GncDateTime(const struct tm tm) :
m_impl(new GncDateTimeImpl(tm)) {}
+GncDateTime::GncDateTime(const std::string str) :
+ m_impl(new GncDateTimeImpl(str)) {}
GncDateTime::~GncDateTime() = default;
void
@@ -180,6 +246,18 @@ GncDateTime::offset() const
return m_impl->offset();
}
+long
+GncDateTime::nsecs() const
+{
+ return m_impl->nsecs();
+}
+
+GncDate
+GncDateTime::date() const
+{
+ return std::move(GncDate(m_impl->date()));
+}
+
std::string
GncDateTime::format(const char* format) const
{
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index 938200c..e2fe6a7 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -27,6 +27,14 @@
#include <cstdint>
#include <memory>
+#include <string>
+
+typedef struct
+{
+ int year; //1400-9999
+ int month; //1-12
+ int day; //1-31
+} ymd;
class GncDateImpl;
class GncDateTimeImpl;
@@ -34,8 +42,7 @@ using time64 = int64_t;
class GncDate
{
-public:
-/** Construct a GncDate representing the current day.
+public:/** Construct a GncDate representing the current day.
*/
GncDate();;
/** Construct a GncDate representing the given year, month, and day in
@@ -52,14 +59,21 @@ public:
* of the constrained range.
*/
GncDate(int year, int month, int day);
+ GncDate(std::unique_ptr<GncDateImpl> impl);
+ GncDate(GncDate&&);
~GncDate();
+ GncDate& operator=(GncDate&&);
/** Set the date object to the computer clock's current day. */
void today();
+/** Get the year, month, and day from the date as a ymd.
+ @return ymd struct
+ */
+ ymd ymd() const;
/** Test that the Date has an implementation. */
bool isnull (void) { return m_impl == nullptr; }
private:
- std::unique_ptr<GncDateImpl> m_impl;
+ std::unique_ptr<GncDateImpl> m_impl;
};
/** GnuCash DateTime class
@@ -88,13 +102,54 @@ public:
* @exception std::invalid_argument if the year is outside the constraints.
*/
GncDateTime(const time64 time);
+/** Construct a GncDateTime in the current timezone representing the
+ * standard struct tm provided.
+ * @param tm: A C-standard struct tm representing the date and
+ * time. Note that the timezone and offset are ignored on those
+ * systems which include them in struct tm.
+ * @exception std::invalid_argument if the year is outside the constraints.
+ */
GncDateTime(const struct tm tm);
+/** Construct a GncDateTime
+ * @param str: A string representing the date and time in some
+ * recognizable format. Note that if a timezone is not specified the
+ * default is UTC, not the local one.
+ * @exception std::invalid_argument if the year is outside the constraints.
+ */
+ GncDateTime(const std::string str);
~GncDateTime();
+/** Set the GncDateTime to the date and time indicated in the computer's clock.
+ */
void now();
+/** Cast the GncDateTime to a time64, seconds from the POSIX epoch. */
explicit operator time64() const;
+/** Cast the GncDateTime to a struct tm. Timezone and offset fields
+ * are not filled.
+ */
explicit operator struct tm() const;
- long offset() const;
+/** Obtain the UTC offset in seconds
+ * @return seconds difference between this local time and UTC. West
+ * is negative.
+ */
+ long offset()const;
+/** Obtain the fractional seconds from the GncDateTime
+ * @return Fractional seconds, represented as nanoseconds, associated
+ * with the time.
+ */
+ long nsecs() const;
+/** Obtain the date from the time, as a GncDate, in the current timezone.
+ * @return GncDate represented by the GncDateTime.
+ */
+ GncDate date() const;
+/** Test if the GncDateTime has a member pointer. Testing only. */
bool isnull (void) { return m_impl == nullptr; }
+/** Format the GncDateTime into a std::string
+
+ * @return a std::string containing a representation of the date
+ * according to the format. Consult the boost::date_time
+ * documentation for format characters; while they mostly compy with
+ * POSIX there are a few differences.
+ */
std::string format(const char* format) const;
private:
diff --git a/src/libqof/qof/test/Makefile.am b/src/libqof/qof/test/Makefile.am
index 84dfa86..f81ddc0 100644
--- a/src/libqof/qof/test/Makefile.am
+++ b/src/libqof/qof/test/Makefile.am
@@ -95,7 +95,9 @@ test_gnc_datetime_CPPFLAGS =\
-I$(GTEST_HEADERS) \
-I$(top_srcdir)/src \
$(BOOST_CPPFLAGS)
-test_gnc_datetime_LDADD = $(GTEST_LIBS)
+test_gnc_datetime_LDADD = \
+ -lboost_date_time \
+ $(GTEST_LIBS)
if !GOOGLE_TEST_LIBS
nodist_test_gnc_datetime_SOURCES = \
$(GTEST_SRC)/src/gtest_main.cc
diff --git a/src/libqof/qof/test/gtest-gnc-datetime.cpp b/src/libqof/qof/test/gtest-gnc-datetime.cpp
index b49ea96..da47b0c 100644
--- a/src/libqof/qof/test/gtest-gnc-datetime.cpp
+++ b/src/libqof/qof/test/gtest-gnc-datetime.cpp
@@ -76,3 +76,14 @@ TEST(gnc_datetime_functions, test_format)
//Date only to finesse timezone issues. It will still fail in +12 DST.
EXPECT_EQ(atime.format("%d-%m-%Y"), "13-11-2045");
}
+
+//This is a bit convoluted because it uses GncDate's GncDateImpl constructor and ymd() function. There's no good way to test the former without violating the privacy of the implementation.
+TEST(gnc_datetime_functions, test_date)
+{
+ GncDateTime atime(2394187200); //2045-11-13 12:00:00 Z
+ GncDate gncd = std::move(atime.date());
+ auto ymd = gncd.ymd();
+ EXPECT_EQ(ymd.year, 2045);
+ EXPECT_EQ(ymd.month, 11);
+ EXPECT_EQ(ymd.day, 13);
+}
commit 3f87f56e2ed41e5c93c284dc19c375f155176430
Author: John Ralls <jralls at ceridwen.us>
Date: Sun Apr 26 18:01:23 2015 -0700
Implement formatted output.
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index f2ab5b6..c41bec5 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -102,7 +102,7 @@ public:
operator struct tm() const;
void now() { m_time = boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year())); }
long offset() const;
-
+ std::string format(const char* format) const;
private:
LDT m_time;
};
@@ -127,6 +127,18 @@ GncDateTimeImpl::offset() const
return offset.total_seconds();
}
+std::string
+GncDateTimeImpl::format(const char* format) const
+{
+ using Facet = boost::local_time::local_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;
+ return ss.str();
+}
+
/* =================== Presentation-class Implementations ====================*/
GncDate::GncDate() : m_impl{new GncDateImpl} {}
GncDate::GncDate(int year, int month, int day) :
@@ -167,3 +179,9 @@ GncDateTime::offset() const
{
return m_impl->offset();
}
+
+std::string
+GncDateTime::format(const char* format) const
+{
+ return m_impl->format(format);
+}
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index d676d59..938200c 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -95,6 +95,7 @@ public:
explicit operator struct tm() const;
long offset() const;
bool isnull (void) { return m_impl == nullptr; }
+ std::string format(const char* format) const;
private:
std::unique_ptr<GncDateTimeImpl> m_impl;
diff --git a/src/libqof/qof/test/gtest-gnc-datetime.cpp b/src/libqof/qof/test/gtest-gnc-datetime.cpp
index dab386f..b49ea96 100644
--- a/src/libqof/qof/test/gtest-gnc-datetime.cpp
+++ b/src/libqof/qof/test/gtest-gnc-datetime.cpp
@@ -69,3 +69,10 @@ TEST(gnc_datetime_constructors, test_struct_tm_constructor)
EXPECT_EQ((24 + tm1.tm_hour - atime.offset() / 3600) % 24, tm.tm_hour);
EXPECT_EQ(tm1.tm_min, tm.tm_min);
}
+
+TEST(gnc_datetime_functions, test_format)
+{
+ 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("%d-%m-%Y"), "13-11-2045");
+}
commit cbb01c94ae8d76a01d08410b09d7e4e74e3bca0f
Author: John Ralls <jralls at ceridwen.us>
Date: Sun Apr 26 16:44:39 2015 -0700
Implement struct tm constructor and cast, offset accessor.
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index 7c5774b..f2ab5b6 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -79,16 +79,29 @@ LDT_from_unix_local(const time64 time)
return LDT(temp, tz);
}
+static LDT
+LDT_from_struct_tm(const struct tm tm)
+{
+ auto tdate = boost::gregorian::date_from_tm(tm);
+ auto tdur = boost::posix_time::time_duration(tm.tm_hour, tm.tm_min,
+ tm.tm_sec, 0);
+ auto tz = tzp.get(tdate.year());
+ return LDT(PTime(tdate, tdur), tz);
+}
+
class GncDateTimeImpl
{
public:
GncDateTimeImpl() : m_time(unix_epoch, tzp.get(unix_epoch.date().year())) {}
GncDateTimeImpl(const time64 time) : m_time(LDT_from_unix_local(time)) {}
+ GncDateTimeImpl(const struct tm tm) : m_time(LDT_from_struct_tm(tm)) {}
GncDateTimeImpl(PTime&& pt) : m_time(pt, tzp.get(pt.date().year())) {}
GncDateTimeImpl(LDT&& ldt) : m_time(ldt) {}
operator time64() const;
+ operator struct tm() const;
void now() { m_time = boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year())); }
+ long offset() const;
private:
LDT m_time;
@@ -102,6 +115,18 @@ GncDateTimeImpl::operator time64() const
return secs;
}
+GncDateTimeImpl::operator struct tm() const
+{
+ return to_tm(m_time);
+}
+
+long
+GncDateTimeImpl::offset() const
+{
+ auto offset = m_time.local_time() - m_time.utc_time();
+ return offset.total_seconds();
+}
+
/* =================== Presentation-class Implementations ====================*/
GncDate::GncDate() : m_impl{new GncDateImpl} {}
GncDate::GncDate(int year, int month, int day) :
@@ -115,7 +140,10 @@ GncDate::today()
}
GncDateTime::GncDateTime() : m_impl(new GncDateTimeImpl) {}
-GncDateTime::GncDateTime(time64 time) : m_impl(new GncDateTimeImpl(time)) {}
+GncDateTime::GncDateTime(const time64 time) :
+ m_impl(new GncDateTimeImpl(time)) {}
+GncDateTime::GncDateTime(const struct tm tm) :
+ m_impl(new GncDateTimeImpl(tm)) {}
GncDateTime::~GncDateTime() = default;
void
@@ -128,3 +156,14 @@ GncDateTime::operator time64() const
{
return m_impl->operator time64();
}
+
+GncDateTime::operator struct tm() const
+{
+ return m_impl->operator struct tm();
+}
+
+long
+GncDateTime::offset() const
+{
+ return m_impl->offset();
+}
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index 015b884..d676d59 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -87,10 +87,13 @@ public:
* @param time: Seconds from the POSIX epoch.
* @exception std::invalid_argument if the year is outside the constraints.
*/
- GncDateTime(time64 time);
+ GncDateTime(const time64 time);
+ GncDateTime(const struct tm tm);
~GncDateTime();
void now();
explicit operator time64() const;
+ explicit operator struct tm() const;
+ long offset() const;
bool isnull (void) { return m_impl == nullptr; }
private:
diff --git a/src/libqof/qof/test/gtest-gnc-datetime.cpp b/src/libqof/qof/test/gtest-gnc-datetime.cpp
index 4f41147..dab386f 100644
--- a/src/libqof/qof/test/gtest-gnc-datetime.cpp
+++ b/src/libqof/qof/test/gtest-gnc-datetime.cpp
@@ -50,3 +50,22 @@ TEST(gnc_datetime_constructors, test_time64_constructor)
EXPECT_EQ(static_cast<time64>(atime), time);
}
+TEST(gnc_datetime_constructors, test_struct_tm_constructor)
+{
+#ifdef HAVE_STRUCT_TM_GMTOFF
+ const struct tm tm {0, 0, 12, 13, 10, 145, 0, 0, 0, NULL, 0 };
+#else
+ const struct tm tm {0, 0, 12, 13, 10, 145, 0, 0, 0 };
+#endif
+
+ const time64 time = 2394187200; //2045-11-13 12:00:00 Z
+ GncDateTime atime(tm);
+ EXPECT_EQ(static_cast<time64>(atime), time);
+ const struct tm tm1 = static_cast<struct tm>(atime);
+ EXPECT_EQ(tm1.tm_year, tm.tm_year);
+ EXPECT_EQ(tm1.tm_mon, tm.tm_mon);
+ EXPECT_EQ(tm1.tm_mday, tm.tm_mday);
+// We have to contort this a bit to handle offsets > 12, e.g. New Zealand during DST.
+ EXPECT_EQ((24 + tm1.tm_hour - atime.offset() / 3600) % 24, tm.tm_hour);
+ EXPECT_EQ(tm1.tm_min, tm.tm_min);
+}
commit e5861dc119aa3fc15dc8c30bf746cf969d5a19d4
Author: John Ralls <jralls at ceridwen.us>
Date: Fri Apr 10 09:33:51 2015 -0700
Add operator time64() to enable static_casting a GncDateTime.
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index 0cf4412..7c5774b 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -86,11 +86,20 @@ public:
GncDateTimeImpl(const time64 time) : m_time(LDT_from_unix_local(time)) {}
GncDateTimeImpl(PTime&& pt) : m_time(pt, tzp.get(pt.date().year())) {}
GncDateTimeImpl(LDT&& ldt) : m_time(ldt) {}
+
+ operator time64() const;
void now() { m_time = boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year())); }
private:
LDT m_time;
};
+
+GncDateTimeImpl::operator time64() const
+{
+ auto duration = m_time.utc_time() - unix_epoch;
+ auto secs = duration.ticks();
+ secs /= ticks_per_second;
+ return secs;
}
/* =================== Presentation-class Implementations ====================*/
@@ -114,4 +123,8 @@ GncDateTime::now()
{
m_impl->now();
}
+
+GncDateTime::operator time64() const
+{
+ return m_impl->operator time64();
}
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index c70f045..015b884 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -90,6 +90,7 @@ public:
GncDateTime(time64 time);
~GncDateTime();
void now();
+ explicit operator time64() const;
bool isnull (void) { return m_impl == nullptr; }
private:
diff --git a/src/libqof/qof/test/gtest-gnc-datetime.cpp b/src/libqof/qof/test/gtest-gnc-datetime.cpp
index 4a3d288..4f41147 100644
--- a/src/libqof/qof/test/gtest-gnc-datetime.cpp
+++ b/src/libqof/qof/test/gtest-gnc-datetime.cpp
@@ -40,12 +40,13 @@ TEST(gnc_date_constructors, test_ymd_constructor)
TEST(gnc_datetime_constructors, test_default_constructor)
{
GncDateTime atime;
- EXPECT_FALSE(atime.isnull());
+ EXPECT_EQ(static_cast<time64>(atime), static_cast<time64>(INT64_C(0)));
}
TEST(gnc_datetime_constructors, test_time64_constructor)
{
const time64 time = 2394187200; //2045-11-13 12:00:00 Z
GncDateTime atime(time);
- EXPECT_FALSE(atime.isnull());
+ EXPECT_EQ(static_cast<time64>(atime), time);
}
+
commit 10daa27abc22bb122ecc504865e22a58c41b073a
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Apr 7 15:36:40 2015 -0700
Default constructors return the epoch.
GncDate::today() and GncDateTime::now() get the current date and time.
Suggested in a C++Now talk by Jeff Garland, the author of boost::date_time.
Reasoning is that getting time from the system clock is expensive and so
shouldn't be done unless needed.
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index 12d7673..0cf4412 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -45,30 +45,30 @@ static const TimeZoneProvider tzp;
static const PTime unix_epoch (Date(1970, boost::gregorian::Jan, 1),
boost::posix_time::seconds(0));
+/* To ensure things aren't overly screwed up by setting the nanosecond clock for boost::date_time. Don't do it, though, it doesn't get us anything and slows down the date/time library. */
+#ifndef BOOST_DATE_TIME_HAS_NANOSECONDS
+static constexpr auto ticks_per_second = INT64_C(1000000);
+#else
+static constexpr auto ticks_per_second = INT64_C(1000000000);
+#endif
/** Private implementation of GncDate. See the documentation for that class.
*/
class GncDateImpl
{
public:
- GncDateImpl(): m_greg(boost::gregorian::day_clock::local_day()) {}
+ GncDateImpl(): m_greg(unix_epoch.date()) {}
GncDateImpl(const int year, const int month, const int day) :
m_greg(year, static_cast<Month>(month), day) {}
+ GncDateImpl(Date d) : m_greg(d) {}
+
+ void today() { m_greg = boost::gregorian::day_clock::local_day(); }
private:
Date m_greg;
};
/** Private implementation of GncDateTime. See the documentation for that class.
*/
-class GncDateTimeImpl
-{
-public:
- GncDateTimeImpl() : m_time(boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year()))) {}
- GncDateTimeImpl(const time64 time);
-private:
- LDT m_time;
-};
-
static LDT
LDT_from_unix_local(const time64 time)
{
@@ -79,14 +79,39 @@ LDT_from_unix_local(const time64 time)
return LDT(temp, tz);
}
-GncDateTimeImpl::GncDateTimeImpl(const time64 time) :
- m_time(LDT_from_unix_local(time)) {}
+class GncDateTimeImpl
+{
+public:
+ GncDateTimeImpl() : m_time(unix_epoch, tzp.get(unix_epoch.date().year())) {}
+ GncDateTimeImpl(const time64 time) : m_time(LDT_from_unix_local(time)) {}
+ GncDateTimeImpl(PTime&& pt) : m_time(pt, tzp.get(pt.date().year())) {}
+ GncDateTimeImpl(LDT&& ldt) : m_time(ldt) {}
+ void now() { m_time = boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year())); }
+private:
+ LDT m_time;
+};
+}
+
+/* =================== Presentation-class Implementations ====================*/
GncDate::GncDate() : m_impl{new GncDateImpl} {}
GncDate::GncDate(int year, int month, int day) :
m_impl(new GncDateImpl(year, month, day)) {}
GncDate::~GncDate() = default;
+void
+GncDate::today()
+{
+ m_impl->today();
+}
+
GncDateTime::GncDateTime() : m_impl(new GncDateTimeImpl) {}
GncDateTime::GncDateTime(time64 time) : m_impl(new GncDateTimeImpl(time)) {}
GncDateTime::~GncDateTime() = default;
+
+void
+GncDateTime::now()
+{
+ m_impl->now();
+}
+}
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
index b145357..c70f045 100644
--- a/src/libqof/qof/gnc-datetime.hpp
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -53,7 +53,9 @@ public:
*/
GncDate(int year, int month, int day);
~GncDate();
-
+/** Set the date object to the computer clock's current day. */
+ void today();
+/** Test that the Date has an implementation. */
bool isnull (void) { return m_impl == nullptr; }
private:
@@ -87,7 +89,7 @@ public:
*/
GncDateTime(time64 time);
~GncDateTime();
-
+ void now();
bool isnull (void) { return m_impl == nullptr; }
private:
commit 01f5a9c04c4c78f5021470a8297142a0704202b4
Author: John Ralls <jralls at ceridwen.us>
Date: Fri Mar 27 10:00:15 2015 +0900
Update filename, copyright in comments for gnu-date.c
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index f523546..db6f22e 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -1,9 +1,9 @@
/********************************************************************\
- * gnc-date.c -- misc utility functions to handle date and time *
- * (to be renamed qofdate.c in libqof2) *
+ * gnc-date.cpp -- C interface for date and time *
* *
- * Copyright (C) 1997 Robin D. Clark <rclark at cs.hmc.edu> *
- * Copyright (C) 1998-2000, 2003 Linas Vepstas <linas at linas.org> *
+ * Copyright 1997 Robin D. Clark <rclark at cs.hmc.edu> *
+ * Copyright 1998-2000, 2003 Linas Vepstas <linas at linas.org> *
+ * Copyright 2011-2015 John Ralls <jralls at ceridwen.us *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@@ -45,6 +45,7 @@ extern "C"
#include "gnc-date.h"
#include "gnc-date-p.h"
+//#include "gnc-datetime.hpp"
#include "gnc-timezone.hpp"
#define N_(string) string //So that xgettext will find it
commit 307c08e2b5c6bc00c0b106a570af2bba6e9afd77
Author: John Ralls <jralls at ceridwen.us>
Date: Fri Mar 27 09:59:06 2015 +0900
Begin GncDate and GncDateTime classes.
Goal is to get the boost::date_time code out of gnu-date.c, to provide
date-time functionality directly to C++, and to replace GDate.
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
new file mode 100644
index 0000000..12d7673
--- /dev/null
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -0,0 +1,92 @@
+/********************************************************************\
+ * gnc-datetime.cpp -- Date and Time classes for GnuCash *
+ * *
+ * Copyright 2015 John Ralls <jralls at ceridwen.us> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+ * *
+\********************************************************************/
+
+extern "C"
+{
+#include "config.h"
+#include "platform.h"
+}
+#include <boost/date_time/gregorian/gregorian.hpp>
+#include <memory>
+#include "gnc-timezone.hpp"
+#include "gnc-datetime.hpp"
+
+using Date = boost::gregorian::date;
+using Month = boost::gregorian::greg_month;
+using PTime = boost::posix_time::ptime;
+using LDT = boost::local_time::local_date_time;
+using Duration = boost::posix_time::time_duration;
+using LDTBase = boost::local_time::local_date_time_base<PTime, boost::date_time::time_zone_base<PTime, char>>;
+using time64 = int64_t;
+
+static const TimeZoneProvider tzp;
+// For converting to/from POSIX time.
+static const PTime unix_epoch (Date(1970, boost::gregorian::Jan, 1),
+ boost::posix_time::seconds(0));
+
+
+/** Private implementation of GncDate. See the documentation for that class.
+ */
+class GncDateImpl
+{
+public:
+ GncDateImpl(): m_greg(boost::gregorian::day_clock::local_day()) {}
+ GncDateImpl(const int year, const int month, const int day) :
+ m_greg(year, static_cast<Month>(month), day) {}
+private:
+ Date m_greg;
+};
+
+/** Private implementation of GncDateTime. See the documentation for that class.
+ */
+class GncDateTimeImpl
+{
+public:
+ GncDateTimeImpl() : m_time(boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year()))) {}
+ GncDateTimeImpl(const time64 time);
+private:
+ LDT m_time;
+};
+
+static LDT
+LDT_from_unix_local(const time64 time)
+{
+ PTime temp(unix_epoch.date(),
+ boost::posix_time::hours(time / 3600) +
+ boost::posix_time::seconds(time % 3600));
+ auto tz = tzp.get(temp.date().year());
+ return LDT(temp, tz);
+}
+
+GncDateTimeImpl::GncDateTimeImpl(const time64 time) :
+ m_time(LDT_from_unix_local(time)) {}
+
+GncDate::GncDate() : m_impl{new GncDateImpl} {}
+GncDate::GncDate(int year, int month, int day) :
+ m_impl(new GncDateImpl(year, month, day)) {}
+GncDate::~GncDate() = default;
+
+GncDateTime::GncDateTime() : m_impl(new GncDateTimeImpl) {}
+GncDateTime::GncDateTime(time64 time) : m_impl(new GncDateTimeImpl(time)) {}
+GncDateTime::~GncDateTime() = default;
diff --git a/src/libqof/qof/gnc-datetime.hpp b/src/libqof/qof/gnc-datetime.hpp
new file mode 100644
index 0000000..b145357
--- /dev/null
+++ b/src/libqof/qof/gnc-datetime.hpp
@@ -0,0 +1,97 @@
+/********************************************************************\
+ * gnc-datetime.cpp -- Date and Time classes for GnuCash *
+ * *
+ * Copyright 2015 John Ralls <jralls at ceridwen.us> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+ * *
+\********************************************************************/
+
+#ifndef __GNC_DATETIME_HPP__
+#define __GNC_DATETIME_HPP__
+
+#include <cstdint>
+#include <memory>
+
+class GncDateImpl;
+class GncDateTimeImpl;
+using time64 = int64_t;
+
+class GncDate
+{
+public:
+/** Construct a GncDate representing the current day.
+ */
+ GncDate();;
+/** Construct a GncDate representing the given year, month, and day in
+ * the proleptic Gregorian calendar.
+ *
+ * Years are constrained to be from 1400 - 9999 CE inclusive. Dates
+ * will be normalized if the day or month values are outside of the
+ * normal ranges. e.g. 1994, -3, 47 will be normalized to 1993-10-17.
+ *
+ * @param year: The year in the Common Era.
+ * @param month: The month, where 1 is January and 12 is December.
+ * @param day: The day of the month, beginning with 1.
+ * @exception std::invalid_argument if the calculated year is outside
+ * of the constrained range.
+ */
+ GncDate(int year, int month, int day);
+ ~GncDate();
+
+ bool isnull (void) { return m_impl == nullptr; }
+
+private:
+ std::unique_ptr<GncDateImpl> m_impl;
+};
+
+/** GnuCash DateTime class
+ *
+ * Represents local time in the current timezone.
+ * As with GncDate, the represented time is limited to the period
+ * between 1400 and 9999 CE.
+ *
+ * Be careful when using times: A particular time is represented
+ * differently depending on the timezone, which can shif the displayed
+ * date. Accounting is generally not sensitive to the time of day, but
+ * is sensitive to the recorded day. Since GncDates are not timezone
+ * dependent they should be preferred for accounting entries.
+ */
+
+class GncDateTime
+{
+public:
+/** Construct a GncDateTime representing the current time in the
+ * current timezone.
+ */
+ GncDateTime();
+/** Construct a GncDateTime in the current timezone representing the
+ * timestamp as seconds from the POSIX epoch (1970-01-01T00:00:00UTC).
+ * @param time: Seconds from the POSIX epoch.
+ * @exception std::invalid_argument if the year is outside the constraints.
+ */
+ GncDateTime(time64 time);
+ ~GncDateTime();
+
+ bool isnull (void) { return m_impl == nullptr; }
+
+private:
+ std::unique_ptr<GncDateTimeImpl> m_impl;
+};
+
+#endif // __GNC_DATETIME_HPP__
diff --git a/src/libqof/qof/test/Makefile.am b/src/libqof/qof/test/Makefile.am
index 15ed8fc..84dfa86 100644
--- a/src/libqof/qof/test/Makefile.am
+++ b/src/libqof/qof/test/Makefile.am
@@ -86,6 +86,23 @@ nodist_test_gnc_timezone_SOURCES = \
test_gnc_timezone_LDADD += $(top_builddir)/src/test-core/libgtest.a
endif
check_PROGRAMS += test-gnc-timezone
+
+test_gnc_datetime_SOURCES = \
+ $(top_srcdir)/$(MODULEPATH)/gnc-datetime.cpp \
+ $(top_srcdir)/$(MODULEPATH)/gnc-timezone.cpp \
+ gtest-gnc-datetime.cpp
+test_gnc_datetime_CPPFLAGS =\
+ -I$(GTEST_HEADERS) \
+ -I$(top_srcdir)/src \
+ $(BOOST_CPPFLAGS)
+test_gnc_datetime_LDADD = $(GTEST_LIBS)
+if !GOOGLE_TEST_LIBS
+nodist_test_gnc_datetime_SOURCES = \
+ $(GTEST_SRC)/src/gtest_main.cc
+test_gnc_datetime_LDADD += $(top_builddir)/src/test-core/libgtest.a
+endif
+check_PROGRAMS += test-gnc-datetime
+
endif
test_qofdir = ${GNC_LIBEXECDIR}/${MODULEPATH}/test
diff --git a/src/libqof/qof/test/gtest-gnc-datetime.cpp b/src/libqof/qof/test/gtest-gnc-datetime.cpp
new file mode 100644
index 0000000..4a3d288
--- /dev/null
+++ b/src/libqof/qof/test/gtest-gnc-datetime.cpp
@@ -0,0 +1,51 @@
+/********************************************************************\
+ * test-gnc-datetime.cpp -- Unit tests for GncDate and GncDateTime *
+ * *
+ * Copyright 2015 John Ralls <jralls at ceridwen.us> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+ * *
+\********************************************************************/
+
+#include "../gnc-datetime.hpp"
+#include <gtest/gtest.h>
+
+TEST(gnc_date_constructors, test_default_constructor)
+{
+ GncDate date;
+ EXPECT_FALSE(date.isnull());
+}
+
+TEST(gnc_date_constructors, test_ymd_constructor)
+{
+ GncDate date(2045, 11, 13);
+ EXPECT_FALSE(date.isnull());
+}
+
+TEST(gnc_datetime_constructors, test_default_constructor)
+{
+ GncDateTime atime;
+ EXPECT_FALSE(atime.isnull());
+}
+
+TEST(gnc_datetime_constructors, test_time64_constructor)
+{
+ const time64 time = 2394187200; //2045-11-13 12:00:00 Z
+ GncDateTime atime(time);
+ EXPECT_FALSE(atime.isnull());
+}
commit 09356976cc7929fa9e2504dbbef69e0fc7d81e55
Author: John Ralls <jralls at ceridwen.us>
Date: Mon Mar 23 17:04:26 2015 +0900
Fix test-aqb timestamp so that it's 29 August in most timezones.
diff --git a/src/import-export/aqb/test/file-book-hbcislot.gnucash b/src/import-export/aqb/test/file-book-hbcislot.gnucash
index e4b6c00..41d0f65 100644
--- a/src/import-export/aqb/test/file-book-hbcislot.gnucash
+++ b/src/import-export/aqb/test/file-book-hbcislot.gnucash
@@ -109,7 +109,7 @@
<slot>
<slot:key>trans-retrieval</slot:key>
<slot:value type="timespec">
- <ts:date>2014-08-29 20:47:36 +0200</ts:date>
+ <ts:date>2014-08-29 13:47:36 +0200</ts:date>
</slot:value>
</slot>
</slot:value>
commit d0ae8c370ea94133537403d036d07bbe2ae9a534
Author: John Ralls <john at aeolus.local>
Date: Mon Mar 23 11:35:05 2015 +0900
Fix stray if and tab-indentation.
diff --git a/src/libqof/qof/test/test-gnc-date.c b/src/libqof/qof/test/test-gnc-date.c
index 3f1a7c4..93f9943 100644
--- a/src/libqof/qof/test/test-gnc-date.c
+++ b/src/libqof/qof/test/test-gnc-date.c
@@ -1,6 +1,6 @@
/********************************************************************
- * utest-gnc-date.c: GLib g_test test suite for gnc-date.c. *
- * Copyright 2012 John Ralls <jralls at ceridwen.us> *
+ * utest-gnc-date.c: GLib g_test test suite for gnc-date.c. *
+ * Copyright 2012 John Ralls <jralls at ceridwen.us> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@@ -144,20 +144,19 @@ test_gnc_localtime (void)
1364160236LL};
guint ind;
if (sizeof(time_t) < sizeof(time64))
- secs[0] = -432761LL;
+ secs[0] = -432761LL;
for (ind = 0; ind < G_N_ELEMENTS (secs); ind++)
{
- if (sizeof(time_t) == sizeof())
struct tm* time = gnc_localtime (&secs[ind]);
- time_t tsecs;
- struct tm* ans;
+ time_t tsecs;
+ struct tm* ans;
if (secs[ind] > max_secs)
{
g_assert (time == NULL);
continue;
}
- tsecs = (time_t)(secs[ind]);
- ans = localtime(&tsecs);
+ tsecs = (time_t)(secs[ind]);
+ ans = localtime(&tsecs);
g_assert_cmpint (time->tm_year, ==, ans->tm_year);
g_assert_cmpint (time->tm_mon, ==, ans->tm_mon);
g_assert_cmpint (time->tm_mday, ==, ans->tm_mday);
@@ -166,7 +165,7 @@ test_gnc_localtime (void)
g_assert_cmpint (time->tm_sec, ==, ans->tm_sec);
g_assert_cmpint (time->tm_wday, ==, ans->tm_wday);
g_assert_cmpint (time->tm_yday, ==, ans->tm_yday);
- g_assert_cmpint (time->tm_isdst, ==, ans->tm_isdst);
+ g_assert_cmpint (time->tm_isdst, ==, ans->tm_isdst);
#ifdef HAVE_STRUCT_TM_GMTOFF
g_assert_cmpint (time->tm_gmtoff, ==, ans->tm_gmtoff);
#endif
@@ -315,11 +314,11 @@ test_gnc_ctime (void)
guint ind;
for (ind = 0; ind < G_N_ELEMENTS (secs); ind++)
{
- time_t time;
- char *datestr;
- if (secs[ind] < INT32_MIN)
- continue;
- time = (time_t)secs[ind];
+ time_t time;
+ char *datestr;
+ if (secs[ind] < INT32_MIN)
+ continue;
+ time = (time_t)secs[ind];
datestr = gnc_ctime (&secs[ind]);
g_assert_cmpstr (datestr, ==, strtok(ctime(&time), "\n"));
g_free (datestr);
@@ -451,10 +450,10 @@ test_gnc_setlocale (int category, gchar *locale)
return;
}
g_fprintf (stderr, "There are some differences between distros in the way they name"
- "locales, and this can cause trouble with the locale-based"
- "formatting. If you get the assert in this function, run locale -a"
- "and make sure that en_US, en_GB, and fr_FR are installed and that"
- "if a suffix is needed it's in the suffixes array.");
+ "locales, and this can cause trouble with the locale-based"
+ "formatting. If you get the assert in this function, run locale -a"
+ "and make sure that en_US, en_GB, and fr_FR are installed and that"
+ "if a suffix is needed it's in the suffixes array.");
g_assert_not_reached ();
}
/* timespec_normalize
@@ -695,7 +694,7 @@ test_timespecCanonicalDayTime (void)
g_assert_cmpint (na.tv_sec, ==, ra.tv_sec);
g_assert_cmpint (nb.tv_sec, ==, rb.tv_sec);
if (sizeof(time_t) >= sizeof(time64))
- g_assert_cmpint (nc.tv_sec, ==, rc.tv_sec);
+ g_assert_cmpint (nc.tv_sec, ==, rc.tv_sec);
}
/* gnc_date_get_last_mday
@@ -954,7 +953,7 @@ test_qof_print_date_dmy_buff (void)
gchar t_buff[MAX_DATE_LENGTH]; \
struct tm *ltime = gnc_localtime ((time64 *)(&time)); \
strftime (t_buff, sizeof (t_buff), GNC_D_FMT, ltime); \
- gnc_tm_free (ltime); \
+ gnc_tm_free (ltime); \
g_assert_cmpstr (datestr, ==, t_buff); \
}
@@ -1215,14 +1214,14 @@ test_qof_print_gdate (void)
#define test_assert_qof_print_date(time, datestr) \
{ \
gchar *buf = qof_print_date (time); \
- g_assert_cmpstr (buf, ==, datestr); \
+ g_assert_cmpstr (buf, ==, datestr); \
g_free (buf); \
}
#define test_assert_qof_print_date_outside_range(time, datestr) \
{ \
gchar *buf = qof_print_date (time); \
- g_assert_cmpstr (buf, ==, datestr); \
+ g_assert_cmpstr (buf, ==, datestr); \
g_free (buf); \
}
@@ -1765,16 +1764,16 @@ test_gnc_dmy2timespec (FixtureB *f, gconstpointer pData)
for (int i = 0; i < sizeof(f->test)/sizeof(TimeMap); ++i)
{
#ifdef HAVE_STRUCT_TM_GMTOFF
- struct tm tm = {0, 0, 0, f->test[i].day, f->test[i].mon - 1,
- f->test[i].yr - 1900, 0, 0, -1, 0, NULL};
+ struct tm tm = {0, 0, 0, f->test[i].day, f->test[i].mon - 1,
+ f->test[i].yr - 1900, 0, 0, -1, 0, NULL};
#else
- struct tm tm = {0, 0, 0, f->test[i].day, f->test[i].mon - 1,
- f->test[i].yr - 1900, 0, 0, -1};
+ struct tm tm = {0, 0, 0, f->test[i].day, f->test[i].mon - 1,
+ f->test[i].yr - 1900, 0, 0, -1};
#endif
- Timespec r_t = gnc_dmy2timespec (f->test[i].day, f->test[i].mon,
- f->test[i].yr);
- int offset = gnc_mktime(&tm) - gnc_timegm(&tm);
- g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs + offset);
+ Timespec r_t = gnc_dmy2timespec (f->test[i].day, f->test[i].mon,
+ f->test[i].yr);
+ int offset = gnc_mktime(&tm) - gnc_timegm(&tm);
+ g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs + offset);
}
}
/* gnc_dmy2timespec_end
@@ -1787,16 +1786,16 @@ test_gnc_dmy2timespec_end (FixtureB *f, gconstpointer pData)
for (int i = 0; i < sizeof(f->test)/sizeof(TimeMap); ++i)
{
#ifdef HAVE_STRUCT_TM_GMTOFF
- struct tm tm = {59, 59, 23, f->test[i].day, f->test[i].mon - 1,
- f->test[i].yr - 1900, 0, 0, -1, 0, NULL};
+ struct tm tm = {59, 59, 23, f->test[i].day, f->test[i].mon - 1,
+ f->test[i].yr - 1900, 0, 0, -1, 0, NULL};
#else
- struct tm tm = {59, 59, 23, f->test[i].day, f->test[i].mon - 1,
- f->test[i].yr - 1900, 0, 0, -1};
+ struct tm tm = {59, 59, 23, f->test[i].day, f->test[i].mon - 1,
+ f->test[i].yr - 1900, 0, 0, -1};
#endif
- Timespec r_t = gnc_dmy2timespec_end (f->test[i].day, f->test[i].mon,
- f->test[i].yr);
- int offset = gnc_mktime(&tm) - gnc_timegm(&tm);
- g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs + offset);
+ Timespec r_t = gnc_dmy2timespec_end (f->test[i].day, f->test[i].mon,
+ f->test[i].yr);
+ int offset = gnc_mktime(&tm) - gnc_timegm(&tm);
+ g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs + offset);
}
}
@@ -1847,37 +1846,37 @@ test_timespec_to_gdate (FixtureA *f, gconstpointer pData)
gnc_localtime_r(&f->ts0.tv_sec, &tm);
g_date_set_dmy (&date2, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
g_assert_cmpint (g_date_get_julian (&date1), ==,
- g_date_get_julian (&date2));
+ g_date_get_julian (&date2));
date1 = timespec_to_gdate (f->ts1);
gnc_localtime_r(&f->ts1.tv_sec, &tm);
g_date_set_dmy (&date2, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
g_assert_cmpint (g_date_get_julian (&date1), ==,
- g_date_get_julian (&date2));
+ g_date_get_julian (&date2));
date1 = timespec_to_gdate (f->ts2);
gnc_localtime_r(&f->ts2.tv_sec, &tm);
g_date_set_dmy (&date2, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
g_assert_cmpint (g_date_get_julian (&date1), ==,
- g_date_get_julian (&date2));
+ g_date_get_julian (&date2));
date1 = timespec_to_gdate (f->ts3);
gnc_localtime_r(&f->ts3.tv_sec, &tm);
g_date_set_dmy (&date2, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
g_assert_cmpint (g_date_get_julian (&date1), ==,
- g_date_get_julian (&date2));
+ g_date_get_julian (&date2));
date1 = timespec_to_gdate (f->ts4);
gnc_localtime_r(&f->ts4.tv_sec, &tm);
g_date_set_dmy (&date2, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
g_assert_cmpint (g_date_get_julian (&date1), ==,
- g_date_get_julian (&date2));
+ g_date_get_julian (&date2));
date1 = timespec_to_gdate (f->ts5);
gnc_localtime_r(&f->ts5.tv_sec, &tm);
g_date_set_dmy (&date2, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
g_assert_cmpint (g_date_get_julian (&date1), ==,
- g_date_get_julian (&date2));
+ g_date_get_julian (&date2));
}
/* gdate_to_timespec
@@ -1889,19 +1888,19 @@ test_gdate_to_timespec (FixtureB *f, gconstpointer pData)
for (int i = 0; i < sizeof(f->test)/sizeof(TimeMap); ++i)
{
#ifdef HAVE_STRUCT_TM_GMTOFF
- struct tm tm = {0, 0, 0, f->test[i].day, f->test[i].mon - 1,
- f->test[i].yr - 1900, 0, 0, -1, 0, NULL};
+ struct tm tm = {0, 0, 0, f->test[i].day, f->test[i].mon - 1,
+ f->test[i].yr - 1900, 0, 0, -1, 0, NULL};
#else
- struct tm tm = {0, 0, 0, f->test[i].day, f->test[i].mon - 1,
- f->test[i].yr - 1900, 0, 0, -1};
+ struct tm tm = {0, 0, 0, f->test[i].day, f->test[i].mon - 1,
+ f->test[i].yr - 1900, 0, 0, -1};
#endif
- GDate gd;
- Timespec r_t;
- int offset = gnc_mktime(&tm) - gnc_timegm(&tm);
- g_date_clear(&gd, 1);
- g_date_set_dmy(&gd, f->test[i].day, f->test[i].mon, f->test[i].yr);
- r_t = gdate_to_timespec(gd);
- g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs + offset);
+ GDate gd;
+ Timespec r_t;
+ int offset = gnc_mktime(&tm) - gnc_timegm(&tm);
+ g_date_clear(&gd, 1);
+ g_date_set_dmy(&gd, f->test[i].day, f->test[i].mon, f->test[i].yr);
+ r_t = gdate_to_timespec(gd);
+ g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs + offset);
}
}
/* gnc_tm_get_day_start
commit d0b916c6f96882fe9508041c92f8d546559d9df5
Author: John Ralls <jralls at ceridwen.us>
Date: Mon Mar 2 08:27:04 2015 -0800
Fix offset calculations for TZif2 files.
diff --git a/src/libqof/qof/Makefile.am b/src/libqof/qof/Makefile.am
index 7744427..bae92cc 100644
--- a/src/libqof/qof/Makefile.am
+++ b/src/libqof/qof/Makefile.am
@@ -11,6 +11,7 @@ libgnc_qof_la_LDFLAGS= \
libgnc_qof_common_libs = \
$(GLIB_LIBS) \
$(REGEX_LIBS) \
+ -lboost_date_time \
$(top_builddir)/lib/libc/libc-missing.la
libgnc_qof_la_LIBADD = $(libgnc_qof_common_libs)
diff --git a/src/libqof/qof/gnc-timezone.cpp b/src/libqof/qof/gnc-timezone.cpp
index 3797671..693c321 100644
--- a/src/libqof/qof/gnc-timezone.cpp
+++ b/src/libqof/qof/gnc-timezone.cpp
@@ -357,6 +357,7 @@ namespace IANAParser
{
unsigned int fb_index = 0;
TZHead tzh = *reinterpret_cast<TZHead*>(&fileblock[fb_index]);
+ static constexpr int ttinfo_size = 6; //struct TTInfo gets padded
last_year = 2037; //Constrained by 32-bit time_t.
auto time_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.timecnt)));
@@ -368,12 +369,12 @@ namespace IANAParser
if (tzh.version == '2' && sizeof(time_t) == sizeof(int64_t))
{
fb_index = (sizeof(tzh) +
- sizeof(time_t) + sizeof(uint8_t) * time_count +
- sizeof(TTInfo) * type_count +
+ (sizeof(uint32_t) + sizeof(uint8_t)) * time_count +
+ ttinfo_size * type_count +
sizeof(char) * char_count +
sizeof(uint8_t) * isgmt_count +
sizeof(uint8_t) * isstd_count +
- 2 * sizeof(time_t) * leap_count);
+ 2 * sizeof(uint32_t) * leap_count);
//This might change at some point in the probably very
//distant future.
@@ -387,9 +388,6 @@ namespace IANAParser
leap_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.leapcnt)));
}
fb_index += sizeof(tzh);
-
- transitions.reserve(time_count);
- tzinfo.reserve(type_count);
auto start_index = fb_index;
auto info_index_zero = start_index + time_count * sizeof(time_t);
for(uint32_t index = 0; index < time_count; ++index)
diff --git a/src/libqof/qof/test/test-gnc-date.c b/src/libqof/qof/test/test-gnc-date.c
index 170339b..3f1a7c4 100644
--- a/src/libqof/qof/test/test-gnc-date.c
+++ b/src/libqof/qof/test/test-gnc-date.c
@@ -54,7 +54,7 @@ extern "C"
static const gchar *suitename = "/qof/gnc-date";
static const time64 secs_per_year = INT64_C(3600) * (INT64_C(24) * INT64_C(365) + 6);
-static const time64 max_secs = secs_per_year * (INT64_C(9999) - INT64_C(1970));
+static const time64 max_secs = (INT64_C(3600) * (INT64_C(24) * INT64_C(365) + 6)) * (INT64_C(9999) - INT64_C(1970));
typedef struct
{
@@ -147,14 +147,17 @@ test_gnc_localtime (void)
secs[0] = -432761LL;
for (ind = 0; ind < G_N_ELEMENTS (secs); ind++)
{
+ if (sizeof(time_t) == sizeof())
struct tm* time = gnc_localtime (&secs[ind]);
+ time_t tsecs;
+ struct tm* ans;
if (secs[ind] > max_secs)
{
g_assert (time == NULL);
continue;
}
- time_t tsecs = (time_t)(secs[ind]);
- struct tm* ans = localtime(&tsecs);
+ tsecs = (time_t)(secs[ind]);
+ ans = localtime(&tsecs);
g_assert_cmpint (time->tm_year, ==, ans->tm_year);
g_assert_cmpint (time->tm_mon, ==, ans->tm_mon);
g_assert_cmpint (time->tm_mday, ==, ans->tm_mday);
@@ -312,10 +315,12 @@ test_gnc_ctime (void)
guint ind;
for (ind = 0; ind < G_N_ELEMENTS (secs); ind++)
{
+ time_t time;
+ char *datestr;
if (secs[ind] < INT32_MIN)
continue;
- time_t time = (time_t)secs[ind];
- char* datestr = gnc_ctime (&secs[ind]);
+ time = (time_t)secs[ind];
+ datestr = gnc_ctime (&secs[ind]);
g_assert_cmpstr (datestr, ==, strtok(ctime(&time), "\n"));
g_free (datestr);
}
@@ -1375,6 +1380,7 @@ test_qof_scan_date (void)
int day = 0, mo = 0, yr = 0;
gint year, month;
time64 now = gnc_time(NULL);
+ gchar buff[MAX_DATE_LENGTH];
struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0
#ifndef G_OS_WIN32
, 0, 0
@@ -1383,7 +1389,6 @@ test_qof_scan_date (void)
gnc_localtime_r(&now, &tm);
year = tm.tm_year + 1900;
month = tm.tm_mon + 1;
- gchar buff[MAX_DATE_LENGTH];
g_assert (!qof_scan_date (NULL, &day, &mo, &yr));
g_assert_cmpint (day, ==, 0);
commit 5a378e1e91a1600bfb217e1dc8f222dc8cac7b9e
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Feb 28 15:00:59 2015 -0800
Fix GCC type-deduction failure.
diff --git a/src/libqof/qof/gnc-timezone.cpp b/src/libqof/qof/gnc-timezone.cpp
index 3f3d638..3797671 100644
--- a/src/libqof/qof/gnc-timezone.cpp
+++ b/src/libqof/qof/gnc-timezone.cpp
@@ -392,7 +392,7 @@ namespace IANAParser
tzinfo.reserve(type_count);
auto start_index = fb_index;
auto info_index_zero = start_index + time_count * sizeof(time_t);
- for(auto index = 0; index < time_count; ++index)
+ for(uint32_t index = 0; index < time_count; ++index)
{
fb_index = start_index + index * sizeof(time_t);
auto info_index = info_index_zero + index;
@@ -408,7 +408,7 @@ namespace IANAParser
auto abbrev = start_index + type_count * tzinfo_size;
auto std_dist = abbrev + char_count;
auto gmt_dist = std_dist + type_count;
- for(auto index = 0; index < type_count; ++index)
+ for(uint32_t index = 0; index < type_count; ++index)
{
fb_index = start_index + index * tzinfo_size;
TTInfo info = *reinterpret_cast<TTInfo*>(&fileblock[fb_index]);
commit 197d43f4a16261f23f96f7e63b5675e83ca9c818
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Feb 28 14:30:28 2015 -0800
Rewrite test-gnc-date.c to not use GDateTime for reference.
diff --git a/src/libqof/qof/test/test-gnc-date.c b/src/libqof/qof/test/test-gnc-date.c
index 3582e18..170339b 100644
--- a/src/libqof/qof/test/test-gnc-date.c
+++ b/src/libqof/qof/test/test-gnc-date.c
@@ -27,7 +27,9 @@ extern "C"
#endif
#include <config.h>
+#include "../../../platform.h"
#include <string.h>
+#include <sys/time.h>
#include <glib.h>
#include <unittest-support.h>
/* Add specific headers for this class */
@@ -35,11 +37,11 @@ extern "C"
#ifdef __cplusplus
}
#endif
-
#include "../gnc-date.h"
#include "../gnc-date-p.h"
#include <locale.h>
#include <glib/gprintf.h>
+#include <inttypes.h>
#ifndef HAVE_STRPTIME
# include "strptime.h"
#endif
@@ -51,6 +53,84 @@ extern "C"
#endif
static const gchar *suitename = "/qof/gnc-date";
+static const time64 secs_per_year = INT64_C(3600) * (INT64_C(24) * INT64_C(365) + 6);
+static const time64 max_secs = secs_per_year * (INT64_C(9999) - INT64_C(1970));
+
+typedef struct
+{
+ short hours;
+ short minutes;
+} TZOffset;
+
+typedef struct
+{
+ TZOffset off_zulu;
+ TZOffset off_05w;
+ TZOffset off_0840e;
+ Timespec ts0;
+ Timespec ts1;
+ Timespec ts2;
+ Timespec ts3;
+ Timespec ts4;
+ Timespec ts5;
+} FixtureA;
+
+static int
+offset_secs (TZOffset tz)
+{
+ return 3600 * tz.hours + 60 * tz.minutes;
+}
+
+static char*
+offset_string (TZOffset tz)
+{
+ return g_strdup_printf("%+02d%02d", tz.hours, tz.minutes);
+}
+
+static void setup (FixtureA *f, gconstpointer pData)
+{
+ f->ts0 = (Timespec){gnc_time(NULL), 0};
+ f->off_zulu = (TZOffset){0, 0};
+ f->off_05w = (TZOffset){-5, 0};
+ f->off_0840e = (TZOffset){8, 40};
+ f->ts1 = (Timespec){607009407, 345678000}; //1989-3-27 13:43:27.345678 Z
+ f->ts2 = (Timespec){1604748079, 0}; //2020-11-7 06:21:19 -05:00
+ f->ts3 = (Timespec){1341398864, 0}; //2012-07-04 19:27:44 +08:40
+ f->ts4 = (Timespec){-261104801, 0}; //1961-09-22 17:53:19 -05:00
+ f->ts5 = (Timespec){2873938879LL, 0}; //2061-01-25 23:21:19 -05:00
+}
+
+typedef struct
+{
+ int yr;
+ int mon;
+ int day;
+ time64 secs;
+} TimeMap;
+
+typedef struct
+{
+ TimeMap test[4];
+} FixtureB;
+
+static void
+setup_begin(FixtureB *f, gconstpointer pData)
+{
+ f->test[0] = (TimeMap){1999, 7, 21, INT64_C(932515200)};
+ f->test[1] = (TimeMap){1918, 3, 31, INT64_C(-1633305600)};
+ f->test[2] = (TimeMap){1918, 4, 1, INT64_C(-1633219200)};
+ f->test[3] = (TimeMap){2057, 11, 20, INT64_C(2773440000)};
+}
+
+static void
+setup_end(FixtureB *f, gconstpointer pData)
+{
+ f->test[0] = (TimeMap){1999, 7, 21, INT64_C(932601599)};
+ f->test[1] = (TimeMap){1918, 3, 31, INT64_C(-1633219201)};
+ f->test[2] = (TimeMap){1918, 4, 1, INT64_C(-1633132801)};
+ f->test[3] = (TimeMap){2057, 11, 20, INT64_C(2773526399)};
+}
+
void test_suite_gnc_date ( void );
static GTimeZone *tz;
/* gnc_localtime just creates a tm on the heap and calls
@@ -59,41 +139,34 @@ static GTimeZone *tz;
static void
test_gnc_localtime (void)
{
- time64 secs[6] = {-15767956734LL, -1123692LL, 432761LL,
+ time64 secs[] = {-15767956734LL, -1123692LL, 432761LL,
723349832LL, 887326459367LL,
- 1364160236LL // This is "Sunday 2013-03-24" (to verify the Sunday
- // difference between g_date_time and tm->tm_wday)
- };
+ 1364160236LL};
guint ind;
+ if (sizeof(time_t) < sizeof(time64))
+ secs[0] = -432761LL;
for (ind = 0; ind < G_N_ELEMENTS (secs); ind++)
{
struct tm* time = gnc_localtime (&secs[ind]);
- GDateTime *gdt = g_date_time_new_from_unix_local (secs[ind]);
- if (gdt == NULL)
+ if (secs[ind] > max_secs)
{
g_assert (time == NULL);
continue;
}
- g_assert_cmpint (time->tm_year + 1900, ==, g_date_time_get_year (gdt));
- g_assert_cmpint (time->tm_mon + 1, ==, g_date_time_get_month (gdt));
- g_assert_cmpint (time->tm_mday, ==, g_date_time_get_day_of_month (gdt));
- g_assert_cmpint (time->tm_hour, ==, g_date_time_get_hour (gdt));
- g_assert_cmpint (time->tm_min, ==, g_date_time_get_minute (gdt));
- g_assert_cmpint (time->tm_sec, ==, g_date_time_get_second (gdt));
- // Watch out: struct tm has wday=0..6 with Sunday=0, but GDateTime has wday=1..7 with Sunday=7.
- g_assert_cmpint (time->tm_wday, ==, (g_date_time_get_day_of_week (gdt) % 7));
- //tm_yday is 0-based, g_date_time_get_day_of_year is 1-based.
- g_assert_cmpint (time->tm_yday, ==,
- g_date_time_get_day_of_year (gdt) - 1);
- if (g_date_time_is_daylight_savings (gdt))
- g_assert_cmpint (time->tm_isdst, ==, 1);
- else
- g_assert_cmpint (time->tm_isdst, ==, 0);
+ time_t tsecs = (time_t)(secs[ind]);
+ struct tm* ans = localtime(&tsecs);
+ g_assert_cmpint (time->tm_year, ==, ans->tm_year);
+ g_assert_cmpint (time->tm_mon, ==, ans->tm_mon);
+ g_assert_cmpint (time->tm_mday, ==, ans->tm_mday);
+ g_assert_cmpint (time->tm_hour, ==, ans->tm_hour);
+ g_assert_cmpint (time->tm_min, ==, ans->tm_min);
+ g_assert_cmpint (time->tm_sec, ==, ans->tm_sec);
+ g_assert_cmpint (time->tm_wday, ==, ans->tm_wday);
+ g_assert_cmpint (time->tm_yday, ==, ans->tm_yday);
+ g_assert_cmpint (time->tm_isdst, ==, ans->tm_isdst);
#ifdef HAVE_STRUCT_TM_GMTOFF
- g_assert_cmpint (time->tm_gmtoff, ==,
- g_date_time_get_utc_offset (gdt) / G_TIME_SPAN_SECOND);
+ g_assert_cmpint (time->tm_gmtoff, ==, ans->tm_gmtoff);
#endif
- g_date_time_unref (gdt);
gnc_tm_free (time);
}
}
@@ -126,8 +199,7 @@ test_gnc_gmtime (void)
for (ind = 0; ind < G_N_ELEMENTS (secs); ind++)
{
struct tm* time = gnc_gmtime (&secs[ind]);
- GDateTime *gdt = g_date_time_new_from_unix_utc (secs[ind]);
- if (gdt == NULL)
+ if ((secs[ind] > max_secs))
{
g_assert (time == NULL);
continue;
@@ -144,7 +216,6 @@ test_gnc_gmtime (void)
#ifdef HAVE_STRUCT_TM_GMTOFF
g_assert_cmpint (time->tm_gmtoff, ==, 0);
#endif
- g_date_time_unref (gdt);
gnc_tm_free (time);
}
}
@@ -172,20 +243,13 @@ test_gnc_mktime (void)
#endif
};
guint ind;
+ int offset = timegm(&time[4]) - mktime(&time[4]);
for (ind = 0; ind < G_N_ELEMENTS (time); ind++)
{
time64 secs = gnc_mktime (&time[ind]);
- GDateTime *gdt = g_date_time_new_local (time[ind].tm_year + 1900,
- time[ind].tm_mon + 1,
- time[ind].tm_mday,
- time[ind].tm_hour,
- time[ind].tm_min,
- (gdouble)time[ind].tm_sec);
- time64 offset = g_date_time_get_utc_offset (gdt) / G_TIME_SPAN_SECOND;
g_assert_cmpint (secs, ==, ans[ind] - offset);
- g_date_time_unref (gdt);
}
}
@@ -224,16 +288,11 @@ test_gnc_mktime_normalization (void)
#endif
};
guint ind;
+ int offset = timegm(&normal_time) - mktime(&normal_time);
for (ind = 0; ind < G_N_ELEMENTS (time); ind++)
{
time64 secs = gnc_mktime (&time[ind]);
- GDateTime *gdt = g_date_time_new_local (time[ind].tm_year + 1900,
- time[ind].tm_mon + 1,
- time[ind].tm_mday,
- time[ind].tm_hour,
- time[ind].tm_min,
- (gdouble)time[ind].tm_sec);
- time64 offset = g_date_time_get_utc_offset (gdt) / G_TIME_SPAN_SECOND;
+
g_assert_cmpfloat (time[ind].tm_sec, ==, normal_time.tm_sec);
g_assert_cmpint (time[ind].tm_min, ==, normal_time.tm_min);
g_assert_cmpint (time[ind].tm_hour, ==, normal_time.tm_hour);
@@ -241,8 +300,6 @@ test_gnc_mktime_normalization (void)
g_assert_cmpint (time[ind].tm_mon, ==, normal_time.tm_mon);
g_assert_cmpint (time[ind].tm_year, ==, normal_time.tm_year);
g_assert_cmpint (secs, ==, ans - offset);
-
- g_date_time_unref (gdt);
}
}
@@ -255,11 +312,11 @@ test_gnc_ctime (void)
guint ind;
for (ind = 0; ind < G_N_ELEMENTS (secs); ind++)
{
- GDateTime *gdt = g_date_time_new_from_unix_local (secs[ind]);
- gchar* datestr = gnc_ctime (&secs[ind]);
- g_assert_cmpstr (datestr, ==,
- g_date_time_format (gdt, "%a %b %e %H:%M:%S %Y"));
- g_date_time_unref (gdt);
+ if (secs[ind] < INT32_MIN)
+ continue;
+ time_t time = (time_t)secs[ind];
+ char* datestr = gnc_ctime (&secs[ind]);
+ g_assert_cmpstr (datestr, ==, strtok(ctime(&time), "\n"));
g_free (datestr);
}
}
@@ -268,12 +325,9 @@ static void
test_gnc_time (void)
{
time64 secs1, secs2;
- GDateTime *gdt;
secs1 = gnc_time (&secs2);
- gdt = g_date_time_new_now_local ();
g_assert_cmpint (secs1, ==, secs2);
- g_assert_cmpint (secs1, ==, g_date_time_to_unix (gdt));
- g_date_time_unref (gdt);
+ g_assert_cmpint (secs1, ==, time(0));
}
/* gnc_difftime and gnc_tm_free are just too simple to bother testing. */
@@ -597,16 +651,13 @@ timespecCanonicalDayTime(Timespec t)// C: 12 in 5 SCM: 19 in 10 Local: 0:0:0
static Timespec
compute_noon_of_day (Timespec *ts)
{
- GDateTime *g = g_date_time_new_from_unix_local (ts->tv_sec);
- gint yr = g_date_time_get_year (g);
- gint mo = g_date_time_get_month (g);
- gint da = g_date_time_get_day_of_month (g);
- Timespec nt = {0, 0 };
-
- g_date_time_unref (g);
- g = g_date_time_new_local (yr, mo, da, 12, 0, 0.0);
- nt.tv_sec = g_date_time_to_unix (g);
- g_date_time_unref (g);
+ Timespec nt = {0, 0};
+ time_t secs = (time_t)ts->tv_sec;
+ struct tm *time = localtime(&secs);
+ time->tm_hour = 12;
+ time->tm_min = 0;
+ time->tm_sec = 0;
+ nt.tv_sec = mktime(time);
return nt;
}
@@ -638,9 +689,8 @@ test_timespecCanonicalDayTime (void)
g_assert_cmpint (n0.tv_sec, ==, r0.tv_sec);
g_assert_cmpint (na.tv_sec, ==, ra.tv_sec);
g_assert_cmpint (nb.tv_sec, ==, rb.tv_sec);
-//GDateTime gets DST wrong here: The DST changes on the second Sunday
-//of March, which this is; Our time-zone sets DST, but GDateTime's doesn't.
- g_assert_cmpint (nc.tv_sec, ==, rc.tv_sec + 3600);
+ if (sizeof(time_t) >= sizeof(time64))
+ g_assert_cmpint (nc.tv_sec, ==, rc.tv_sec);
}
/* gnc_date_get_last_mday
@@ -913,13 +963,10 @@ test_qof_print_date_buff (void)
{
gchar buff[MAX_DATE_LENGTH];
gchar *locale = g_strdup (setlocale (LC_TIME, NULL));
- GDateTime *gd1 = g_date_time_new_local (1974, 11, 23, 12, 0, 0.0);
- GDateTime *gd2 = g_date_time_new_local (1961, 2, 2, 12, 0, 0.0);
- GDateTime *gd3 = g_date_time_new_local (2045, 6, 16, 12, 0, 0.0);
- time64 tm1 = g_date_time_to_unix (gd1);
- time64 tm2 = g_date_time_to_unix (gd2);
- time64 tm3 = g_date_time_to_unix (gd3);
+ time64 tm1 = 154440000; //1974-11-23 12:00:00
+ time64 tm2 = -281188800; //1961-02-02 12:00:00
+ time64 tm3 = 2381227200LL; //2045-06-16 12:00:00
qof_date_format_set (QOF_DATE_FORMAT_UK);
memset ((gpointer)buff, 0, sizeof (buff));
@@ -986,50 +1033,47 @@ test_qof_print_date_buff (void)
memset ((gpointer)buff, 0, sizeof (buff));
g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm1),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, g_date_time_format (gd1, GNC_D_FMT));
+ g_assert_cmpstr (buff, ==, "11/23/1974");
memset ((gpointer)buff, 0, sizeof (buff));
g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm2),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, g_date_time_format (gd2, GNC_D_FMT));
+ g_assert_cmpstr (buff, ==, "02/02/1961");
memset ((gpointer)buff, 0, sizeof (buff));
g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm3),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, g_date_time_format (gd3, GNC_D_FMT));
+ g_assert_cmpstr (buff, ==, "06/16/2045");
test_gnc_setlocale (LC_TIME, "en_GB");
memset ((gpointer)buff, 0, sizeof (buff));
g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm1),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, g_date_time_format (gd1, GNC_D_FMT));
+ g_assert_cmpstr (buff, ==, "23/11/1974");
memset ((gpointer)buff, 0, sizeof (buff));
g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm2),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, g_date_time_format (gd2, GNC_D_FMT));
+ g_assert_cmpstr (buff, ==, "02/02/1961");
memset ((gpointer)buff, 0, sizeof (buff));
g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm3),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, g_date_time_format (gd3, GNC_D_FMT));
+ g_assert_cmpstr (buff, ==, "16/06/2045");
test_gnc_setlocale (LC_TIME, "fr_FR");
memset ((gpointer)buff, 0, sizeof (buff));
g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm1),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, g_date_time_format (gd1, GNC_D_FMT));
+ g_assert_cmpstr (buff, ==, "23.11.1974");
memset ((gpointer)buff, 0, sizeof (buff));
g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm2),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, g_date_time_format (gd2, GNC_D_FMT));
+ g_assert_cmpstr (buff, ==, "02.02.1961");
memset ((gpointer)buff, 0, sizeof (buff));
g_assert_cmpint (qof_print_date_buff (buff, sizeof (buff), tm3),
==, strlen (buff));
- g_assert_cmpstr (buff, ==, g_date_time_format (gd3, GNC_D_FMT));
+ g_assert_cmpstr (buff, ==, "16.06.2045");
setlocale (LC_TIME, locale);
g_free (locale);
- g_date_time_unref (gd1);
- g_date_time_unref (gd2);
- g_date_time_unref (gd3);
}
/* qof_print_gdate
size_t
@@ -1192,13 +1236,10 @@ static void
test_qof_print_date (void)
{
gchar *locale = g_strdup (setlocale (LC_TIME, NULL));
- GDateTime *gd1 = g_date_time_new_local (1974, 11, 23, 12, 0, 0.0);
- GDateTime *gd2 = g_date_time_new_local (1961, 2, 2, 12, 0, 0.0);
- GDateTime *gd3 = g_date_time_new_local (2045, 6, 16, 12, 0, 0.0);
- time64 tm1 = g_date_time_to_unix (gd1);
- time64 tm2 = g_date_time_to_unix (gd2);
- time64 tm3 = g_date_time_to_unix (gd3);
+ time64 tm1 = 154440000; //1974-11-23 12:00:00
+ time64 tm2 = -281188800; //1961-02-02 12:00:00
+ time64 tm3 = 2381227200LL; //2045-06-16 12:00:00
qof_date_format_set (QOF_DATE_FORMAT_UK);
test_assert_qof_print_date (tm1, "23/11/1974");
@@ -1222,34 +1263,22 @@ test_qof_print_date (void)
qof_date_format_set (QOF_DATE_FORMAT_LOCALE);
test_gnc_setlocale (LC_TIME, "en_US");
- test_assert_qof_print_date (tm1,
- g_date_time_format (gd1, GNC_D_FMT));
- test_assert_qof_print_date_outside_range (tm2,
- g_date_time_format (gd2, GNC_D_FMT));
- test_assert_qof_print_date_outside_range (tm3,
- g_date_time_format (gd3, GNC_D_FMT));
+ test_assert_qof_print_date (tm1,"11/23/1974");
+ test_assert_qof_print_date_outside_range (tm2, "02/02/1961");
+ test_assert_qof_print_date_outside_range (tm3, "06/16/2045");
test_gnc_setlocale (LC_TIME, "en_GB");
- test_assert_qof_print_date (tm1,
- g_date_time_format (gd1, GNC_D_FMT));
- test_assert_qof_print_date_outside_range (tm2,
- g_date_time_format (gd2, GNC_D_FMT));
- test_assert_qof_print_date_outside_range (tm3,
- g_date_time_format (gd3, GNC_D_FMT));
+ test_assert_qof_print_date (tm1, "23/11/1974");
+ test_assert_qof_print_date_outside_range (tm2, "02/02/1961");
+ test_assert_qof_print_date_outside_range (tm3, "16/06/2045");
test_gnc_setlocale (LC_TIME, "fr_FR");
- test_assert_qof_print_date (tm1,
- g_date_time_format (gd1, GNC_D_FMT));
- test_assert_qof_print_date_outside_range (tm2,
- g_date_time_format (gd2, GNC_D_FMT));
- test_assert_qof_print_date_outside_range (tm3,
- g_date_time_format (gd3, GNC_D_FMT));
+ test_assert_qof_print_date (tm1, "23.11.1974");
+ test_assert_qof_print_date_outside_range (tm2, "02.02.1961");
+ test_assert_qof_print_date_outside_range (tm3, "16.06.2045");
setlocale (LC_TIME, locale);
g_free (locale);
- g_date_time_unref (gd1);
- g_date_time_unref (gd2);
- g_date_time_unref (gd3);
}
/* gnc_print_date
const char *
@@ -1344,16 +1373,17 @@ test_qof_scan_date (void)
{
gchar *locale = g_strdup (setlocale (LC_TIME, NULL));
int day = 0, mo = 0, yr = 0;
- GDateTime *gdt = g_date_time_new_now_local ();
- gint year = g_date_time_get_year (gdt);
- gint month = g_date_time_get_month (gdt);
+ gint year, month;
+ time64 now = gnc_time(NULL);
struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0
#ifndef G_OS_WIN32
, 0, 0
#endif
};
+ gnc_localtime_r(&now, &tm);
+ year = tm.tm_year + 1900;
+ month = tm.tm_mon + 1;
gchar buff[MAX_DATE_LENGTH];
- g_date_time_unref (gdt);
g_assert (!qof_scan_date (NULL, &day, &mo, &yr));
g_assert_cmpint (day, ==, 0);
@@ -1519,19 +1549,18 @@ gnc_date_timestamp (void)// C: 2 in 2 Local: 0:0:0
static void
test_gnc_date_timestamp (void)
{
- GDateTime *gdt = g_date_time_new_now_local ();
+ time64 now = gnc_time(NULL);
gchar *timestr = gnc_date_timestamp ();
- struct tm tm;
-
- g_assert (strptime (timestr, "%Y%m%d%H%M%S", &tm));
- g_assert_cmpint (g_date_time_get_year (gdt), ==, tm.tm_year + 1900);
- g_assert_cmpint (g_date_time_get_month (gdt), ==, tm.tm_mon + 1);
- g_assert_cmpint (g_date_time_get_day_of_month (gdt), ==, tm.tm_mday);
- g_assert_cmpint (g_date_time_get_hour (gdt), ==, tm.tm_hour);
- g_assert_cmpint (g_date_time_get_minute (gdt), ==, tm.tm_min);
- g_assert_cmpint (g_date_time_get_second (gdt), ==, tm.tm_sec);
+ struct tm tm0, tm1;
+ gnc_localtime_r(&now, &tm0);
+ g_assert (strptime (timestr, "%Y%m%d%H%M%S", &tm1));
+ g_assert_cmpint (tm0.tm_year, ==, tm1.tm_year);
+ g_assert_cmpint (tm0.tm_mon, ==, tm1.tm_mon);
+ g_assert_cmpint (tm0.tm_mday, ==, tm1.tm_mday);
+ g_assert_cmpint (tm0.tm_hour, ==, tm1.tm_hour);
+ g_assert_cmpint (tm0.tm_min, ==, tm1.tm_min);
+ g_assert_cmpint (tm0.tm_sec, ==, tm1.tm_sec);
- g_date_time_unref (gdt);
g_free (timestr);
}
/* gnc_iso8601_to_timespec_gmt
@@ -1545,17 +1574,8 @@ get_nanoseconds (GDateTime *gdt)
}
static void
-test_gnc_iso8601_to_timespec_gmt (void)
+test_gnc_iso8601_to_timespec_gmt (FixtureA *f, gconstpointer pData)
{
- GTimeZone *zulu = g_time_zone_new ("Z");
- GTimeZone *tz05 = g_time_zone_new ("-05");
- GTimeZone *tz0840 = g_time_zone_new ("+08:40");
- GDateTime *gdt1 = g_date_time_new (zulu, 1989, 3, 27, 13, 43, 27.345678);
- GDateTime *gdt2 = g_date_time_new (tz05, 2020, 11, 7, 6, 21, 19.0);
- GDateTime *gdt3 = g_date_time_new (tz0840, 2012, 7, 4, 19, 27, 44.0);
- GDateTime *gdt4 = g_date_time_new (tz05, 1961, 9, 22, 17, 53, 19.0);
- GDateTime *gdt5 = g_date_time_new (tz05, 2061, 1, 25, 23, 21, 19.0);
-
Timespec t;
t = gnc_iso8601_to_timespec_gmt (NULL);
@@ -1567,44 +1587,34 @@ test_gnc_iso8601_to_timespec_gmt (void)
g_assert_cmpint (t.tv_nsec, ==, 0);
t = gnc_iso8601_to_timespec_gmt ("1989-03-27 13:43:27.345678");
- g_assert_cmpint (t.tv_sec, ==, g_date_time_to_unix (gdt1));
+ g_assert_cmpint (t.tv_sec, ==, f->ts1.tv_sec);
/* MinGW has some precision issues in the last microsecond digit */
#ifdef G_OS_WIN32
- g_assert_cmpint (t.tv_nsec - 2000, <=, get_nanoseconds (gdt1));
- g_assert_cmpint (t.tv_nsec + 2000, >=, get_nanoseconds (gdt1));
+ g_assert_cmpint (t.tv_nsec - 2000, <=, f->ts1.tv_nsec);
+ g_assert_cmpint (t.tv_nsec + 2000, >=, f->ts1.tv_nsec);
#else
- g_assert_cmpint (t.tv_nsec, ==, get_nanoseconds (gdt1));
+ g_assert_cmpint (t.tv_nsec, ==, f->ts1.tv_nsec);
#endif
t = gnc_iso8601_to_timespec_gmt ("2020-11-7 06:21:19 -05");
- g_assert_cmpint (t.tv_sec, ==, g_date_time_to_unix (gdt2));
- g_assert_cmpint (t.tv_nsec, ==, get_nanoseconds (gdt2));
+ g_assert_cmpint (t.tv_sec, ==, f->ts2.tv_sec);
+ g_assert_cmpint (t.tv_nsec, ==, f->ts2.tv_nsec);
t = gnc_iso8601_to_timespec_gmt ("2012-07-04 19:27:44.0+08:40");
- g_assert_cmpint (t.tv_sec, ==, g_date_time_to_unix (gdt3));
- g_assert_cmpint (t.tv_nsec, ==, get_nanoseconds (gdt3));
+ g_assert_cmpint (t.tv_sec, ==, f->ts3.tv_sec);
+ g_assert_cmpint (t.tv_nsec, ==, f->ts3.tv_nsec);
t = gnc_iso8601_to_timespec_gmt ("1961-09-22 17:53:19 -05");
- g_assert_cmpint (t.tv_sec, ==, g_date_time_to_unix (gdt4));
- g_assert_cmpint (t.tv_nsec, ==, get_nanoseconds (gdt4));
+ g_assert_cmpint (t.tv_sec, ==, f->ts4.tv_sec);
+ g_assert_cmpint (t.tv_nsec, ==, f->ts4.tv_nsec);
t = gnc_iso8601_to_timespec_gmt ("2061-01-25 23:21:19.0 -05:00");
- g_assert_cmpint (t.tv_sec, ==, g_date_time_to_unix (gdt5));
- g_assert_cmpint (t.tv_nsec, ==, get_nanoseconds (gdt5));
-
- g_date_time_unref (gdt1);
- g_date_time_unref (gdt2);
- g_date_time_unref (gdt3);
- g_date_time_unref (gdt4);
- g_date_time_unref (gdt5);
- g_time_zone_unref (zulu);
- g_time_zone_unref (tz05);
- g_time_zone_unref (tz0840);
+ g_assert_cmpint (t.tv_sec, ==, f->ts5.tv_sec);
+ g_assert_cmpint (t.tv_nsec, ==, f->ts5.tv_nsec);
}
/* gnc_timespec_to_iso8601_buff
char *
gnc_timespec_to_iso8601_buff (Timespec ts, char * buff)// C: 18 in 7 Local: 0:0:0
*/
-#define ISO8601_SIZE MAX_DATE_LENGTH + 4
static Timespec
g_date_time_to_timespec (GDateTime *gdt)
{
@@ -1614,42 +1624,32 @@ g_date_time_to_timespec (GDateTime *gdt)
return t;
}
+#define ISO8601_SIZE MAX_DATE_LENGTH + 4
static gchar*
-format_timestring (GDateTime *gdt)
+format_timestring (Timespec ts, TZOffset tz)
{
static const unsigned tzlen = MAX_DATE_LENGTH - 26;
- gchar *fmt = "%Y-%m-%d %H:%M";
- GDateTime *ngdt = g_date_time_to_local (gdt);
- gchar *date_base = g_date_time_format (ngdt, fmt);
- gchar buf[tzlen], *retval;
-#ifdef G_OS_WIN32
- gchar *tz = g_date_time_format (ngdt, "%Z");
+ char *fmt = "%Y-%m-%d %H:%M:%S";
+ struct tm tm;
+ char buf[MAX_DATE_LENGTH], *retval;
+ char tzbuf[tzlen];
+ memset(tzbuf, 0, sizeof(tzbuf));
+ gnc_localtime_r(&ts.tv_sec, &tm);
+#if PLATFORM(WINDOWS)
+ strftime(tzbuf, sizeof(tzbuf), "%Z", &tm);
#else
- gchar *tz = g_date_time_format (ngdt, "%z");
+ strftime(tzbuf, sizeof(tzbuf), "%z", &tm);
#endif
- memset (buf, 0, tzlen);
- g_snprintf (buf, tzlen, "%s", tz);
- retval = g_strdup_printf ("%s:%02d.%06d %s", date_base,
- g_date_time_get_second (ngdt),
- g_date_time_get_microsecond (ngdt), buf);
- g_date_time_unref (ngdt);
- g_free (date_base);
- g_free (tz);
+ memset (buf, 0, sizeof(buf));
+ strftime(buf, sizeof(buf), fmt, &tm);
+ retval = g_strdup_printf ("%s.%06ld %s", buf, ts.tv_nsec / 1000, tzbuf);
+
return retval;
}
static void
-test_gnc_timespec_to_iso8601_buff (void)
-{
- GTimeZone *zulu = g_time_zone_new ("Z");
- GTimeZone *tz05 = g_time_zone_new ("-05");
- GTimeZone *tz0840 = g_time_zone_new ("+08:40");
- GDateTime *gdt0 = g_date_time_new_from_unix_utc (0);
- GDateTime *gdt1 = g_date_time_new (zulu, 1989, 3, 27, 13, 43, 27.0);
- GDateTime *gdt2 = g_date_time_new (tz05, 2020, 11, 7, 6, 21, 19.0);
- GDateTime *gdt3 = g_date_time_new (tz0840, 2012, 7, 4, 19, 27, 44.0);
- GDateTime *gdt4 = g_date_time_new (tz05, 1961, 9, 22, 17, 53, 19.0);
- GDateTime *gdt5 = g_date_time_new (tz05, 2061, 1, 25, 23, 21, 19.0);
+test_gnc_timespec_to_iso8601_buff (FixtureA *f, gconstpointer pData)
+{
gchar buff[ISO8601_SIZE];
gchar *time_str;
@@ -1661,138 +1661,85 @@ test_gnc_timespec_to_iso8601_buff (void)
end = gnc_timespec_to_iso8601_buff (t, NULL);
g_assert (end == NULL);
- end = gnc_timespec_to_iso8601_buff (t, buff);
+ end = gnc_timespec_to_iso8601_buff (f->ts0, buff);
g_assert_cmpint (end - buff, ==, strlen (buff));
- time_str = format_timestring (gdt0);
+ time_str = format_timestring (f->ts0, f->off_zulu);
g_assert_cmpstr (buff, ==, time_str);
g_free (time_str);
- t = g_date_time_to_timespec (gdt1);
- end = gnc_timespec_to_iso8601_buff (t, buff);
- time_str = format_timestring (gdt1);
+ end = gnc_timespec_to_iso8601_buff (f->ts1, buff);
+ time_str = format_timestring (f->ts1, f->off_zulu);
g_assert_cmpstr (buff, ==, time_str);
g_free (time_str);
- t = g_date_time_to_timespec (gdt2);
- end = gnc_timespec_to_iso8601_buff (t, buff);
- time_str = format_timestring (gdt2);
+ end = gnc_timespec_to_iso8601_buff (f->ts2, buff);
+ time_str = format_timestring (f->ts2, f->off_05w);
g_assert_cmpstr (buff, ==, time_str);
g_free (time_str);
- t = g_date_time_to_timespec (gdt3);
- end = gnc_timespec_to_iso8601_buff (t, buff);
- time_str = format_timestring (gdt3);
+ end = gnc_timespec_to_iso8601_buff (f->ts3, buff);
+ time_str = format_timestring (f->ts3, f->off_0840e);
g_assert_cmpstr (buff, ==, time_str);
g_free (time_str);
- t = g_date_time_to_timespec (gdt4);
- end = gnc_timespec_to_iso8601_buff (t, buff);
- time_str = format_timestring (gdt4);
+ end = gnc_timespec_to_iso8601_buff (f->ts4, buff);
+ time_str = format_timestring (f->ts4, f->off_05w);
g_assert_cmpstr (buff, ==, time_str);
g_free (time_str);
- t = g_date_time_to_timespec (gdt5);
- end = gnc_timespec_to_iso8601_buff (t, buff);
- time_str = format_timestring (gdt5);
+ end = gnc_timespec_to_iso8601_buff (f->ts5, buff);
+ time_str = format_timestring (f->ts5, f->off_05w);
g_assert_cmpstr (buff, ==, time_str);
g_free (time_str);
-
- g_date_time_unref (gdt0);
- g_date_time_unref (gdt1);
- g_date_time_unref (gdt2);
- g_date_time_unref (gdt3);
- g_date_time_unref (gdt4);
- g_date_time_unref (gdt5);
- g_time_zone_unref (zulu);
- g_time_zone_unref (tz05);
- g_time_zone_unref (tz0840);
}
/* gnc_timespec2dmy
void
gnc_timespec2dmy (Timespec t, int *day, int *month, int *year)// C: 1 Local: 0:0:0
*/
static void
-test_gnc_timespec2dmy (void)
-{
- GTimeZone *zulu = g_time_zone_new ("Z");
- GTimeZone *tz05 = g_time_zone_new ("-05");
- GTimeZone *tz0840 = g_time_zone_new ("+08:40");
- GDateTime *gdt0 = g_date_time_new_from_unix_utc (0);
- GDateTime *gdt1 = g_date_time_new (zulu, 1989, 3, 27, 13, 43, 27.345678);
- GDateTime *gdt2 = g_date_time_new (tz05, 2020, 11, 7, 6, 21, 19.0);
- GDateTime *gdt3 = g_date_time_new (tz0840, 2012, 7, 4, 19, 27, 44.0);
- GDateTime *gdt4 = g_date_time_new (tz05, 1961, 9, 22, 17, 53, 19.0);
- GDateTime *gdt5 = g_date_time_new (tz05, 2061, 1, 25, 23, 21, 19.0);
- GDateTime *gdt_local;
-
+test_gnc_timespec2dmy (FixtureA *f, gconstpointer pData)
+{
+ struct tm tm;
int day, r_day, mo, r_mo, yr, r_yr;
- Timespec t;
- t = g_date_time_to_timespec (gdt0);
- gnc_timespec2dmy (t, &r_day, &r_mo, &r_yr);
- gdt_local = g_date_time_to_local (gdt0);
- g_date_time_get_ymd (gdt_local, &yr, &mo, &day);
- g_date_time_unref (gdt_local);
- g_assert_cmpint (r_day, ==, day);
- g_assert_cmpint (r_mo, ==, mo);
- g_assert_cmpint (r_yr, ==, yr);
-
- t = g_date_time_to_timespec (gdt1);
- gnc_timespec2dmy (t, &r_day, &r_mo, &r_yr);
- gdt_local = g_date_time_to_local (gdt1);
- g_date_time_get_ymd (gdt_local, &yr, &mo, &day);
- g_date_time_unref (gdt_local);
- g_assert_cmpint (r_day, ==, day);
- g_assert_cmpint (r_mo, ==, mo);
- g_assert_cmpint (r_yr, ==, yr);
-
- t = g_date_time_to_timespec (gdt2);
- gnc_timespec2dmy (t, &r_day, &r_mo, &r_yr);
- gdt_local = g_date_time_to_local (gdt2);
- g_date_time_get_ymd (gdt_local, &yr, &mo, &day);
- g_date_time_unref (gdt_local);
- g_assert_cmpint (r_day, ==, day);
- g_assert_cmpint (r_mo, ==, mo);
- g_assert_cmpint (r_yr, ==, yr);
-
- t = g_date_time_to_timespec (gdt3);
- gnc_timespec2dmy (t, &r_day, &r_mo, &r_yr);
- gdt_local = g_date_time_to_local (gdt3);
- g_date_time_get_ymd (gdt_local, &yr, &mo, &day);
- g_date_time_unref (gdt_local);
- g_assert_cmpint (r_day, ==, day);
- g_assert_cmpint (r_mo, ==, mo);
- g_assert_cmpint (r_yr, ==, yr);
-
- t = g_date_time_to_timespec (gdt4);
- gnc_timespec2dmy (t, &r_day, &r_mo, &r_yr);
- gdt_local = g_date_time_to_local (gdt4);
- g_date_time_get_ymd (gdt_local, &yr, &mo, &day);
- g_date_time_unref (gdt_local);
- g_assert_cmpint (r_day, ==, day);
- g_assert_cmpint (r_mo, ==, mo);
- g_assert_cmpint (r_yr, ==, yr);
-
- t = g_date_time_to_timespec (gdt5);
- gnc_timespec2dmy (t, &r_day, &r_mo, &r_yr);
- gdt_local = g_date_time_to_local (gdt5);
- g_date_time_get_ymd (gdt_local, &yr, &mo, &day);
- g_date_time_unref (gdt_local);
- /* 2038 Bug */
- g_assert_cmpint (r_day, ==, day);
- g_assert_cmpint (r_mo, ==, mo);
- g_assert_cmpint (r_yr, ==, yr);
-
- g_date_time_unref (gdt0);
- g_date_time_unref (gdt1);
- g_date_time_unref (gdt2);
- g_date_time_unref (gdt3);
- g_date_time_unref (gdt4);
- g_date_time_unref (gdt5);
- g_time_zone_unref (zulu);
- g_time_zone_unref (tz05);
- g_time_zone_unref (tz0840);
+
+ gnc_timespec2dmy (f->ts0, &r_day, &r_mo, &r_yr);
+ gnc_localtime_r (&f->ts0.tv_sec, &tm);
+ g_assert_cmpint (r_day, ==, tm.tm_mday);
+ g_assert_cmpint (r_mo, ==, tm.tm_mon + 1);
+ g_assert_cmpint (r_yr, ==, tm.tm_year + 1900);
+
+ gnc_timespec2dmy (f->ts1, &r_day, &r_mo, &r_yr);
+ gnc_localtime_r (&f->ts1.tv_sec, &tm);
+ g_assert_cmpint (r_day, ==, tm.tm_mday);
+ g_assert_cmpint (r_mo, ==, tm.tm_mon + 1);
+ g_assert_cmpint (r_yr, ==, tm.tm_year + 1900);
+
+ gnc_timespec2dmy (f->ts2, &r_day, &r_mo, &r_yr);
+ gnc_localtime_r (&f->ts2.tv_sec, &tm);
+ g_assert_cmpint (r_day, ==, tm.tm_mday);
+ g_assert_cmpint (r_mo, ==, tm.tm_mon + 1);
+ g_assert_cmpint (r_yr, ==, tm.tm_year + 1900);
+
+ gnc_timespec2dmy (f->ts3, &r_day, &r_mo, &r_yr);
+ gnc_localtime_r (&f->ts3.tv_sec, &tm);
+ g_assert_cmpint (r_day, ==, tm.tm_mday);
+ g_assert_cmpint (r_mo, ==, tm.tm_mon + 1);
+ g_assert_cmpint (r_yr, ==, tm.tm_year + 1900);
+
+ gnc_timespec2dmy (f->ts4, &r_day, &r_mo, &r_yr);
+ gnc_localtime_r (&f->ts4.tv_sec, &tm);
+ g_assert_cmpint (r_day, ==, tm.tm_mday);
+ g_assert_cmpint (r_mo, ==, tm.tm_mon + 1);
+ g_assert_cmpint (r_yr, ==, tm.tm_year + 1900);
+
+ gnc_timespec2dmy (f->ts5, &r_day, &r_mo, &r_yr);
+ gnc_localtime_r (&f->ts5.tv_sec, &tm);
+ g_assert_cmpint (r_day, ==, tm.tm_mday);
+ g_assert_cmpint (r_mo, ==, tm.tm_mon + 1);
+ g_assert_cmpint (r_yr, ==, tm.tm_year + 1900);
+
}
/* gnc_dmy2timespec_internal
static Timespec
@@ -1807,89 +1754,47 @@ Timespec
gnc_dmy2timespec (int day, int month, int year)// C: 8 in 5 Local: 1:0:0
*/
static void
-test_gnc_dmy2timespec (void)
-{
- GDateTime *gdt1 = g_date_time_new_local (1999, 7, 21, 0, 0, 0);
- GDateTime *gdt2 = g_date_time_new_local (1918, 3, 31, 0, 0, 0);
- GDateTime *gdt3 = g_date_time_new_local (1918, 4, 1, 0, 0, 0);
- GDateTime *gdt4 = g_date_time_new_local (2057, 11, 20, 0, 0, 0);
-
- gint day, mon, yr;
- Timespec t, r_t;
-
- t = g_date_time_to_timespec (gdt1);
- g_date_time_get_ymd (gdt1, &yr, &mon, &day);
- r_t = gnc_dmy2timespec (day, mon, yr);
- g_assert_cmpint (r_t.tv_sec, ==, t.tv_sec);
- g_assert_cmpint (r_t.tv_nsec, ==, t.tv_nsec);
-
- t = g_date_time_to_timespec (gdt2);
- g_date_time_get_ymd (gdt2, &yr, &mon, &day);
- r_t = gnc_dmy2timespec (day, mon, yr);
- g_assert_cmpint (r_t.tv_sec, ==, t.tv_sec);
- g_assert_cmpint (r_t.tv_nsec, ==, t.tv_nsec);
-
- t = g_date_time_to_timespec (gdt3);
- g_date_time_get_ymd (gdt3, &yr, &mon, &day);
- r_t = gnc_dmy2timespec (day, mon, yr);
- g_assert_cmpint (r_t.tv_sec, ==, t.tv_sec);
- g_assert_cmpint (r_t.tv_nsec, ==, t.tv_nsec);
-
- t = g_date_time_to_timespec (gdt4);
- g_date_time_get_ymd (gdt4, &yr, &mon, &day);
- r_t = gnc_dmy2timespec (day, mon, yr);
- g_assert_cmpint (r_t.tv_sec, ==, t.tv_sec);
- g_assert_cmpint (r_t.tv_nsec, ==, t.tv_nsec);
-
- g_date_time_unref (gdt1);
- g_date_time_unref (gdt2);
- g_date_time_unref (gdt3);
- g_date_time_unref (gdt4);
+test_gnc_dmy2timespec (FixtureB *f, gconstpointer pData)
+{
+
+ for (int i = 0; i < sizeof(f->test)/sizeof(TimeMap); ++i)
+ {
+#ifdef HAVE_STRUCT_TM_GMTOFF
+ struct tm tm = {0, 0, 0, f->test[i].day, f->test[i].mon - 1,
+ f->test[i].yr - 1900, 0, 0, -1, 0, NULL};
+#else
+ struct tm tm = {0, 0, 0, f->test[i].day, f->test[i].mon - 1,
+ f->test[i].yr - 1900, 0, 0, -1};
+#endif
+ Timespec r_t = gnc_dmy2timespec (f->test[i].day, f->test[i].mon,
+ f->test[i].yr);
+ int offset = gnc_mktime(&tm) - gnc_timegm(&tm);
+ g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs + offset);
+ }
}
/* gnc_dmy2timespec_end
Timespec
gnc_dmy2timespec_end (int day, int month, int year)// C: 1 Local: 0:0:0
*/
static void
-test_gnc_dmy2timespec_end (void)
-{
- GDateTime *gdt1 = g_date_time_new_local (1999, 7, 21,23,59, 59);
- GDateTime *gdt2 = g_date_time_new_local (1918, 3, 30, 23, 59, 59);
- GDateTime *gdt3 = g_date_time_new_local (1918, 3, 31, 23, 59, 59);
- GDateTime *gdt4 = g_date_time_new_local (2057, 11, 20, 23, 59, 59);
-
- gint day, mon, yr;
- Timespec t, r_t;
-
- t = g_date_time_to_timespec (gdt1);
- g_date_time_get_ymd (gdt1, &yr, &mon, &day);
- r_t = gnc_dmy2timespec_end (day, mon, yr);
- g_assert_cmpint (r_t.tv_sec, ==, t.tv_sec);
- g_assert_cmpint (r_t.tv_nsec, ==, t.tv_nsec);
-
- t = g_date_time_to_timespec (gdt2);
- g_date_time_get_ymd (gdt2, &yr, &mon, &day);
- r_t = gnc_dmy2timespec_end (day, mon, yr);
- g_assert_cmpint (r_t.tv_sec, ==, t.tv_sec);
- g_assert_cmpint (r_t.tv_nsec, ==, t.tv_nsec);
-
- t = g_date_time_to_timespec (gdt3);
- g_date_time_get_ymd (gdt3, &yr, &mon, &day);
- r_t = gnc_dmy2timespec_end (day, mon, yr);
- g_assert_cmpint (r_t.tv_sec, ==, t.tv_sec);
- g_assert_cmpint (r_t.tv_nsec, ==, t.tv_nsec);
-
- t = g_date_time_to_timespec (gdt4);
- g_date_time_get_ymd (gdt4, &yr, &mon, &day);
- r_t = gnc_dmy2timespec_end (day, mon, yr);
- g_assert_cmpint (r_t.tv_sec, ==, t.tv_sec);
- g_assert_cmpint (r_t.tv_nsec, ==, t.tv_nsec);
-
- g_date_time_unref (gdt1);
- g_date_time_unref (gdt2);
- g_date_time_unref (gdt3);
- g_date_time_unref (gdt4);
+test_gnc_dmy2timespec_end (FixtureB *f, gconstpointer pData)
+{
+ for (int i = 0; i < sizeof(f->test)/sizeof(TimeMap); ++i)
+ {
+#ifdef HAVE_STRUCT_TM_GMTOFF
+ struct tm tm = {59, 59, 23, f->test[i].day, f->test[i].mon - 1,
+ f->test[i].yr - 1900, 0, 0, -1, 0, NULL};
+#else
+ struct tm tm = {59, 59, 23, f->test[i].day, f->test[i].mon - 1,
+ f->test[i].yr - 1900, 0, 0, -1};
+#endif
+ Timespec r_t = gnc_dmy2timespec_end (f->test[i].day, f->test[i].mon,
+ f->test[i].yr);
+ int offset = gnc_mktime(&tm) - gnc_timegm(&tm);
+ g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs + offset);
+ }
}
+
/* gnc_timezone
long int
gnc_timezone (const struct tm *tm)// C: 5 in 2 Local: 2:0:0
@@ -1926,132 +1831,73 @@ test_timespecTotime64 (void)
GDate timespec_to_gdate (Timespec ts)// C: 5 in 4 Local: 0:0:0
*/
static void
-test_timespec_to_gdate (void)
-{
- GTimeZone *zulu = g_time_zone_new ("Z");
- GTimeZone *tz05 = g_time_zone_new ("-05");
- GTimeZone *tz0840 = g_time_zone_new ("+08:40");
- GDateTime *gdt0 = g_date_time_new_from_unix_utc (0);
- GDateTime *gdt1 = g_date_time_new (zulu, 1989, 3, 27, 13, 43, 27.345678);
- GDateTime *gdt2 = g_date_time_new (tz05, 2020, 11, 7, 6, 21, 19.0);
- GDateTime *gdt3 = g_date_time_new (tz0840, 2012, 7, 4, 19, 27, 44.0);
- GDateTime *gdt4 = g_date_time_new (tz05, 1961, 9, 22, 17, 53, 19.0);
- GDateTime *gdt5 = g_date_time_new (tz05, 2061, 1, 25, 23, 21, 19.0);
- GDateTime *gdt_local;
-
- gint day, mon, yr;
+test_timespec_to_gdate (FixtureA *f, gconstpointer pData)
+{
GDate date1, date2;
- Timespec t;
+ struct tm tm;
g_date_clear (&date2, 1);
- t = g_date_time_to_timespec (gdt0);
- date1 = timespec_to_gdate (t);
- gdt_local = g_date_time_to_local (gdt0);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- g_date_time_unref (gdt_local);
- g_date_set_dmy (&date2, day, mon, yr);
- g_assert_cmpint (g_date_get_julian (&date1), ==, g_date_get_julian (&date2));
-
- t = g_date_time_to_timespec (gdt1);
- date1 = timespec_to_gdate (t);
- gdt_local = g_date_time_to_local (gdt1);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- g_date_time_unref (gdt_local);
- g_date_set_dmy (&date2, day, mon, yr);
- g_assert_cmpint (g_date_get_julian (&date1), ==, g_date_get_julian (&date2));
-
- t = g_date_time_to_timespec (gdt2);
- date1 = timespec_to_gdate (t);
- gdt_local = g_date_time_to_local (gdt2);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- g_date_time_unref (gdt_local);
- g_date_set_dmy (&date2, day, mon, yr);
- g_assert_cmpint (g_date_get_julian (&date1), ==, g_date_get_julian (&date2));
-
- t = g_date_time_to_timespec (gdt3);
- date1 = timespec_to_gdate (t);
- gdt_local = g_date_time_to_local (gdt3);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- g_date_time_unref (gdt_local);
- g_date_set_dmy (&date2, day, mon, yr);
- g_assert_cmpint (g_date_get_julian (&date1), ==, g_date_get_julian (&date2));
- t = g_date_time_to_timespec (gdt4);
- date1 = timespec_to_gdate (t);
- gdt_local = g_date_time_to_local (gdt4);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- g_date_time_unref (gdt_local);
- g_date_set_dmy (&date2, day, mon, yr);
- g_assert_cmpint (g_date_get_julian (&date1), ==, g_date_get_julian (&date2));
-
- t = g_date_time_to_timespec (gdt5);
- date1 = timespec_to_gdate (t);
- gdt_local = g_date_time_to_local (gdt5);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- g_date_time_unref (gdt_local);
- g_date_set_dmy (&date2, day, mon, yr);
- g_assert_cmpint (g_date_get_julian (&date1),
- ==, g_date_get_julian (&date2));
-
- g_date_time_unref (gdt0);
- g_date_time_unref (gdt1);
- g_date_time_unref (gdt2);
- g_date_time_unref (gdt3);
- g_date_time_unref (gdt4);
- g_date_time_unref (gdt5);
- g_time_zone_unref (zulu);
- g_time_zone_unref (tz05);
- g_time_zone_unref (tz0840);
+ date1 = timespec_to_gdate (f->ts0);
+ gnc_localtime_r(&f->ts0.tv_sec, &tm);
+ g_date_set_dmy (&date2, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
+ g_assert_cmpint (g_date_get_julian (&date1), ==,
+ g_date_get_julian (&date2));
+
+ date1 = timespec_to_gdate (f->ts1);
+ gnc_localtime_r(&f->ts1.tv_sec, &tm);
+ g_date_set_dmy (&date2, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
+ g_assert_cmpint (g_date_get_julian (&date1), ==,
+ g_date_get_julian (&date2));
+
+ date1 = timespec_to_gdate (f->ts2);
+ gnc_localtime_r(&f->ts2.tv_sec, &tm);
+ g_date_set_dmy (&date2, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
+ g_assert_cmpint (g_date_get_julian (&date1), ==,
+ g_date_get_julian (&date2));
+
+ date1 = timespec_to_gdate (f->ts3);
+ gnc_localtime_r(&f->ts3.tv_sec, &tm);
+ g_date_set_dmy (&date2, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
+ g_assert_cmpint (g_date_get_julian (&date1), ==,
+ g_date_get_julian (&date2));
+
+ date1 = timespec_to_gdate (f->ts4);
+ gnc_localtime_r(&f->ts4.tv_sec, &tm);
+ g_date_set_dmy (&date2, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
+ g_assert_cmpint (g_date_get_julian (&date1), ==,
+ g_date_get_julian (&date2));
+
+ date1 = timespec_to_gdate (f->ts5);
+ gnc_localtime_r(&f->ts5.tv_sec, &tm);
+ g_date_set_dmy (&date2, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
+ g_assert_cmpint (g_date_get_julian (&date1), ==,
+ g_date_get_julian (&date2));
}
+
/* gdate_to_timespec
Timespec gdate_to_timespec (GDate d)// C: 7 in 6 Local: 0:0:0
*/
static void
-test_gdate_to_timespec (void)
-{
- GDateTime *gdt1 = g_date_time_new_local (1999, 7, 21, 0, 0, 0);
- GDateTime *gdt2 = g_date_time_new_local (1918, 3, 31, 0, 0, 0);
- GDateTime *gdt3 = g_date_time_new_local (1918, 4, 1, 0, 0, 0);
- GDateTime *gdt4 = g_date_time_new_local (2057, 11, 20, 0, 0, 0);
-
- gint day, mon, yr;
- Timespec t, r_t;
- GDate gd;
-
- g_date_clear (&gd, 1);
-
- t = g_date_time_to_timespec (gdt1);
- g_date_time_get_ymd (gdt1, &yr, &mon, &day);
- g_date_set_dmy (&gd, day, mon, yr);
- r_t = gdate_to_timespec (gd);
- g_assert_cmpint (r_t.tv_sec, ==, t.tv_sec);
- g_assert_cmpint (r_t.tv_nsec, ==, t.tv_nsec);
-
- t = g_date_time_to_timespec (gdt2);
- g_date_time_get_ymd (gdt2, &yr, &mon, &day);
- g_date_set_dmy (&gd, day, mon, yr);
- r_t = gdate_to_timespec (gd);
- g_assert_cmpint (r_t.tv_sec, ==, t.tv_sec);
- g_assert_cmpint (r_t.tv_nsec, ==, t.tv_nsec);
-
- t = g_date_time_to_timespec (gdt3);
- g_date_time_get_ymd (gdt3, &yr, &mon, &day);
- g_date_set_dmy (&gd, day, mon, yr);
- r_t = gdate_to_timespec (gd);
- g_assert_cmpint (r_t.tv_sec, ==, t.tv_sec);
- g_assert_cmpint (r_t.tv_nsec, ==, t.tv_nsec);
-
- t = g_date_time_to_timespec (gdt4);
- g_date_time_get_ymd (gdt4, &yr, &mon, &day);
- g_date_set_dmy (&gd, day, mon, yr);
- r_t = gdate_to_timespec (gd);
- g_assert_cmpint (r_t.tv_sec, ==, t.tv_sec);
- g_assert_cmpint (r_t.tv_nsec, ==, t.tv_nsec);
-
- g_date_time_unref (gdt1);
- g_date_time_unref (gdt2);
- g_date_time_unref (gdt3);
- g_date_time_unref (gdt4);
+test_gdate_to_timespec (FixtureB *f, gconstpointer pData)
+{
+ for (int i = 0; i < sizeof(f->test)/sizeof(TimeMap); ++i)
+ {
+#ifdef HAVE_STRUCT_TM_GMTOFF
+ struct tm tm = {0, 0, 0, f->test[i].day, f->test[i].mon - 1,
+ f->test[i].yr - 1900, 0, 0, -1, 0, NULL};
+#else
+ struct tm tm = {0, 0, 0, f->test[i].day, f->test[i].mon - 1,
+ f->test[i].yr - 1900, 0, 0, -1};
+#endif
+ GDate gd;
+ Timespec r_t;
+ int offset = gnc_mktime(&tm) - gnc_timegm(&tm);
+ g_date_clear(&gd, 1);
+ g_date_set_dmy(&gd, f->test[i].day, f->test[i].mon, f->test[i].yr);
+ r_t = gdate_to_timespec(gd);
+ g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs + offset);
+ }
}
/* gnc_tm_get_day_start
static void
@@ -2073,160 +1919,112 @@ test_gnc_tm_get_day_end (void)
time64
gnc_time64_get_day_start (time64 time_val)// C: 8 in 7 Local: 0:0:0
*/
+
+static void
+tm_day_begin(struct tm *tm)
+{
+ tm->tm_hour = 0;
+ tm->tm_min = 0;
+ tm->tm_sec = 0;
+}
+
static void
-test_gnc_time64_get_day_start (void)
-{
- GTimeZone *zulu = g_time_zone_new ("Z");
- GTimeZone *tz05 = g_time_zone_new ("-05");
- GTimeZone *tz0840 = g_time_zone_new ("+08:40");
- GDateTime *gdt0 = g_date_time_new_from_unix_utc (0);
- GDateTime *gdt1 = g_date_time_new (zulu, 1989, 3, 27, 13, 43, 27.345678);
- GDateTime *gdt2 = g_date_time_new (tz05, 2020, 11, 7, 6, 21, 19.0);
- GDateTime *gdt3 = g_date_time_new (tz0840, 2012, 7, 4, 19, 27, 44.0);
- GDateTime *gdt4 = g_date_time_new (tz05, 1961, 9, 22, 17, 53, 19.0);
- GDateTime *gdt5 = g_date_time_new (tz05, 2061, 1, 25, 23, 21, 19.0);
- GDateTime *gdt_local, *gdt_day_begin;
-
- gint day, mon, yr;
- time64 time, t_time, r_time;
-
- gdt_local = g_date_time_to_local (gdt0);
- time = g_date_time_to_unix (gdt0);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_begin = g_date_time_new_local (yr, mon, day, 0, 0, 0);
- t_time = g_date_time_to_unix (gdt_day_begin);
- r_time = gnc_time64_get_day_start (time);
- /* This will work in the half of the world where localtime is later than UTC */
+test_gnc_time64_get_day_start (FixtureA *f, gconstpointer pData)
+{
+ struct tm tm;
+ time64 t_time, r_time;
+
+ gnc_localtime_r(&f->ts0.tv_sec, &tm);
+ tm_day_begin(&tm);
+ t_time = gnc_mktime(&tm);
+ r_time = gnc_time64_get_day_start (f->ts0.tv_sec);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = g_date_time_to_local (gdt1);
- time = g_date_time_to_unix (gdt1);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_begin = g_date_time_new_local (yr, mon, day, 0, 0, 0);
- t_time = g_date_time_to_unix (gdt_day_begin);
- r_time = gnc_time64_get_day_start (time);
+ gnc_localtime_r(&f->ts1.tv_sec, &tm);
+ tm_day_begin(&tm);
+ t_time = gnc_mktime(&tm);
+ r_time = gnc_time64_get_day_start (f->ts1.tv_sec);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = g_date_time_to_local (gdt2);
- time = g_date_time_to_unix (gdt2);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_begin = g_date_time_new_local (yr, mon, day, 0, 0, 0);
- t_time = g_date_time_to_unix (gdt_day_begin);
- r_time = gnc_time64_get_day_start (time);
+ gnc_localtime_r(&f->ts2.tv_sec, &tm);
+ tm_day_begin(&tm);
+ t_time = gnc_mktime(&tm);
+ r_time = gnc_time64_get_day_start (f->ts2.tv_sec);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = g_date_time_to_local (gdt3);
- time = g_date_time_to_unix (gdt3);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_begin = g_date_time_new_local (yr, mon, day, 0, 0, 0);
- t_time = g_date_time_to_unix (gdt_day_begin);
- r_time = gnc_time64_get_day_start (time);
+ gnc_localtime_r(&f->ts3.tv_sec, &tm);
+ tm_day_begin(&tm);
+ t_time = gnc_mktime(&tm);
+ r_time = gnc_time64_get_day_start (f->ts3.tv_sec);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = g_date_time_to_local (gdt4);
- time = g_date_time_to_unix (gdt4);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_begin = g_date_time_new_local (yr, mon, day, 0, 0, 0);
- t_time = g_date_time_to_unix (gdt_day_begin);
- r_time = gnc_time64_get_day_start (time);
+ gnc_localtime_r(&f->ts4.tv_sec, &tm);
+ tm_day_begin(&tm);
+ t_time = gnc_mktime(&tm);
+ r_time = gnc_time64_get_day_start (f->ts4.tv_sec);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = g_date_time_to_local (gdt5);
- time = g_date_time_to_unix (gdt5);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_begin = g_date_time_new_local (yr, mon, day, 0, 0, 0);
- t_time = g_date_time_to_unix (gdt_day_begin);
- r_time = gnc_time64_get_day_start (time);
+ gnc_localtime_r(&f->ts5.tv_sec, &tm);
+ tm_day_begin(&tm);
+ t_time = gnc_mktime(&tm);
+ r_time = gnc_time64_get_day_start (f->ts5.tv_sec);
g_assert_cmpint (t_time, ==, r_time);
- g_date_time_unref (gdt0);
- g_date_time_unref (gdt1);
- g_date_time_unref (gdt2);
- g_date_time_unref (gdt3);
- g_date_time_unref (gdt4);
- g_date_time_unref (gdt5);
- g_time_zone_unref (zulu);
- g_time_zone_unref (tz05);
- g_time_zone_unref (tz0840);
-}
+ }
/* gnc_time64_get_day_end
time64
gnc_time64_get_day_end (time64 time_val)// C: 12 in 8 Local: 0:0:0
*/
static void
-test_gnc_time64_get_day_end (void)
-{
- GTimeZone *zulu = g_time_zone_new ("Z");
- GTimeZone *tz05 = g_time_zone_new ("-05");
- GTimeZone *tz0840 = g_time_zone_new ("+08:40");
- GDateTime *gdt0 = g_date_time_new_from_unix_utc (0);
- GDateTime *gdt1 = g_date_time_new (zulu, 1989, 3, 27, 13, 43, 27.345678);
- GDateTime *gdt2 = g_date_time_new (tz05, 2020, 11, 7, 6, 21, 19.0);
- GDateTime *gdt3 = g_date_time_new (tz0840, 2012, 7, 4, 19, 27, 44.0);
- GDateTime *gdt4 = g_date_time_new (tz05, 1961, 9, 22, 17, 53, 19.0);
- GDateTime *gdt5 = g_date_time_new (tz05, 2061, 1, 25, 23, 21, 19.0);
- GDateTime *gdt_local, *gdt_day_end;
-
- gint day, mon, yr;
- time64 time, t_time, r_time;
-
- gdt_local = g_date_time_to_local (gdt0);
- time = g_date_time_to_unix (gdt0);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_end = g_date_time_new_local (yr, mon, day, 23, 59, 59);
- t_time = g_date_time_to_unix (gdt_day_end);
- r_time = gnc_time64_get_day_end (time);
+tm_day_end(struct tm *tm)
+{
+ tm->tm_hour = 23;
+ tm->tm_min = 59;
+ tm->tm_sec = 59;
+}
+
+static void
+test_gnc_time64_get_day_end (FixtureA *f, gconstpointer pData)
+{
+ struct tm tm;
+ time64 t_time, r_time;
+
+ gnc_localtime_r(&f->ts0.tv_sec, &tm);
+ tm_day_end(&tm);
+ t_time = gnc_mktime(&tm);
+ r_time = gnc_time64_get_day_end (f->ts0.tv_sec);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = g_date_time_to_local (gdt1);
- time = g_date_time_to_unix (gdt1);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_end = g_date_time_new_local (yr, mon, day, 23, 59, 59);
- t_time = g_date_time_to_unix (gdt_day_end);
- r_time = gnc_time64_get_day_end (time);
+ gnc_localtime_r(&f->ts1.tv_sec, &tm);
+ tm_day_end(&tm);
+ t_time = gnc_mktime(&tm);
+ r_time = gnc_time64_get_day_end (f->ts1.tv_sec);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = g_date_time_to_local (gdt2);
- time = g_date_time_to_unix (gdt2);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_end = g_date_time_new_local (yr, mon, day, 23, 59, 59);
- t_time = g_date_time_to_unix (gdt_day_end);
- r_time = gnc_time64_get_day_end (time);
+ gnc_localtime_r(&f->ts2.tv_sec, &tm);
+ tm_day_end(&tm);
+ t_time = gnc_mktime(&tm);
+ r_time = gnc_time64_get_day_end (f->ts2.tv_sec);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = g_date_time_to_local (gdt3);
- time = g_date_time_to_unix (gdt3);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_end = g_date_time_new_local (yr, mon, day, 23, 59, 59);
- t_time = g_date_time_to_unix (gdt_day_end);
- r_time = gnc_time64_get_day_end (time);
+ gnc_localtime_r(&f->ts3.tv_sec, &tm);
+ tm_day_end(&tm);
+ t_time = gnc_mktime(&tm);
+ r_time = gnc_time64_get_day_end (f->ts3.tv_sec);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = g_date_time_to_local (gdt4);
- time = g_date_time_to_unix (gdt4);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_end = g_date_time_new_local (yr, mon, day, 23, 59, 59);
- t_time = g_date_time_to_unix (gdt_day_end);
- r_time = gnc_time64_get_day_end (time);
+ gnc_localtime_r(&f->ts4.tv_sec, &tm);
+ tm_day_end(&tm);
+ t_time = gnc_mktime(&tm);
+ r_time = gnc_time64_get_day_end (f->ts4.tv_sec);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = g_date_time_to_local (gdt5);
- time = g_date_time_to_unix (gdt5);
- g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_end = g_date_time_new_local (yr, mon, day, 23, 59, 59);
- t_time = g_date_time_to_unix (gdt_day_end);
- r_time = gnc_time64_get_day_end (time);
+ gnc_localtime_r(&f->ts5.tv_sec, &tm);
+ tm_day_end(&tm);
+ t_time = gnc_mktime(&tm);
+ r_time = gnc_time64_get_day_end (f->ts5.tv_sec);
g_assert_cmpint (t_time, ==, r_time);
- g_date_time_unref (gdt0);
- g_date_time_unref (gdt1);
- g_date_time_unref (gdt2);
- g_date_time_unref (gdt3);
- g_date_time_unref (gdt4);
- g_date_time_unref (gdt5);
- g_time_zone_unref (zulu);
- g_time_zone_unref (tz05);
- g_time_zone_unref (tz0840);
}
/* gnc_tm_get_today_start
void
@@ -2326,22 +2124,22 @@ test_suite_gnc_date (void)
// GNC_TEST_ADD_FUNC (suitename, "qof format time", test_qof_format_time);
// GNC_TEST_ADD_FUNC (suitename, "qof strftime", test_qof_strftime);
GNC_TEST_ADD_FUNC (suitename, "gnc_date_timestamp", test_gnc_date_timestamp);
- GNC_TEST_ADD_FUNC (suitename, "gnc iso8601 to timespec gmt", test_gnc_iso8601_to_timespec_gmt);
- GNC_TEST_ADD_FUNC (suitename, "gnc timespec to iso8601 buff", test_gnc_timespec_to_iso8601_buff);
- GNC_TEST_ADD_FUNC (suitename, "gnc timespec2dmy", test_gnc_timespec2dmy);
+ GNC_TEST_ADD (suitename, "gnc iso8601 to timespec gmt", FixtureA, NULL, setup, test_gnc_iso8601_to_timespec_gmt, NULL);
+ GNC_TEST_ADD (suitename, "gnc timespec to iso8601 buff", FixtureA, NULL, setup, test_gnc_timespec_to_iso8601_buff, NULL);
+ GNC_TEST_ADD (suitename, "gnc timespec2dmy", FixtureA, NULL, setup, test_gnc_timespec2dmy, NULL);
// GNC_TEST_ADD_FUNC (suitename, "gnc dmy2timespec internal", test_gnc_dmy2timespec_internal);
- GNC_TEST_ADD_FUNC (suitename, "gnc dmy2timespec", test_gnc_dmy2timespec);
- GNC_TEST_ADD_FUNC (suitename, "gnc dmy2timespec end", test_gnc_dmy2timespec_end);
+ GNC_TEST_ADD (suitename, "gnc dmy2timespec", FixtureB, NULL, setup_begin, test_gnc_dmy2timespec, NULL);
+ GNC_TEST_ADD (suitename, "gnc dmy2timespec end", FixtureB, NULL, setup_end, test_gnc_dmy2timespec_end, NULL);
// GNC_TEST_ADD_FUNC (suitename, "gnc timezone", test_gnc_timezone);
// GNC_TEST_ADD_FUNC (suitename, "timespecFromTime t", test_timespecFromtime64);
// GNC_TEST_ADD_FUNC (suitename, "timespec now", test_timespec_now);
// GNC_TEST_ADD_FUNC (suitename, "timespecToTime t", test_timespecTotime64);
- GNC_TEST_ADD_FUNC (suitename, "timespec to gdate", test_timespec_to_gdate);
- GNC_TEST_ADD_FUNC (suitename, "gdate to timespec", test_gdate_to_timespec);
+ GNC_TEST_ADD (suitename, "timespec to gdate", FixtureA, NULL, setup, test_timespec_to_gdate, NULL);
+ GNC_TEST_ADD (suitename, "gdate to timespec", FixtureB, NULL, setup_begin, test_gdate_to_timespec, NULL);
// GNC_TEST_ADD_FUNC (suitename, "gnc tm get day start", test_gnc_tm_get_day_start);
// GNC_TEST_ADD_FUNC (suitename, "gnc tm get day end", test_gnc_tm_get_day_end);
- GNC_TEST_ADD_FUNC (suitename, "gnc time64 get day start", test_gnc_time64_get_day_start);
- GNC_TEST_ADD_FUNC (suitename, "gnc time64 get day end", test_gnc_time64_get_day_end);
+ GNC_TEST_ADD (suitename, "gnc time64 get day start", FixtureA, NULL, setup, test_gnc_time64_get_day_start, NULL);
+ GNC_TEST_ADD (suitename, "gnc time64 get day end", FixtureA, NULL, setup, test_gnc_time64_get_day_end, NULL);
// GNC_TEST_ADD_FUNC (suitename, "gnc tm get today start", test_gnc_tm_get_today_start);
// GNC_TEST_ADD_FUNC (suitename, "gnc timet get today start", test_gnc_time64_get_today_start);
// GNC_TEST_ADD_FUNC (suitename, "gnc timet get today end", test_gnc_time64_get_today_end);
commit 327ef838ea05151120b44ced18463dfff174df4e
Author: John Ralls <jralls at ceridwen.us>
Date: Fri Feb 27 15:34:39 2015 -0800
Correct a couple of incorrect comments.
diff --git a/src/libqof/qof/gnc-date.h b/src/libqof/qof/gnc-date.h
index bcefb81..6c75372 100644
--- a/src/libqof/qof/gnc-date.h
+++ b/src/libqof/qof/gnc-date.h
@@ -186,7 +186,7 @@ struct tm* gnc_localtime_r (const time64 *secs, struct tm* time);
struct tm* gnc_gmtime (const time64 *secs);
/** \brief calculate seconds from the epoch given a time struct
- * \param time: A struct tm* for the function to fill.
+ * \param time: A struct tm* containing the date-time information.
* The time is understood to be in the current local time zone.
* \return Seconds since 00:00:01 UTC 01 January 1970 (negative values
* are seconds before that moment).
@@ -194,7 +194,7 @@ struct tm* gnc_gmtime (const time64 *secs);
time64 gnc_mktime (struct tm* time);
/** \brief calculate seconds from the epoch given a time struct
- * \param time: A struct tm* for the function to fill.
+ * \param time: A struct tm* containing the date-time information
* The time is understood to be utc.
* \return Seconds since 00:00:01 UTC 01 January 1970 (negative values
* are seconds before that moment).
commit e938b39ff2d7a07f7c7b08abddb9768891ed803e
Author: John Ralls <jralls at ceridwen.us>
Date: Fri Feb 27 15:34:21 2015 -0800
Remove gnc_time_utc.
It produces exactly the same result as gnc_time: The current utc time.
diff --git a/src/import-export/aqb/gnc-ab-utils.c b/src/import-export/aqb/gnc-ab-utils.c
index 1998c0d..fb6c926 100644
--- a/src/import-export/aqb/gnc-ab-utils.c
+++ b/src/import-export/aqb/gnc-ab-utils.c
@@ -506,7 +506,7 @@ gnc_ab_trans_to_gnc(const AB_TRANSACTION *ab_trans, Account *gnc_acc)
else
g_warning("transaction_cb: Oops, date 'valuta_date' was NULL");
- xaccTransSetDateEnteredSecs(gnc_trans, gnc_time_utc (NULL));
+ xaccTransSetDateEnteredSecs(gnc_trans, gnc_time (NULL));
/* Currency. We take simply the default currency of the gnucash account */
xaccTransSetCurrency(gnc_trans, xaccAccountGetCommodity(gnc_acc));
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 7ef9761..f523546 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -284,18 +284,6 @@ time64
gnc_time (time64 *tbuf)
{
auto pdt = boost::posix_time::second_clock::universal_time();
- auto tz = tzp.get(pdt.date().year());
- LDT ldt(pdt, tz);
- auto secs = time64_from_date_time(pdt);
- if (tbuf != nullptr)
- *tbuf = secs;
- return secs;
-}
-
-time64
-gnc_time_utc (time64 *tbuf)
-{
- auto pdt = boost::posix_time::second_clock::universal_time();
auto secs = time64_from_date_time(pdt);
if (tbuf != NULL)
*tbuf = secs;
diff --git a/src/libqof/qof/gnc-date.h b/src/libqof/qof/gnc-date.h
index f166a78..bcefb81 100644
--- a/src/libqof/qof/gnc-date.h
+++ b/src/libqof/qof/gnc-date.h
@@ -219,14 +219,6 @@ gchar* gnc_ctime (const time64 *secs);
*/
time64 gnc_time (time64 *tbuf);
-/** \brief get the current utc time
- * \param A time64* which, if not NULL, will be filled in with the same
- * value as is returned.
- * \return Seconds since 00:00:01 UTC 01 January 1970 (negative values
- * are seconds before that moment)
- */
-time64 gnc_time_utc (time64 *tbuf);
-
/** \brief Find the difference in seconds between two time values
* \param secs1: The first time value, in Seconds since
* 00:00:01 UTC 01 January 1970 (negative values are seconds before that moment)
commit 4f90e4e0507657e0a98f66999a62e4cce46cdc7b
Author: John Ralls <jralls at ceridwen.us>
Date: Fri Feb 27 15:32:46 2015 -0800
Get rid of gettimeofday call in Transaction.
We were throwing away the microseconds anyway.
diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c
index 73ec15d..fb195c1 100644
--- a/src/engine/Transaction.c
+++ b/src/engine/Transaction.c
@@ -1627,15 +1627,7 @@ xaccTransCommitEdit (Transaction *trans)
/* Record the time of last modification */
if (0 == trans->date_entered.tv_sec)
{
- struct timeval tv;
-#ifdef HAVE_GETTIMEOFDAY
- gettimeofday (&tv, NULL);
-#else
- time (&(tv.tv_sec));
- tv.tv_usec = 0;
-#endif
- trans->date_entered.tv_sec = tv.tv_sec;
-// trans->date_entered.tv_nsec = 1000 * tv.tv_usec;
+ trans->date_entered.tv_sec = gnc_time(NULL);
qof_instance_set_dirty(QOF_INSTANCE(trans));
}
commit 99efb5d44634407c8d69f1747b94e26acf7f6615
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Feb 26 12:00:52 2015 -0800
Reimplement gnc_timespec_to_iso8601_buff to handle microseconds.
Just because there are tests that do. Removing fractional seconds (which
are never used in live code) will be a separate step.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 6b1e6ff..7ef9761 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -1358,15 +1358,23 @@ char *
gnc_timespec_to_iso8601_buff (Timespec ts, char * buff)
{
constexpr size_t max_iso_date_length = 32;
- std::string fmt1 = "%Y-%m-%d %H:%M:%s %q";
+ const char* format = "%Y-%m-%d %H:%M:%s %q";
if (! buff) return NULL;
- memset(buff, 0, max_iso_date_length + 1);
- char* str = gnc_print_time64(ts.tv_sec, fmt1.c_str());
- strncpy (buff, str, max_iso_date_length);
- free(str);
- return buff + strlen (buff);
+ using Facet = boost::local_time::local_time_facet;
+ auto date_time = LDT_from_unix_local(ts.tv_sec);
+ date_time = date_time + boost::posix_time::microseconds(ts.tv_nsec / 1000);
+ 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 << date_time;
+ auto sstr = ss.str();
+
+ memset(buff, 0, sstr.length() + 1);
+ strncpy(buff, sstr.c_str(), sstr.length());
+ return buff + sstr.length();
}
void
commit 23687ee21c69a0e1141b4770f16699036c17b2e5
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Feb 26 11:58:59 2015 -0800
Replace random uses of GDateTime.
diff --git a/src/backend/sql/gnc-backend-sql.c b/src/backend/sql/gnc-backend-sql.c
index 5d25bad..2124be9 100644
--- a/src/backend/sql/gnc-backend-sql.c
+++ b/src/backend/sql/gnc-backend-sql.c
@@ -2057,12 +2057,10 @@ load_date( const GncSqlBackend* be, GncSqlRow* row,
if (G_VALUE_HOLDS_INT64 (val))
{
gint64 time = g_value_get_int64 (val);
- GDateTime *gdt = g_date_time_new_from_unix_utc (time);
+ Timespec ts = {time, 0};
+ struct tm tm;
gint day, month, year;
- GDate *date;
- g_date_time_get_ymd (gdt, &year, &month, &day);
- date = g_date_new_dmy (day, month, year);
- g_date_time_unref (gdt);
+ GDate date = timespec_to_gdate(ts);
if ( table_row->gobj_param_name != NULL )
{
if (QOF_IS_INSTANCE (pObject))
@@ -2073,9 +2071,8 @@ load_date( const GncSqlBackend* be, GncSqlRow* row,
}
else
{
- (*setter)( pObject, date );
+ (*setter)( pObject, &date );
}
- g_date_free( date );
}
else if ( G_VALUE_HOLDS_STRING( val ) )
{
diff --git a/src/backend/sql/test/utest-gnc-backend-sql.c b/src/backend/sql/test/utest-gnc-backend-sql.c
index 559b95c..4ab0446 100644
--- a/src/backend/sql/test/utest-gnc-backend-sql.c
+++ b/src/backend/sql/test/utest-gnc-backend-sql.c
@@ -575,42 +575,6 @@ test_gnc_sql_add_objectref_guid_col_info_to_list (Fixture *fixture, gconstpointe
/* gnc_sql_convert_timespec_to_string
gchar*
gnc_sql_convert_timespec_to_string (const GncSqlBackend* be, Timespec ts)// C: 1 */
-static Timespec*
-gnc_date_string_to_timespec_gmt (gchar *datestr)
-{
- Timespec *ts = g_slice_new0 (Timespec);
- gint yr, mo, da, hr, min;
- gdouble sec;
- GDateTime *dt = NULL;
-
- sscanf (datestr, "%04d-%02d-%02d %02d:%02d:%02lf",
- &yr, &mo, &da, &hr, &min, &sec);
- g_assert_cmpint (1, <=, yr);
- g_assert_cmpint (9999, >=, yr);
- g_assert_cmpint (1, <=, mo);
- g_assert_cmpint (12, >=, mo);
- g_assert_cmpint (1, <=, da);
- if (mo == 1 || mo == 3 || mo == 5 || mo == 7
- || mo == 8 || mo == 10 || mo == 12)
- g_assert_cmpint (31, >=, da);
- else if (mo != 2)
- g_assert_cmpint (30, >=, da);
- else if (yr % 4 == 0 && !(yr % 400 == 0 && yr % 2000 != 0))
- g_assert_cmpint (29, >=, da);
- else
- g_assert_cmpint (28, >=, da);
- g_assert_cmpint (0, <=, hr);
- g_assert_cmpint (60, >=, hr);
- g_assert_cmpint (0, <=, min);
- g_assert_cmpint (60, >=, min);
- g_assert_cmpfloat (0.0, <=, sec);
- g_assert_cmpfloat (60.0, >=, sec);
- dt = g_date_time_new_utc (yr, mo, da, hr, min, sec);
- ts->tv_sec = g_date_time_to_unix (dt);
- ts->tv_nsec = g_date_time_get_microsecond (dt) * 1000;
- g_date_time_unref (dt);
- return ts;
-}
#define numtests 6
static void
@@ -635,12 +599,11 @@ test_gnc_sql_convert_timespec_to_string ()
for (i = 0; i < numtests; i++)
{
- Timespec *ts = gnc_date_string_to_timespec_gmt (date[i]);
- gchar *datestr = gnc_sql_convert_timespec_to_string (&be, *ts);
+ Timespec ts = gnc_iso8601_to_timespec_gmt (date[i]);
+ gchar *datestr = gnc_sql_convert_timespec_to_string (&be, ts);
g_assert_cmpstr (date[i], ==, datestr);
g_free (datestr);
- g_slice_free (Timespec, ts);
}
}
diff --git a/src/backend/xml/sixtp-dom-generators.c b/src/backend/xml/sixtp-dom-generators.c
index 5022f69..083bb72 100644
--- a/src/backend/xml/sixtp-dom-generators.c
+++ b/src/backend/xml/sixtp-dom-generators.c
@@ -127,10 +127,6 @@ commodity_ref_to_dom_tree(const char *tag, const gnc_commodity *c)
return ret;
}
-/* gnc_g_date_time_new_from_timespec_local normalizes the timespec,
- * but we want to serialize it un-normalized, so we make a partial
- * copy.
- */
char *
timespec_sec_to_string(const Timespec *ts)
{
diff --git a/src/gnome-utils/gnc-main-window.c b/src/gnome-utils/gnc-main-window.c
index e028e78..89462ef 100644
--- a/src/gnome-utils/gnc-main-window.c
+++ b/src/gnome-utils/gnc-main-window.c
@@ -1655,8 +1655,8 @@ static gchar *generate_statusbar_lastmodified_message()
{
/* Translators: This is the date and time that is shown in
the status bar after opening a file: The date and time of
- last modification. The string is the format string for
- glib's function g_date_time_format(), see there for an
+ last modification. The string is a format string using
+ boost::date_time's format flags, see the boost docs for an
explanation of the modifiers. First string is for a locale
that has the a.m. or p.m. string in its locale, second
string is for locales that do not have that string. */
diff --git a/src/libqof/qof/gnc-date.h b/src/libqof/qof/gnc-date.h
index c25371a..f166a78 100644
--- a/src/libqof/qof/gnc-date.h
+++ b/src/libqof/qof/gnc-date.h
@@ -159,8 +159,7 @@ typedef enum
* versions of Unix. 32-bit time_t overflows at 03:14:07 UTC on
* Tuesday, 19 January 2038 and so cannot represent dates after that.
*
- * These functions use GLib's GDateTime internally, and include a
- * workaround for the lack of Win32 support before GLib 2.36.
+ * These functions use boost::date_time internally.
*/
/** \brief fill out a time struct from a 64-bit time value.
* \param secs: Seconds since 00:00:01 UTC 01 January 1970 (negative values
@@ -243,14 +242,6 @@ gdouble gnc_difftime (const time64 secs1, const time64 secs2);
*/
void gnc_tm_free (struct tm* time);
-/** \brief Create a GDateTime from a Timespec
- * \param ts: A local (int64-based) Timespec
- * \note: GDateTimes use microseconds, not nanoseconds, so in theory we lose precision. In practice, there's no portable way to get either.
- * \note: Works around the lack of Win32 support in GTimeZone before GLib 2.36.
- * \return A GDateTime pointer. Free it with g_date_time_unref () when you're done with it.
- */
-GDateTime* gnc_g_date_time_new_from_timespec_local (Timespec tm);
-
/** \name String / DateFormat conversion. */
//@{
commit eb3bafed7f5dbc7e148344fbe97fe3668e532268
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Feb 26 10:29:11 2015 -0800
Ensure HH:MM:SS field separators are in place for timezone offsets
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 6933580..6b1e6ff 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -1324,7 +1324,11 @@ gnc_iso8601_to_timespec_gmt(const char *cstr)
auto tzpos = str.find_first_of("+-", str.find(":"));
if (tzpos != str.npos)
{
- string tzstr = "XXX" + str.substr(tzpos) ;
+ string tzstr = "XXX" + str.substr(tzpos);
+ if (tzstr.length() > 6 && tzstr[6] != ':') //6 for XXXsHH, s is + or -
+ tzstr.insert(6, ":");
+ if (tzstr.length() > 9 && tzstr[9] != ':') //9 for XXXsHH:MM
+ tzstr.insert(9, ":");
TZ_Ptr tzp(new PTZ(tzstr));
if (str[tzpos - 1] == ' ') --tzpos;
auto pdt = boost::posix_time::time_from_string(str.substr(0, tzpos));
commit ae11e3506fa9ecab5f690caf2fed428aeb13b596
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Feb 26 10:28:19 2015 -0800
Boost::date_time uses "%q" to format timezones by offset.
diff --git a/src/backend/xml/sixtp-dom-generators.c b/src/backend/xml/sixtp-dom-generators.c
index 48311ef..5022f69 100644
--- a/src/backend/xml/sixtp-dom-generators.c
+++ b/src/backend/xml/sixtp-dom-generators.c
@@ -134,7 +134,7 @@ commodity_ref_to_dom_tree(const char *tag, const gnc_commodity *c)
char *
timespec_sec_to_string(const Timespec *ts)
{
- return gnc_print_time64(ts->tv_sec, "%Y-%m-%d %H:%M:%S %z");
+ return gnc_print_time64(ts->tv_sec, "%Y-%m-%d %H:%M:%S %q");
}
gchar *
commit 154911e23ffdcf6a4a938aa84ffdd7f444dc935a
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Feb 26 10:26:46 2015 -0800
Align GDate's month (1-12) with struct tm's (0-11).
Wow. This has gone undetected for an amazingly long time.
diff --git a/src/core-utils/gnc-gdate-utils.c b/src/core-utils/gnc-gdate-utils.c
index ae415fd..1ab4ed7 100644
--- a/src/core-utils/gnc-gdate-utils.c
+++ b/src/core-utils/gnc-gdate-utils.c
@@ -39,7 +39,7 @@ gnc_gdate_set_time64 (GDate* gd, time64 time)
{
struct tm tm;
gnc_localtime_r(&time, &tm);
- g_date_set_dmy (gd, tm.tm_mday, tm.tm_mon, tm.tm_year + 1900);
+ g_date_set_dmy (gd, tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
}
commit 32852ec49b8cfdb2ccefe2ef20f8b1160ad0a763
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Feb 26 10:24:23 2015 -0800
Ensure that gnc_timespec_to_iso8601_buff's buff is initialized empty.
So that there's no trailing garbage on the string.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 7260c8e..6933580 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -1358,6 +1358,7 @@ gnc_timespec_to_iso8601_buff (Timespec ts, char * buff)
if (! buff) return NULL;
+ memset(buff, 0, max_iso_date_length + 1);
char* str = gnc_print_time64(ts.tv_sec, fmt1.c_str());
strncpy (buff, str, max_iso_date_length);
free(str);
commit 83f2627bbb1175b39146e52affb19827a9ab38eb
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Feb 26 10:20:54 2015 -0800
Implement gnc_timegm correctly.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 0455f22..7260c8e 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -269,8 +269,9 @@ time64
gnc_timegm (struct tm* time)
{
auto newtime = *time;
- newtime.tm_gmtoff = 0;
- return gnc_mktime(&newtime);
+ normalize_struct_tm(time);
+ auto pdt = boost::posix_time::ptime_from_tm(*time);
+ return time64_from_date_time(pdt);
}
char*
commit 6fd68c3caa59b80a2bcae22c509f94e588e1d99a
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Feb 24 14:11:03 2015 -0800
Fix missed change from PLATFORM_OSX to GNC_PLATFORM_OSX.
diff --git a/src/gnc-module/test/test-dynload.c b/src/gnc-module/test/test-dynload.c
index 435bb40..1bd407a 100644
--- a/src/gnc-module/test/test-dynload.c
+++ b/src/gnc-module/test/test-dynload.c
@@ -28,7 +28,7 @@ guile_main(void *closure, int argc, char ** argv)
#ifdef G_OS_WIN32
/* MinGW builds libgnc-module-0.dll */
modpath = g_module_build_path ("../.libs", "gnc-module-0");
-#elif defined(PLATFORM_OSX)
+#elif defined(GNC_PLATFORM_OSX)
/* We build libgnc-module as a shared library for testing, and on OSX
* that means that g_module_build_path (), which uses ".so", doesn't
* build the right path name.
commit 9f2d3843f856b6e63d956541314db25389edfcb6
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Feb 24 11:53:36 2015 -0800
Miscellaneous corrections to pass tests.
Includes removing some tests that are either no longer relevant or which
only tested test conditions.
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index e9bcb5d..0455f22 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -98,9 +98,9 @@ static const PTime unix_epoch (Date(1970, boost::gregorian::Jan, 1),
boost::posix_time::seconds(0));
/* To ensure things aren't overly screwed up by setting the nanosecond clock for boost::date_time. Don't do it, though, it doesn't get us anything and slows down the date/time library. */
#ifndef BOOST_DATE_TIME_HAS_NANOSECONDS
-static constexpr uint64_t ticks_per_second = UINT64_C(1000000);
+static constexpr auto ticks_per_second = INT64_C(1000000);
#else
-static constexpr uint64_t ticks_per_second = UINT64_C(1000000000);
+static constexpr auto ticks_per_second = INT64_C(1000000000);
#endif
static LDT
gnc_get_LDT(int year, int month, int day, int hour, int minute, int seconds)
@@ -126,7 +126,19 @@ static time64
time64_from_date_time(T time)
{
auto duration = time - unix_epoch;
- return duration.ticks() / ticks_per_second;
+ auto secs = duration.ticks();
+ secs /= ticks_per_second;
+ return secs;
+}
+
+template<>
+time64
+time64_from_date_time<LDT>(LDT time)
+{
+ auto duration = time.utc_time() - unix_epoch;
+ auto secs = duration.ticks();
+ secs /= ticks_per_second;
+ return secs;
}
/****************** Posix Replacement Functions ***************************/
@@ -186,7 +198,8 @@ gnc_gmtime (const time64 *secs)
}
static void
-normalize_time_component (gint *inner, gint *outer, guint divisor, gint base)
+normalize_time_component (int *inner, int *outer, unsigned int divisor,
+ int base)
{
while (*inner < base)
{
@@ -200,11 +213,12 @@ normalize_time_component (gint *inner, gint *outer, guint divisor, gint base)
}
}
-static gint
-normalize_month (gint month)
+static void
+normalize_month(int *month, int *year)
{
- month = (month % 12 + 12) % 12;
- return month == 0 ? 12 : month;
+ ++(*month);
+ normalize_time_component(month, year, 12, 1);
+ --(*month);
}
static void
@@ -213,7 +227,6 @@ normalize_struct_tm (struct tm* time)
gint year = time->tm_year + 1900;
gint last_day;
- ++time->tm_mon;
/* Gregorian_date throws if it gets an out-of-range year
* so clamp year into gregorian_date's range.
*/
@@ -223,20 +236,21 @@ normalize_struct_tm (struct tm* time)
normalize_time_component (&(time->tm_sec), &(time->tm_min), 60, 0);
normalize_time_component (&(time->tm_min), &(time->tm_hour), 60, 0);
normalize_time_component (&(time->tm_hour), &(time->tm_mday), 24, 0);
- normalize_time_component (&(time->tm_mon), &year, 12, 1);
+ normalize_month (&(time->tm_mon), &year);
+
+ // auto month_in_range = []int (int m){ return (m + 12) % 12; }
while (time->tm_mday < 1)
{
- last_day = gnc_date_get_last_mday (normalize_month (--time->tm_mon), year);
- time->tm_mday += last_day;
- normalize_time_component (&(time->tm_mon), &year, 12, 1);
+ normalize_month (&(--time->tm_mon), &year);
+ last_day = gnc_date_get_last_mday (time->tm_mon, year);
+ time->tm_mday += last_day;
}
- last_day = gnc_date_get_last_mday (normalize_month (time->tm_mon), year);
+ last_day = gnc_date_get_last_mday (time->tm_mon, year);
while (time->tm_mday > last_day)
{
- ++time->tm_mon;
time->tm_mday -= last_day;
- normalize_time_component (&(time->tm_mon), &year, 12, 1);
- last_day = gnc_date_get_last_mday (normalize_month (time->tm_mon), year);
+ normalize_month(&(++time->tm_mon), &year);
+ last_day = gnc_date_get_last_mday (time->tm_mon, year);
}
time->tm_year = year - 1900;
}
@@ -245,7 +259,10 @@ time64
gnc_mktime (struct tm* time)
{
normalize_struct_tm (time);
- return time64_from_date_time(boost::posix_time::ptime_from_tm(*time));
+ auto ldt = gnc_get_LDT (time->tm_year + 1900, time->tm_mon + 1,
+ time->tm_mday, time->tm_hour, time->tm_min,
+ time->tm_sec);
+ return time64_from_date_time(ldt);
}
time64
@@ -265,7 +282,9 @@ gnc_ctime (const time64 *secs)
time64
gnc_time (time64 *tbuf)
{
- auto pdt = boost::posix_time::second_clock::local_time();
+ auto pdt = boost::posix_time::second_clock::universal_time();
+ auto tz = tzp.get(pdt.date().year());
+ LDT ldt(pdt, tz);
auto secs = time64_from_date_time(pdt);
if (tbuf != nullptr)
*tbuf = secs;
@@ -516,10 +535,10 @@ int gnc_date_get_last_mday (int month, int year)
};
/* Is this a leap year? */
- if (year % 2000 == 0) return last_day_of_month[1][month-1];
- if (year % 400 == 0 ) return last_day_of_month[0][month-1];
- if (year % 4 == 0 ) return last_day_of_month[1][month-1];
- return last_day_of_month[0][month-1];
+ if (year % 2000 == 0) return last_day_of_month[1][month];
+ if (year % 400 == 0 ) return last_day_of_month[0][month];
+ if (year % 4 == 0 ) return last_day_of_month[1][month];
+ return last_day_of_month[0][month];
}
/* Safety function */
@@ -1276,7 +1295,7 @@ qof_strftime(gchar *buf, gsize max, const gchar *format, const struct tm *tm)
gchar *
gnc_date_timestamp (void)
{
- return gnc_print_time64(gnc_time(nullptr), "%Y-%M-%d %H:%M%S");
+ return gnc_print_time64(gnc_time(nullptr), "%Y%m%d%H%M%S");
}
/********************************************************************\
@@ -1288,11 +1307,43 @@ gnc_date_timestamp (void)
#define ISO_DATE_FORMAT "%d-%d-%d %d:%d:%lf%s"
Timespec
-gnc_iso8601_to_timespec_gmt(const char *str)
+gnc_iso8601_to_timespec_gmt(const char *cstr)
{
- auto pdt = boost::posix_time::time_from_string(str);
- auto time = time64_from_date_time(pdt);
- return {time, 0};
+ using std::string;
+ using PTZ = boost::local_time::posix_time_zone;
+
+ if (!cstr) return {0, 0};
+// try
+ {
+ string str(cstr);
+ if (str.empty())
+ return {0, 0};
+ time64 time;
+ uint32_t nsecs;
+ auto tzpos = str.find_first_of("+-", str.find(":"));
+ if (tzpos != str.npos)
+ {
+ string tzstr = "XXX" + str.substr(tzpos) ;
+ TZ_Ptr tzp(new PTZ(tzstr));
+ if (str[tzpos - 1] == ' ') --tzpos;
+ auto pdt = boost::posix_time::time_from_string(str.substr(0, tzpos));
+ LDT ldt(pdt.date(), pdt.time_of_day(), tzp,
+ LDTBase::NOT_DATE_TIME_ON_ERROR);
+ time = time64_from_date_time(ldt);
+ nsecs = (ldt.utc_time() - unix_epoch).ticks() % ticks_per_second;
+ }
+ else
+ {
+ auto pdt = boost::posix_time::time_from_string(str);
+ time = time64_from_date_time(pdt);
+ nsecs = (pdt - unix_epoch).ticks() % ticks_per_second;
+ }
+ return {time, static_cast<int32_t>(nsecs) * INT32_C(1000)};
+ }
+// catch(...)
+ // {
+// return {0, 0};
+// }
}
/********************************************************************\
@@ -1302,15 +1353,10 @@ char *
gnc_timespec_to_iso8601_buff (Timespec ts, char * buff)
{
constexpr size_t max_iso_date_length = 32;
- std::string fmt1 = "%Y-%m-%d %H:%M";
+ std::string fmt1 = "%Y-%m-%d %H:%M:%s %q";
- g_return_val_if_fail (buff != NULL, NULL);
+ if (! buff) return NULL;
-#ifdef G_OS_WIN32
- fmt1 += "%Z";
-#else
- fmt1 += "%z";
-#endif
char* str = gnc_print_time64(ts.tv_sec, fmt1.c_str());
strncpy (buff, str, max_iso_date_length);
free(str);
diff --git a/src/libqof/qof/test/test-gnc-date.c b/src/libqof/qof/test/test-gnc-date.c
index 98b96e2..3582e18 100644
--- a/src/libqof/qof/test/test-gnc-date.c
+++ b/src/libqof/qof/test/test-gnc-date.c
@@ -152,19 +152,8 @@ test_gnc_gmtime (void)
static void
test_gnc_mktime (void)
{
- struct
- {
- time64 secs;
- gint wday;
- gint yday;
- } ans[5] =
- {
- { -15767956734LL, 4, 297 },
- { -1123692LL, 4, 352 },
- { 432761LL, 2, 6 },
- { 723349832LL, 4, 338 },
- { 1175964426LL, 6, 97 }
- };
+ time64 ans[5] =
+ { -15752870334LL, -1123692LL, 432761LL, 723349832LL, 1175964426LL};
struct tm time[5] =
{
@@ -194,17 +183,8 @@ test_gnc_mktime (void)
time[ind].tm_min,
(gdouble)time[ind].tm_sec);
time64 offset = g_date_time_get_utc_offset (gdt) / G_TIME_SPAN_SECOND;
- g_assert_cmpint (secs, ==, ans[ind].secs - offset);
- g_assert_cmpint (time[ind].tm_wday, ==, ans[ind].wday);
- g_assert_cmpint (time[ind].tm_yday, ==, ans[ind].yday);
- if (g_date_time_is_daylight_savings (gdt))
- g_assert_cmpint (time[ind].tm_isdst, ==, 1);
- else
- g_assert_cmpint (time[ind].tm_isdst, ==, 0);
+ g_assert_cmpint (secs, ==, ans[ind] - offset);
-#ifdef HAVE_STRUCT_TM_GMTOFF
- g_assert_cmpint (time[ind].tm_gmtoff, ==, offset);
-#endif
g_date_time_unref (gdt);
}
}
@@ -216,12 +196,7 @@ test_gnc_mktime (void)
static void
test_gnc_mktime_normalization (void)
{
- struct answer
- {
- time64 secs;
- gint wday;
- gint yday;
- } ans = { 723349832LL, 4, 338 };
+ time64 ans = 723349832LL;
struct tm normal_time =
#ifdef HAVE_STRUCT_TM_GMTOFF
@@ -265,16 +240,8 @@ test_gnc_mktime_normalization (void)
g_assert_cmpint (time[ind].tm_mday, ==, normal_time.tm_mday);
g_assert_cmpint (time[ind].tm_mon, ==, normal_time.tm_mon);
g_assert_cmpint (time[ind].tm_year, ==, normal_time.tm_year);
- g_assert_cmpint (secs, ==, ans.secs - offset);
- g_assert_cmpint (time[ind].tm_wday, ==, ans.wday);
- g_assert_cmpint (time[ind].tm_yday, ==, ans.yday);
- if (g_date_time_is_daylight_savings (gdt))
- g_assert_cmpint (time[ind].tm_isdst, ==, 1);
- else
- g_assert_cmpint (time[ind].tm_isdst, ==, 0);
-#ifdef HAVE_STRUCT_TM_GMTOFF
- g_assert_cmpint (time[ind].tm_gmtoff, ==, offset);
-#endif
+ g_assert_cmpint (secs, ==, ans - offset);
+
g_date_time_unref (gdt);
}
}
@@ -302,7 +269,6 @@ test_gnc_time (void)
{
time64 secs1, secs2;
GDateTime *gdt;
- secs1 = gnc_time (NULL);
secs1 = gnc_time (&secs2);
gdt = g_date_time_new_now_local ();
g_assert_cmpint (secs1, ==, secs2);
@@ -672,7 +638,9 @@ test_timespecCanonicalDayTime (void)
g_assert_cmpint (n0.tv_sec, ==, r0.tv_sec);
g_assert_cmpint (na.tv_sec, ==, ra.tv_sec);
g_assert_cmpint (nb.tv_sec, ==, rb.tv_sec);
- g_assert_cmpint (nc.tv_sec, ==, rc.tv_sec);
+//GDateTime gets DST wrong here: The DST changes on the second Sunday
+//of March, which this is; Our time-zone sets DST, but GDateTime's doesn't.
+ g_assert_cmpint (nc.tv_sec, ==, rc.tv_sec + 3600);
}
/* gnc_date_get_last_mday
@@ -681,32 +649,32 @@ int gnc_date_get_last_mday (int month, int year)// C: 1 Local: 1:0:0
static void
test_gnc_date_get_last_mday (void)
{
- g_assert_cmpint (gnc_date_get_last_mday (1, 1975), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (1, 1980), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (2, 1975), ==, 28);
- g_assert_cmpint (gnc_date_get_last_mday (2, 1980), ==, 29);
- g_assert_cmpint (gnc_date_get_last_mday (3, 1975), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (3, 1980), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (4, 1975), ==, 30);
- g_assert_cmpint (gnc_date_get_last_mday (4, 1980), ==, 30);
- g_assert_cmpint (gnc_date_get_last_mday (5, 1975), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (5, 1980), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (6, 1975), ==, 30);
- g_assert_cmpint (gnc_date_get_last_mday (6, 1980), ==, 30);
+ g_assert_cmpint (gnc_date_get_last_mday (0, 1975), ==, 31);
+ g_assert_cmpint (gnc_date_get_last_mday (0, 1980), ==, 31);
+ g_assert_cmpint (gnc_date_get_last_mday (1, 1975), ==, 28);
+ g_assert_cmpint (gnc_date_get_last_mday (1, 1980), ==, 29);
+ g_assert_cmpint (gnc_date_get_last_mday (2, 1975), ==, 31);
+ g_assert_cmpint (gnc_date_get_last_mday (2, 1980), ==, 31);
+ g_assert_cmpint (gnc_date_get_last_mday (3, 1975), ==, 30);
+ g_assert_cmpint (gnc_date_get_last_mday (3, 1980), ==, 30);
+ g_assert_cmpint (gnc_date_get_last_mday (4, 1975), ==, 31);
+ g_assert_cmpint (gnc_date_get_last_mday (4, 1980), ==, 31);
+ g_assert_cmpint (gnc_date_get_last_mday (5, 1975), ==, 30);
+ g_assert_cmpint (gnc_date_get_last_mday (5, 1980), ==, 30);
+ g_assert_cmpint (gnc_date_get_last_mday (6, 1975), ==, 31);
+ g_assert_cmpint (gnc_date_get_last_mday (6, 1980), ==, 31);
g_assert_cmpint (gnc_date_get_last_mday (7, 1975), ==, 31);
g_assert_cmpint (gnc_date_get_last_mday (7, 1980), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (8, 1975), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (8, 1980), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (9, 1975), ==, 30);
- g_assert_cmpint (gnc_date_get_last_mday (9, 1980), ==, 30);
- g_assert_cmpint (gnc_date_get_last_mday (10, 1975), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (10, 1980), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (11, 1975), ==, 30);
- g_assert_cmpint (gnc_date_get_last_mday (11, 1980), ==, 30);
- g_assert_cmpint (gnc_date_get_last_mday (12, 1975), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (12, 1980), ==, 31);
- g_assert_cmpint (gnc_date_get_last_mday (2, 2000), ==, 29);
- g_assert_cmpint (gnc_date_get_last_mday (2, 2400), ==, 28);
+ g_assert_cmpint (gnc_date_get_last_mday (8, 1975), ==, 30);
+ g_assert_cmpint (gnc_date_get_last_mday (8, 1980), ==, 30);
+ g_assert_cmpint (gnc_date_get_last_mday (9, 1975), ==, 31);
+ g_assert_cmpint (gnc_date_get_last_mday (9, 1980), ==, 31);
+ g_assert_cmpint (gnc_date_get_last_mday (10, 1975), ==, 30);
+ g_assert_cmpint (gnc_date_get_last_mday (10, 1980), ==, 30);
+ g_assert_cmpint (gnc_date_get_last_mday (11, 1975), ==, 31);
+ g_assert_cmpint (gnc_date_get_last_mday (11, 1980), ==, 31);
+ g_assert_cmpint (gnc_date_get_last_mday (1, 2000), ==, 29);
+ g_assert_cmpint (gnc_date_get_last_mday (1, 2400), ==, 28);
}
/* Getter, no testing needed.
QofDateFormat qof_date_format_get (void)// C: 5 in 3 Local: 0:0:0
@@ -1677,7 +1645,7 @@ test_gnc_timespec_to_iso8601_buff (void)
GTimeZone *tz05 = g_time_zone_new ("-05");
GTimeZone *tz0840 = g_time_zone_new ("+08:40");
GDateTime *gdt0 = g_date_time_new_from_unix_utc (0);
- GDateTime *gdt1 = g_date_time_new (zulu, 1989, 3, 27, 13, 43, 27.345678);
+ GDateTime *gdt1 = g_date_time_new (zulu, 1989, 3, 27, 13, 43, 27.0);
GDateTime *gdt2 = g_date_time_new (tz05, 2020, 11, 7, 6, 21, 19.0);
GDateTime *gdt3 = g_date_time_new (tz0840, 2012, 7, 4, 19, 27, 44.0);
GDateTime *gdt4 = g_date_time_new (tz05, 1961, 9, 22, 17, 53, 19.0);
@@ -1687,28 +1655,11 @@ test_gnc_timespec_to_iso8601_buff (void)
gchar *time_str;
Timespec t = { 0, 0 };
gchar *end;
- gchar *logdomain = "qof";
- guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
-#if defined(__clang__)
-#define _func "char *gnc_timespec_to_iso8601_buff(Timespec, char *)"
-#else
-#define _func "char* gnc_timespec_to_iso8601_buff(Timespec, char*)"
-//#define _func "gnc_timespec_to_iso8601_buff"
-#endif
- gchar *msg = _func ": assertion " _Q "buff != NULL' failed";
-#undef _func
- TestErrorStruct check = { loglevel, logdomain, msg, 0 };
- GLogFunc oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler,
- &check);
- g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check);
memset (buff, 0, sizeof buff);
end = gnc_timespec_to_iso8601_buff (t, NULL);
g_assert (end == NULL);
- g_assert_cmpint (check.hits, ==, 1);
-
- g_log_set_default_handler (oldlogger, NULL);
end = gnc_timespec_to_iso8601_buff (t, buff);
g_assert_cmpint (end - buff, ==, strlen (buff));
commit fb6992f30355b0b5d5ee6a8c80b6ce8037f34a0e
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Feb 24 11:50:58 2015 -0800
Separate the initial case so that it ends the year before the first transition.
This permits the zone_vector to actually get the first transition.
diff --git a/src/libqof/qof/gnc-timezone.cpp b/src/libqof/qof/gnc-timezone.cpp
index 1fae186..3f3d638 100644
--- a/src/libqof/qof/gnc-timezone.cpp
+++ b/src/libqof/qof/gnc-timezone.cpp
@@ -559,15 +559,17 @@ TimeZoneProvider::TimeZoneProvider(const std::string& tzname) : zone_vector {}
auto this_info = parser.tzinfo.begin() + txi->index;
auto this_time = boost::posix_time::from_time_t(txi->timestamp);
auto this_year = this_time.date().year();
- //Initial case, gap in transitions > 1 year, non-dst zone
+ //Initial case
+ if (last_time.is_not_a_date_time())
+ zone_vector.push_back(zone_no_dst(this_year - 1, last_info));
+ //gap in transitions > 1 year, non-dst zone
//change. In the last case the exact date of the change will be
//wrong because boost::local_date::timezone isn't able to
//represent it. For GnuCash's purposes this isn't likely to be
//important as the last time this sort of transition happened
//was 1946, but we have to handle the case in order to parse
//the tz file.
- if (last_time.is_not_a_date_time() ||
- this_year - last_time.date().year() > 1 ||
+ else if (this_year - last_time.date().year() > 1 ||
last_info->info.isdst == this_info->info.isdst)
{
zone_vector.push_back(zone_no_dst(this_year, last_info));
commit 23d4e4a56f7166a08c0534325f7d93682e92cd94
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Feb 24 11:49:31 2015 -0800
Correct week determination when computing DST transitions from timestamps.
diff --git a/src/libqof/qof/gnc-timezone.cpp b/src/libqof/qof/gnc-timezone.cpp
index 077291f..1fae186 100644
--- a/src/libqof/qof/gnc-timezone.cpp
+++ b/src/libqof/qof/gnc-timezone.cpp
@@ -443,7 +443,7 @@ namespace DSTRule
Transition::Transition(gregorian_date date) :
month(date.month()), dow(date.day_of_week()),
- week(static_cast<week_num>((7 + date.day() - date.day_of_week()) / 7 + 1))
+ week(static_cast<week_num>((7 + date.day() - date.day_of_week()) / 7))
{}
bool
commit c7ca7850dfde0a34d6e09d9826f8660b387857d2
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Feb 24 11:48:10 2015 -0800
Correct gncBillTerm's use of gnc_date_get_last_mday() to use the struct_tm form of month.
I.e., where January is 0.
diff --git a/src/engine/gncBillTerm.c b/src/engine/gncBillTerm.c
index d65b1bd..3b6eeb0 100644
--- a/src/engine/gncBillTerm.c
+++ b/src/engine/gncBillTerm.c
@@ -764,7 +764,7 @@ compute_monthyear (const GncBillTerm *term, Timespec post_date,
gnc_timespec2dmy (post_date, &iday, &imonth, &iyear);
if (cutoff <= 0)
- cutoff += gnc_date_get_last_mday (imonth, iyear);
+ cutoff += gnc_date_get_last_mday (imonth - 1, iyear);
if (iday <= cutoff)
{
@@ -811,7 +811,7 @@ compute_time (const GncBillTerm *term, Timespec post_date, int days)
break;
case GNC_TERM_TYPE_PROXIMO:
compute_monthyear (term, post_date, &month, &year);
- day = gnc_date_get_last_mday (month, year);
+ day = gnc_date_get_last_mday (month - 1, year);
if (days < day)
day = days;
res = gnc_dmy2timespec (day, month, year);
commit a07c78e51120d8cd7a5e117095416affacc03f8a
Author: John Ralls <jralls at ceridwen.us>
Date: Sun Feb 8 19:41:56 2015 -0800
Start fixing up test-gnc-date.c for boost::date_time.
diff --git a/src/libqof/qof/test/test-gnc-date.c b/src/libqof/qof/test/test-gnc-date.c
index c2fc38d..98b96e2 100644
--- a/src/libqof/qof/test/test-gnc-date.c
+++ b/src/libqof/qof/test/test-gnc-date.c
@@ -52,59 +52,23 @@ extern "C"
static const gchar *suitename = "/qof/gnc-date";
void test_suite_gnc_date ( void );
-
-typedef struct
-{
- GDateTime *(*new_local)(gint, gint, gint, gint, gint, gdouble);
- GDateTime *(*adjust_for_dst)(GDateTime *, GTimeZone *);
- GDateTime *(*new_from_unix_local)(time64);
- GDateTime *(*new_from_timeval_local)(GTimeVal *);
- GDateTime *(*new_now_local)(void);
- GDateTime *(*to_local)(GDateTime *);
-} _GncDateTime;
-
-static _GncDateTime gncdt;
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-extern void _gnc_date_time_init (_GncDateTime *);
-
-#ifdef __cplusplus
-}
-#endif
-
+static GTimeZone *tz;
/* gnc_localtime just creates a tm on the heap and calls
* gnc_localtime_r with it, so this suffices to test both.
*/
static void
test_gnc_localtime (void)
{
- time64 secs[6] = {-43238956734LL, -1123692LL, 432761LL,
+ time64 secs[6] = {-15767956734LL, -1123692LL, 432761LL,
723349832LL, 887326459367LL,
1364160236LL // This is "Sunday 2013-03-24" (to verify the Sunday
// difference between g_date_time and tm->tm_wday)
};
guint ind;
-#if defined(__clang__)
-#define _func "struct tm *gnc_localtime_r(const time64 *, struct tm *)"
-#else
-#define _func "tm* gnc_localtime_r(const time64*, tm*)"
-//#define _func "gnc_localtime_r"
-#endif
- gchar *msg = _func ": assertion " _Q "gdt != NULL' failed";
-#undef _func
- gint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
- gchar *logdomain = "qof";
- TestErrorStruct check = {loglevel, logdomain, msg, 0};
- GLogFunc hdlr = g_log_set_default_handler ((GLogFunc)test_null_handler, &check);
- g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check);
-
for (ind = 0; ind < G_N_ELEMENTS (secs); ind++)
{
struct tm* time = gnc_localtime (&secs[ind]);
- GDateTime *gdt = gncdt.new_from_unix_local (secs[ind]);
+ GDateTime *gdt = g_date_time_new_from_unix_local (secs[ind]);
if (gdt == NULL)
{
g_assert (time == NULL);
@@ -118,7 +82,9 @@ test_gnc_localtime (void)
g_assert_cmpint (time->tm_sec, ==, g_date_time_get_second (gdt));
// Watch out: struct tm has wday=0..6 with Sunday=0, but GDateTime has wday=1..7 with Sunday=7.
g_assert_cmpint (time->tm_wday, ==, (g_date_time_get_day_of_week (gdt) % 7));
- g_assert_cmpint (time->tm_yday, ==, g_date_time_get_day_of_year (gdt));
+ //tm_yday is 0-based, g_date_time_get_day_of_year is 1-based.
+ g_assert_cmpint (time->tm_yday, ==,
+ g_date_time_get_day_of_year (gdt) - 1);
if (g_date_time_is_daylight_savings (gdt))
g_assert_cmpint (time->tm_isdst, ==, 1);
else
@@ -130,49 +96,33 @@ test_gnc_localtime (void)
g_date_time_unref (gdt);
gnc_tm_free (time);
}
- g_assert_cmpint (check.hits, ==, 1);
- g_log_set_default_handler (hdlr, NULL);
}
static void
test_gnc_gmtime (void)
{
- time64 secs[6] = {-43238956734LL, -1123692LL, 432761LL,
+ time64 secs[6] = {-15767956734LL, -1123692LL, 432761LL,
723349832LL, 887326459367LL, 1175964426LL
};
struct tm answers[6] =
{
#ifdef HAVE_STRUCT_TM_GMTOFF
- { 6, 41, 2, 24, 9, -1301, 4, 297, 0, 0, NULL },
- { 48, 51, 23, 18, 11, 69, 4, 352, 0, 0, NULL },
- { 41, 12, 0, 6, 0, 70, 2, 6, 0, 0, NULL },
- { 32, 30, 2, 3, 11, 92, 4, 338, 0, 0, NULL },
+ { 6, 1, 12, 2, 4, -430, 1, 121, 0, 0, NULL },
+ { 48, 51, 23, 18, 11, 69, 4, 351, 0, 0, NULL },
+ { 41, 12, 0, 6, 0, 70, 2, 5, 0, 0, NULL },
+ { 32, 30, 2, 3, 11, 92, 4, 337, 0, 0, NULL },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
- { 6, 47, 16, 7, 3, 107, 6, 97, 0, 0, NULL },
+ { 6, 47, 16, 7, 3, 107, 6, 96, 0, 0, NULL },
#else
- { 6, 41, 2, 24, 9, -1301, 4, 297, 0 },
- { 48, 51, 23, 18, 11, 69, 4, 352, 0 },
- { 41, 12, 0, 6, 0, 70, 2, 6, 0 },
- { 32, 30, 2, 3, 11, 92, 4, 338, 0 },
+ { 6, 1, 12, 2, 4 -430, 1, 121, 0 },
+ { 48, 51, 23, 18, 11, 69, 4, 351, 0 },
+ { 41, 12, 0, 6, 0, 70, 2, 5, 0 },
+ { 32, 30, 2, 3, 11, 92, 4, 337, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 6, 47, 16, 7, 3, 107, 6, 97, 0 },
+ { 6, 47, 16, 7, 3, 107, 6, 96, 0 },
#endif
};
guint ind;
-#if defined(__clang__)
-#define _func "struct tm *gnc_gmtime(const time64 *)"
-#else
-#define _func "tm* gnc_gmtime(const time64*)"
-//#define _func "gnc_gmtime"
-#endif
- gchar *msg = _func ": assertion " _Q "gdt != NULL' failed";
-#undef _func
- gint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
- gchar *logdomain = "qof";
- TestErrorStruct check = {loglevel, logdomain, msg, 0};
- GLogFunc hdlr = g_log_set_default_handler ((GLogFunc)test_null_handler, &check);
- g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check);
-
for (ind = 0; ind < G_N_ELEMENTS (secs); ind++)
{
struct tm* time = gnc_gmtime (&secs[ind]);
@@ -190,15 +140,13 @@ test_gnc_gmtime (void)
g_assert_cmpint (time->tm_sec, ==, answers[ind].tm_sec);
g_assert_cmpint (time->tm_wday, ==, answers[ind].tm_wday);
g_assert_cmpint (time->tm_yday, ==, answers[ind].tm_yday);
- g_assert_cmpint (time->tm_isdst, ==, 0);
+ g_assert_cmpint (time->tm_isdst, ==, -1);
#ifdef HAVE_STRUCT_TM_GMTOFF
g_assert_cmpint (time->tm_gmtoff, ==, 0);
#endif
g_date_time_unref (gdt);
gnc_tm_free (time);
}
- g_assert_cmpint (check.hits, ==, 1);
- g_log_set_default_handler (hdlr, NULL);
}
static void
@@ -211,7 +159,7 @@ test_gnc_mktime (void)
gint yday;
} ans[5] =
{
- { -43238956734LL, 4, 297 },
+ { -15767956734LL, 4, 297 },
{ -1123692LL, 4, 352 },
{ 432761LL, 2, 6 },
{ 723349832LL, 4, 338 },
@@ -221,13 +169,13 @@ test_gnc_mktime (void)
struct tm time[5] =
{
#ifdef HAVE_STRUCT_TM_GMTOFF
- { 6, 41, 2, 24, 9, -1301, 0, 0, -1, 0, NULL },
+ { 6, 41, 2, 24, 9, -430, 0, 0, -1, 0, NULL },
{ 48, 51, 23, 18, 11, 69, 0, 0, -1, 0, NULL },
{ 41, 12, 0, 6, 0, 70, 0, 0, -1, 0, NULL },
{ 32, 30, 2, 3, 11, 92, 0, 0, -1, 0, NULL },
{ 6, 47, 16, 7, 3, 107, 0, 0, -1, 0, NULL },
#else
- { 6, 41, 2, 24, 9, -1301, 0, 0, -1 },
+ { 6, 41, 2, 24, 9, -430, 0, 0, -1 },
{ 48, 51, 23, 18, 11, 69, 0, 0, -1 },
{ 41, 12, 0, 6, 0, 70, 0, 0, -1 },
{ 32, 30, 2, 3, 11, 92, 0, 0, -1 },
@@ -239,7 +187,7 @@ test_gnc_mktime (void)
for (ind = 0; ind < G_N_ELEMENTS (time); ind++)
{
time64 secs = gnc_mktime (&time[ind]);
- GDateTime *gdt = gncdt.new_local (time[ind].tm_year + 1900,
+ GDateTime *gdt = g_date_time_new_local (time[ind].tm_year + 1900,
time[ind].tm_mon + 1,
time[ind].tm_mday,
time[ind].tm_hour,
@@ -304,7 +252,7 @@ test_gnc_mktime_normalization (void)
for (ind = 0; ind < G_N_ELEMENTS (time); ind++)
{
time64 secs = gnc_mktime (&time[ind]);
- GDateTime *gdt = gncdt.new_local (time[ind].tm_year + 1900,
+ GDateTime *gdt = g_date_time_new_local (time[ind].tm_year + 1900,
time[ind].tm_mon + 1,
time[ind].tm_mday,
time[ind].tm_hour,
@@ -334,13 +282,13 @@ test_gnc_mktime_normalization (void)
static void
test_gnc_ctime (void)
{
- time64 secs[5] = {-43238956734LL, -1123692LL, 432761LL,
+ time64 secs[5] = {-15767956734LL, -1123692LL, 432761LL,
723349832LL, 1175964426LL
};
guint ind;
for (ind = 0; ind < G_N_ELEMENTS (secs); ind++)
{
- GDateTime *gdt = gncdt.new_from_unix_local (secs[ind]);
+ GDateTime *gdt = g_date_time_new_from_unix_local (secs[ind]);
gchar* datestr = gnc_ctime (&secs[ind]);
g_assert_cmpstr (datestr, ==,
g_date_time_format (gdt, "%a %b %e %H:%M:%S %Y"));
@@ -356,7 +304,7 @@ test_gnc_time (void)
GDateTime *gdt;
secs1 = gnc_time (NULL);
secs1 = gnc_time (&secs2);
- gdt = gncdt.new_now_local ();
+ gdt = g_date_time_new_now_local ();
g_assert_cmpint (secs1, ==, secs2);
g_assert_cmpint (secs1, ==, g_date_time_to_unix (gdt));
g_date_time_unref (gdt);
@@ -683,14 +631,14 @@ timespecCanonicalDayTime(Timespec t)// C: 12 in 5 SCM: 19 in 10 Local: 0:0:0
static Timespec
compute_noon_of_day (Timespec *ts)
{
- GDateTime *g = gncdt.new_from_unix_local (ts->tv_sec);
+ GDateTime *g = g_date_time_new_from_unix_local (ts->tv_sec);
gint yr = g_date_time_get_year (g);
gint mo = g_date_time_get_month (g);
gint da = g_date_time_get_day_of_month (g);
Timespec nt = {0, 0 };
g_date_time_unref (g);
- g = gncdt.new_local (yr, mo, da, 12, 0, 0.0);
+ g = g_date_time_new_local (yr, mo, da, 12, 0, 0.0);
nt.tv_sec = g_date_time_to_unix (g);
g_date_time_unref (g);
return nt;
@@ -997,9 +945,9 @@ test_qof_print_date_buff (void)
{
gchar buff[MAX_DATE_LENGTH];
gchar *locale = g_strdup (setlocale (LC_TIME, NULL));
- GDateTime *gd1 = gncdt.new_local (1974, 11, 23, 12, 0, 0.0);
- GDateTime *gd2 = gncdt.new_local (1961, 2, 2, 12, 0, 0.0);
- GDateTime *gd3 = gncdt.new_local (2045, 6, 16, 12, 0, 0.0);
+ GDateTime *gd1 = g_date_time_new_local (1974, 11, 23, 12, 0, 0.0);
+ GDateTime *gd2 = g_date_time_new_local (1961, 2, 2, 12, 0, 0.0);
+ GDateTime *gd3 = g_date_time_new_local (2045, 6, 16, 12, 0, 0.0);
time64 tm1 = g_date_time_to_unix (gd1);
time64 tm2 = g_date_time_to_unix (gd2);
@@ -1276,9 +1224,9 @@ static void
test_qof_print_date (void)
{
gchar *locale = g_strdup (setlocale (LC_TIME, NULL));
- GDateTime *gd1 = gncdt.new_local (1974, 11, 23, 12, 0, 0.0);
- GDateTime *gd2 = gncdt.new_local (1961, 2, 2, 12, 0, 0.0);
- GDateTime *gd3 = gncdt.new_local (2045, 6, 16, 12, 0, 0.0);
+ GDateTime *gd1 = g_date_time_new_local (1974, 11, 23, 12, 0, 0.0);
+ GDateTime *gd2 = g_date_time_new_local (1961, 2, 2, 12, 0, 0.0);
+ GDateTime *gd3 = g_date_time_new_local (2045, 6, 16, 12, 0, 0.0);
time64 tm1 = g_date_time_to_unix (gd1);
time64 tm2 = g_date_time_to_unix (gd2);
@@ -1428,7 +1376,7 @@ test_qof_scan_date (void)
{
gchar *locale = g_strdup (setlocale (LC_TIME, NULL));
int day = 0, mo = 0, yr = 0;
- GDateTime *gdt = gncdt.new_now_local ();
+ GDateTime *gdt = g_date_time_new_now_local ();
gint year = g_date_time_get_year (gdt);
gint month = g_date_time_get_month (gdt);
struct tm tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0
@@ -1603,7 +1551,7 @@ gnc_date_timestamp (void)// C: 2 in 2 Local: 0:0:0
static void
test_gnc_date_timestamp (void)
{
- GDateTime *gdt = gncdt.new_now_local ();
+ GDateTime *gdt = g_date_time_new_now_local ();
gchar *timestr = gnc_date_timestamp ();
struct tm tm;
@@ -1703,7 +1651,7 @@ format_timestring (GDateTime *gdt)
{
static const unsigned tzlen = MAX_DATE_LENGTH - 26;
gchar *fmt = "%Y-%m-%d %H:%M";
- GDateTime *ngdt = gncdt.to_local (gdt);
+ GDateTime *ngdt = g_date_time_to_local (gdt);
gchar *date_base = g_date_time_format (ngdt, fmt);
gchar buf[tzlen], *retval;
#ifdef G_OS_WIN32
@@ -1832,7 +1780,7 @@ test_gnc_timespec2dmy (void)
t = g_date_time_to_timespec (gdt0);
gnc_timespec2dmy (t, &r_day, &r_mo, &r_yr);
- gdt_local = gncdt.to_local (gdt0);
+ gdt_local = g_date_time_to_local (gdt0);
g_date_time_get_ymd (gdt_local, &yr, &mo, &day);
g_date_time_unref (gdt_local);
g_assert_cmpint (r_day, ==, day);
@@ -1841,7 +1789,7 @@ test_gnc_timespec2dmy (void)
t = g_date_time_to_timespec (gdt1);
gnc_timespec2dmy (t, &r_day, &r_mo, &r_yr);
- gdt_local = gncdt.to_local (gdt1);
+ gdt_local = g_date_time_to_local (gdt1);
g_date_time_get_ymd (gdt_local, &yr, &mo, &day);
g_date_time_unref (gdt_local);
g_assert_cmpint (r_day, ==, day);
@@ -1850,7 +1798,7 @@ test_gnc_timespec2dmy (void)
t = g_date_time_to_timespec (gdt2);
gnc_timespec2dmy (t, &r_day, &r_mo, &r_yr);
- gdt_local = gncdt.to_local (gdt2);
+ gdt_local = g_date_time_to_local (gdt2);
g_date_time_get_ymd (gdt_local, &yr, &mo, &day);
g_date_time_unref (gdt_local);
g_assert_cmpint (r_day, ==, day);
@@ -1859,7 +1807,7 @@ test_gnc_timespec2dmy (void)
t = g_date_time_to_timespec (gdt3);
gnc_timespec2dmy (t, &r_day, &r_mo, &r_yr);
- gdt_local = gncdt.to_local (gdt3);
+ gdt_local = g_date_time_to_local (gdt3);
g_date_time_get_ymd (gdt_local, &yr, &mo, &day);
g_date_time_unref (gdt_local);
g_assert_cmpint (r_day, ==, day);
@@ -1868,7 +1816,7 @@ test_gnc_timespec2dmy (void)
t = g_date_time_to_timespec (gdt4);
gnc_timespec2dmy (t, &r_day, &r_mo, &r_yr);
- gdt_local = gncdt.to_local (gdt4);
+ gdt_local = g_date_time_to_local (gdt4);
g_date_time_get_ymd (gdt_local, &yr, &mo, &day);
g_date_time_unref (gdt_local);
g_assert_cmpint (r_day, ==, day);
@@ -1877,7 +1825,7 @@ test_gnc_timespec2dmy (void)
t = g_date_time_to_timespec (gdt5);
gnc_timespec2dmy (t, &r_day, &r_mo, &r_yr);
- gdt_local = gncdt.to_local (gdt5);
+ gdt_local = g_date_time_to_local (gdt5);
g_date_time_get_ymd (gdt_local, &yr, &mo, &day);
g_date_time_unref (gdt_local);
/* 2038 Bug */
@@ -1910,10 +1858,10 @@ gnc_dmy2timespec (int day, int month, int year)// C: 8 in 5 Local: 1:0:0
static void
test_gnc_dmy2timespec (void)
{
- GDateTime *gdt1 = gncdt.new_local (1999, 7, 21, 0, 0, 0);
- GDateTime *gdt2 = gncdt.new_local (1918, 3, 31, 0, 0, 0);
- GDateTime *gdt3 = gncdt.new_local (1918, 4, 1, 0, 0, 0);
- GDateTime *gdt4 = gncdt.new_local (2057, 11, 20, 0, 0, 0);
+ GDateTime *gdt1 = g_date_time_new_local (1999, 7, 21, 0, 0, 0);
+ GDateTime *gdt2 = g_date_time_new_local (1918, 3, 31, 0, 0, 0);
+ GDateTime *gdt3 = g_date_time_new_local (1918, 4, 1, 0, 0, 0);
+ GDateTime *gdt4 = g_date_time_new_local (2057, 11, 20, 0, 0, 0);
gint day, mon, yr;
Timespec t, r_t;
@@ -1954,10 +1902,10 @@ gnc_dmy2timespec_end (int day, int month, int year)// C: 1 Local: 0:0:0
static void
test_gnc_dmy2timespec_end (void)
{
- GDateTime *gdt1 = gncdt.new_local (1999, 7, 21,23,59, 59);
- GDateTime *gdt2 = gncdt.new_local (1918, 3, 30, 23, 59, 59);
- GDateTime *gdt3 = gncdt.new_local (1918, 3, 31, 23, 59, 59);
- GDateTime *gdt4 = gncdt.new_local (2057, 11, 20, 23, 59, 59);
+ GDateTime *gdt1 = g_date_time_new_local (1999, 7, 21,23,59, 59);
+ GDateTime *gdt2 = g_date_time_new_local (1918, 3, 30, 23, 59, 59);
+ GDateTime *gdt3 = g_date_time_new_local (1918, 3, 31, 23, 59, 59);
+ GDateTime *gdt4 = g_date_time_new_local (2057, 11, 20, 23, 59, 59);
gint day, mon, yr;
Timespec t, r_t;
@@ -2048,7 +1996,7 @@ test_timespec_to_gdate (void)
t = g_date_time_to_timespec (gdt0);
date1 = timespec_to_gdate (t);
- gdt_local = gncdt.to_local (gdt0);
+ gdt_local = g_date_time_to_local (gdt0);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
g_date_time_unref (gdt_local);
g_date_set_dmy (&date2, day, mon, yr);
@@ -2056,7 +2004,7 @@ test_timespec_to_gdate (void)
t = g_date_time_to_timespec (gdt1);
date1 = timespec_to_gdate (t);
- gdt_local = gncdt.to_local (gdt1);
+ gdt_local = g_date_time_to_local (gdt1);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
g_date_time_unref (gdt_local);
g_date_set_dmy (&date2, day, mon, yr);
@@ -2064,7 +2012,7 @@ test_timespec_to_gdate (void)
t = g_date_time_to_timespec (gdt2);
date1 = timespec_to_gdate (t);
- gdt_local = gncdt.to_local (gdt2);
+ gdt_local = g_date_time_to_local (gdt2);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
g_date_time_unref (gdt_local);
g_date_set_dmy (&date2, day, mon, yr);
@@ -2072,14 +2020,14 @@ test_timespec_to_gdate (void)
t = g_date_time_to_timespec (gdt3);
date1 = timespec_to_gdate (t);
- gdt_local = gncdt.to_local (gdt3);
+ gdt_local = g_date_time_to_local (gdt3);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
g_date_time_unref (gdt_local);
g_date_set_dmy (&date2, day, mon, yr);
g_assert_cmpint (g_date_get_julian (&date1), ==, g_date_get_julian (&date2));
t = g_date_time_to_timespec (gdt4);
date1 = timespec_to_gdate (t);
- gdt_local = gncdt.to_local (gdt4);
+ gdt_local = g_date_time_to_local (gdt4);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
g_date_time_unref (gdt_local);
g_date_set_dmy (&date2, day, mon, yr);
@@ -2087,7 +2035,7 @@ test_timespec_to_gdate (void)
t = g_date_time_to_timespec (gdt5);
date1 = timespec_to_gdate (t);
- gdt_local = gncdt.to_local (gdt5);
+ gdt_local = g_date_time_to_local (gdt5);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
g_date_time_unref (gdt_local);
g_date_set_dmy (&date2, day, mon, yr);
@@ -2110,10 +2058,10 @@ Timespec gdate_to_timespec (GDate d)// C: 7 in 6 Local: 0:0:0
static void
test_gdate_to_timespec (void)
{
- GDateTime *gdt1 = gncdt.new_local (1999, 7, 21, 0, 0, 0);
- GDateTime *gdt2 = gncdt.new_local (1918, 3, 31, 0, 0, 0);
- GDateTime *gdt3 = gncdt.new_local (1918, 4, 1, 0, 0, 0);
- GDateTime *gdt4 = gncdt.new_local (2057, 11, 20, 0, 0, 0);
+ GDateTime *gdt1 = g_date_time_new_local (1999, 7, 21, 0, 0, 0);
+ GDateTime *gdt2 = g_date_time_new_local (1918, 3, 31, 0, 0, 0);
+ GDateTime *gdt3 = g_date_time_new_local (1918, 4, 1, 0, 0, 0);
+ GDateTime *gdt4 = g_date_time_new_local (2057, 11, 20, 0, 0, 0);
gint day, mon, yr;
Timespec t, r_t;
@@ -2191,51 +2139,51 @@ test_gnc_time64_get_day_start (void)
gint day, mon, yr;
time64 time, t_time, r_time;
- gdt_local = gncdt.to_local (gdt0);
+ gdt_local = g_date_time_to_local (gdt0);
time = g_date_time_to_unix (gdt0);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_begin = gncdt.new_local (yr, mon, day, 0, 0, 0);
+ gdt_day_begin = g_date_time_new_local (yr, mon, day, 0, 0, 0);
t_time = g_date_time_to_unix (gdt_day_begin);
r_time = gnc_time64_get_day_start (time);
/* This will work in the half of the world where localtime is later than UTC */
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = gncdt.to_local (gdt1);
+ gdt_local = g_date_time_to_local (gdt1);
time = g_date_time_to_unix (gdt1);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_begin = gncdt.new_local (yr, mon, day, 0, 0, 0);
+ gdt_day_begin = g_date_time_new_local (yr, mon, day, 0, 0, 0);
t_time = g_date_time_to_unix (gdt_day_begin);
r_time = gnc_time64_get_day_start (time);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = gncdt.to_local (gdt2);
+ gdt_local = g_date_time_to_local (gdt2);
time = g_date_time_to_unix (gdt2);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_begin = gncdt.new_local (yr, mon, day, 0, 0, 0);
+ gdt_day_begin = g_date_time_new_local (yr, mon, day, 0, 0, 0);
t_time = g_date_time_to_unix (gdt_day_begin);
r_time = gnc_time64_get_day_start (time);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = gncdt.to_local (gdt3);
+ gdt_local = g_date_time_to_local (gdt3);
time = g_date_time_to_unix (gdt3);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_begin = gncdt.new_local (yr, mon, day, 0, 0, 0);
+ gdt_day_begin = g_date_time_new_local (yr, mon, day, 0, 0, 0);
t_time = g_date_time_to_unix (gdt_day_begin);
r_time = gnc_time64_get_day_start (time);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = gncdt.to_local (gdt4);
+ gdt_local = g_date_time_to_local (gdt4);
time = g_date_time_to_unix (gdt4);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_begin = gncdt.new_local (yr, mon, day, 0, 0, 0);
+ gdt_day_begin = g_date_time_new_local (yr, mon, day, 0, 0, 0);
t_time = g_date_time_to_unix (gdt_day_begin);
r_time = gnc_time64_get_day_start (time);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = gncdt.to_local (gdt5);
+ gdt_local = g_date_time_to_local (gdt5);
time = g_date_time_to_unix (gdt5);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_begin = gncdt.new_local (yr, mon, day, 0, 0, 0);
+ gdt_day_begin = g_date_time_new_local (yr, mon, day, 0, 0, 0);
t_time = g_date_time_to_unix (gdt_day_begin);
r_time = gnc_time64_get_day_start (time);
g_assert_cmpint (t_time, ==, r_time);
@@ -2271,50 +2219,50 @@ test_gnc_time64_get_day_end (void)
gint day, mon, yr;
time64 time, t_time, r_time;
- gdt_local = gncdt.to_local (gdt0);
+ gdt_local = g_date_time_to_local (gdt0);
time = g_date_time_to_unix (gdt0);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_end = gncdt.new_local (yr, mon, day, 23, 59, 59);
+ gdt_day_end = g_date_time_new_local (yr, mon, day, 23, 59, 59);
t_time = g_date_time_to_unix (gdt_day_end);
r_time = gnc_time64_get_day_end (time);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = gncdt.to_local (gdt1);
+ gdt_local = g_date_time_to_local (gdt1);
time = g_date_time_to_unix (gdt1);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_end = gncdt.new_local (yr, mon, day, 23, 59, 59);
+ gdt_day_end = g_date_time_new_local (yr, mon, day, 23, 59, 59);
t_time = g_date_time_to_unix (gdt_day_end);
r_time = gnc_time64_get_day_end (time);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = gncdt.to_local (gdt2);
+ gdt_local = g_date_time_to_local (gdt2);
time = g_date_time_to_unix (gdt2);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_end = gncdt.new_local (yr, mon, day, 23, 59, 59);
+ gdt_day_end = g_date_time_new_local (yr, mon, day, 23, 59, 59);
t_time = g_date_time_to_unix (gdt_day_end);
r_time = gnc_time64_get_day_end (time);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = gncdt.to_local (gdt3);
+ gdt_local = g_date_time_to_local (gdt3);
time = g_date_time_to_unix (gdt3);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_end = gncdt.new_local (yr, mon, day, 23, 59, 59);
+ gdt_day_end = g_date_time_new_local (yr, mon, day, 23, 59, 59);
t_time = g_date_time_to_unix (gdt_day_end);
r_time = gnc_time64_get_day_end (time);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = gncdt.to_local (gdt4);
+ gdt_local = g_date_time_to_local (gdt4);
time = g_date_time_to_unix (gdt4);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_end = gncdt.new_local (yr, mon, day, 23, 59, 59);
+ gdt_day_end = g_date_time_new_local (yr, mon, day, 23, 59, 59);
t_time = g_date_time_to_unix (gdt_day_end);
r_time = gnc_time64_get_day_end (time);
g_assert_cmpint (t_time, ==, r_time);
- gdt_local = gncdt.to_local (gdt5);
+ gdt_local = g_date_time_to_local (gdt5);
time = g_date_time_to_unix (gdt5);
g_date_time_get_ymd (gdt_local, &yr, &mon, &day);
- gdt_day_end = gncdt.new_local (yr, mon, day, 23, 59, 59);
+ gdt_day_end = g_date_time_new_local (yr, mon, day, 23, 59, 59);
t_time = g_date_time_to_unix (gdt_day_end);
r_time = gnc_time64_get_day_end (time);
g_assert_cmpint (t_time, ==, r_time);
@@ -2392,9 +2340,7 @@ timespec_get_type( void )// Local: 0:0:0
void
test_suite_gnc_date (void)
{
- _gnc_date_time_init (&gncdt);
-
-
+ tz = g_time_zone_new_local();
GNC_TEST_ADD_FUNC (suitename, "gnc localtime", test_gnc_localtime);
GNC_TEST_ADD_FUNC (suitename, "gnc gmtime", test_gnc_gmtime);
GNC_TEST_ADD_FUNC (suitename, "gnc mktime", test_gnc_mktime);
@@ -2451,5 +2397,5 @@ test_suite_gnc_date (void)
// GNC_TEST_ADD_FUNC (suitename, "gnc dow abbrev", test_gnc_dow_abbrev);
// GNC_TEST_ADD_FUNC (suitename, "timespec boxed copy func", test_timespec_boxed_copy_func);
// GNC_TEST_ADD_FUNC (suitename, "timespec boxed free func", test_timespec_boxed_free_func);
-
+ g_time_zone_unref(tz);
}
commit 6c6153b5b67d0b95b4efc9e2d7036342659e732a
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Feb 7 11:29:48 2015 -0800
Replace GDateTime dependency with boost::date_time.
diff --git a/src/libqof/qof/gnc-date-p.h b/src/libqof/qof/gnc-date-p.h
index 80e064f..9c443c9 100644
--- a/src/libqof/qof/gnc-date-p.h
+++ b/src/libqof/qof/gnc-date-p.h
@@ -23,10 +23,15 @@
#ifndef __GNC_DATE_P_H__
#define __GNC_DATE_P_H__
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdint.h>
#include "gnc-date.h"
-#define NANOS_PER_SECOND 1000000000
+#define NANOS_PER_SECOND INT32_C(1000000000)
/** Convert a given date/time format from UTF-8 to an encoding suitable for the
* strftime system call.
@@ -74,4 +79,7 @@ typedef struct
Testfuncs *gnc_date_load_funcs (void);
+#ifdef __cplusplus
+}
+#endif
#endif /* __GNC_DATE_P_H__ */
diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index d67d2c3..e9bcb5d 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -25,46 +25,36 @@
\********************************************************************/
#define __EXTENSIONS__
-#ifdef __cplusplus
extern "C"
{
-#endif
#include "config.h"
#include <glib.h>
-#include <glib/gprintf.h>
-/* to be renamed qofdate.c */
-#include <ctype.h>
+#include <libintl.h>
+#include "platform.h"
+#include "qof.h"
#ifdef HAVE_LANGINFO_D_FMT
-# include <langinfo.h>
+# include <langinfo.h>
#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <glib.h>
-#include <glib/gi18n.h>
-
-#include "gnc-date-p.h"
-#include "qof.h"
-
-#ifndef HAVE_STRPTIME
-#include "strptime.h"
-#endif
-#ifndef HAVE_LOCALTIME_R
-#include "localtime_r.h"
-#endif
-#include "platform.h"
-
#ifdef G_OS_WIN32
# include <windows.h>
#endif
-#ifdef __cplusplus
}
-#endif
+
+#include "gnc-date.h"
+#include "gnc-date-p.h"
+
+#include "gnc-timezone.hpp"
+#define N_(string) string //So that xgettext will find it
+
+using Date = boost::gregorian::date;
+using Month = boost::gregorian::greg_month;
+using PTime = boost::posix_time::ptime;
+using LDT = boost::local_time::local_date_time;
+using Duration = boost::posix_time::time_duration;
+using LDTBase = boost::local_time::local_date_time_base<PTime, boost::date_time::time_zone_base<PTime, char>>;
#ifdef HAVE_LANGINFO_D_FMT
# define GNC_D_FMT (nl_langinfo (D_FMT))
@@ -101,151 +91,55 @@ static int dateCompletionBackMonths = 6;
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = QOF_MOD_ENGINE;
-/* Getting a timezone is expensive, and we do it a lot. Cache the value. */
-static GTimeZone*
-gnc_g_time_zone_new_local (void)
-{
- static GTimeZone* tz = NULL;
- if (tz)
- return tz;
- tz = g_time_zone_new_local();
- return tz;
-}
-
-static GDateTime*
-gnc_g_date_time_new_local (gint year, gint month, gint day, gint hour, gint minute, gdouble seconds)
-{
- GTimeZone *tz = gnc_g_time_zone_new_local();
- GDateTime *gdt = g_date_time_new (tz, year, month, day,
- hour, minute, seconds);
- if (!gdt)
- return gdt;
- g_date_time_unref (gdt);
-/* g_date_time_new truncates nanoseconds to microseconds. Sometimes in
- * converting (particularly when parsing from a string) the
- * nanoseconds will have lost 1/2 a femtosecond or so. Adding 1/2 a
- * nano second ensures that the truncation doesn't lose a micorsecond
- * in translation.
- */
- seconds += 5e-10;
- gdt = g_date_time_new (tz, year, month, day, hour, minute, seconds);
- return gdt;
-}
-
-static GDateTime*
-gnc_g_date_time_adjust_for_dst (GDateTime *gdt, GTimeZone *tz)
-{
- GDateTime *ngdt;
- g_return_val_if_fail (gdt != NULL, NULL);
- ngdt = g_date_time_to_timezone (gdt, tz);
- g_date_time_unref (gdt);
- gdt = g_date_time_to_timezone (ngdt, tz);
- g_date_time_unref (ngdt);
- return gdt;
-}
-
-GDateTime*
-gnc_g_date_time_new_from_unix_local (time64 time)
-{
- GTimeZone *tz = gnc_g_time_zone_new_local ();
- GDateTime *gdt = g_date_time_new_from_unix_utc (time);
- if (gdt)
- gdt = gnc_g_date_time_adjust_for_dst (gdt, tz);
- return gdt;
-}
-
-static GDateTime*
-gnc_g_date_time_new_from_timeval_local (const GTimeVal* tv)
+// Default constructor Initializes to the current locale.
+static const TimeZoneProvider tzp;
+// For converting to/from POSIX time.
+static const PTime unix_epoch (Date(1970, boost::gregorian::Jan, 1),
+ boost::posix_time::seconds(0));
+/* To ensure things aren't overly screwed up by setting the nanosecond clock for boost::date_time. Don't do it, though, it doesn't get us anything and slows down the date/time library. */
+#ifndef BOOST_DATE_TIME_HAS_NANOSECONDS
+static constexpr uint64_t ticks_per_second = UINT64_C(1000000);
+#else
+static constexpr uint64_t ticks_per_second = UINT64_C(1000000000);
+#endif
+static LDT
+gnc_get_LDT(int year, int month, int day, int hour, int minute, int seconds)
{
- GTimeZone *tz = gnc_g_time_zone_new_local ();
- GDateTime *gdt = g_date_time_new_from_timeval_utc (tv);
- if (gdt)
- gdt = gnc_g_date_time_adjust_for_dst (gdt, tz);
- return gdt;
+ Date date(year, static_cast<Month>(month), day);
+ Duration time(hour, minute, seconds);
+ auto tz = tzp.get(year);
+ return LDT(date, time, tz, LDTBase::NOT_DATE_TIME_ON_ERROR);
}
-static GDateTime*
-gnc_g_date_time_new_now_local (void)
+static LDT
+LDT_from_unix_local(const time64 time)
{
- GTimeZone *tz = gnc_g_time_zone_new_local ();
- GDateTime *gdt = g_date_time_new_now_utc ();
- if (gdt)
- gdt = gnc_g_date_time_adjust_for_dst (gdt, tz);
- return gdt;
-
+ PTime temp(unix_epoch.date(),
+ boost::posix_time::hours(time / 3600) +
+ boost::posix_time::seconds(time % 3600));
+ auto tz = tzp.get(temp.date().year());
+ return LDT(temp, tz);
}
-static GDateTime*
-gnc_g_date_time_to_local (GDateTime* gdt)
+template<typename T>
+static time64
+time64_from_date_time(T time)
{
- GTimeZone *tz = NULL;
- if (gdt)
- {
- tz = gnc_g_time_zone_new_local ();
- gdt = gnc_g_date_time_adjust_for_dst (g_date_time_to_utc (gdt), tz);
- }
- return gdt;
+ auto duration = time - unix_epoch;
+ return duration.ticks() / ticks_per_second;
}
-typedef struct
-{
- GDateTime *(*new_local)(gint, gint, gint, gint, gint, gdouble);
- GDateTime *(*adjust_for_dst)(GDateTime *, GTimeZone *);
- GDateTime *(*new_from_unix_local)(time64);
- GDateTime *(*new_from_timeval_local)(const GTimeVal *);
- GDateTime *(*new_now_local)(void);
- GDateTime *(*to_local)(GDateTime *);
-} _GncDateTime;
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-void _gnc_date_time_init(_GncDateTime*);
-void
-_gnc_date_time_init (_GncDateTime *gncdt)
-{
- gncdt->new_local = gnc_g_date_time_new_local;
- gncdt->adjust_for_dst = gnc_g_date_time_adjust_for_dst;
- gncdt->new_from_unix_local = gnc_g_date_time_new_from_unix_local;
- gncdt->new_from_timeval_local = gnc_g_date_time_new_from_timeval_local;
- gncdt->new_now_local = gnc_g_date_time_new_now_local;
- gncdt->to_local = gnc_g_date_time_to_local;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
/****************** Posix Replacement Functions ***************************/
void
gnc_tm_free (struct tm* time)
{
- g_slice_free1 (sizeof (struct tm), time);
-}
-
-#define MAX_TZ_SIZE
-static void
-gnc_g_date_time_fill_struct_tm (GDateTime *gdt, struct tm* time)
-{
- memset (time, 0, sizeof (struct tm));
- g_date_time_get_ymd (gdt, &(time->tm_year), &(time->tm_mon), &(time->tm_mday));
- time->tm_sec = g_date_time_get_second (gdt);
- time->tm_min = g_date_time_get_minute (gdt);
- time->tm_hour = g_date_time_get_hour (gdt);
- // Watch out: struct tm has wday=0..6 with Sunday=0, but GDateTime has wday=1..7 with Sunday=7.
- time->tm_wday = g_date_time_get_day_of_week (gdt) % 7;
- time->tm_yday = g_date_time_get_day_of_year (gdt);
- time->tm_isdst = g_date_time_is_daylight_savings (gdt);
- time->tm_year -= 1900;
- --time->tm_mon;
+ free(time);
}
struct tm*
gnc_localtime (const time64 *secs)
{
- struct tm *time = static_cast<struct tm*>(g_slice_alloc0 (sizeof (struct tm)));
+ auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm)));
if (gnc_localtime_r (secs, time) == NULL)
{
gnc_tm_free (time);
@@ -254,39 +148,41 @@ gnc_localtime (const time64 *secs)
return time;
}
-/* Linux, Darwin, and MSWindows implementations of this function set the
- * globals timezone and daylight; BSD doesn't have those globals, and
- * Gnucash never uses them, so they're omitted from this
- * implementation. Bug 704185.
- */
struct tm*
gnc_localtime_r (const time64 *secs, struct tm* time)
{
- GDateTime *gdt = gnc_g_date_time_new_from_unix_local (*secs);
- g_return_val_if_fail (gdt != NULL, NULL);
-
- gnc_g_date_time_fill_struct_tm (gdt, time);
- if (g_date_time_is_daylight_savings (gdt))
- time->tm_isdst = 1;
-
+ try
+ {
+ auto ldt = LDT_from_unix_local(*secs);
+ *time = boost::local_time::to_tm(ldt);
#ifdef HAVE_STRUCT_TM_GMTOFF
- time->tm_gmtoff = g_date_time_get_utc_offset (gdt) / G_TIME_SPAN_SECOND;
+ auto offset = ldt.zone()->base_utc_offset();
+ if (ldt.is_dst())
+ offset += ldt.zone()->dst_offset();
+ time->tm_gmtoff = offset.total_seconds();
#endif
-
- g_date_time_unref (gdt);
- return time;
+ }
+ catch(boost::gregorian::bad_year)
+ {
+ return NULL; //Yeah, it should be nullptr, but this is a C-linkage func.
+ }
+ return time;
}
struct tm*
gnc_gmtime (const time64 *secs)
{
- struct tm *time;
- GDateTime *gdt = g_date_time_new_from_unix_utc (*secs);
- g_return_val_if_fail (gdt != NULL, NULL);
- time = static_cast<struct tm*>(g_slice_alloc0 (sizeof (struct tm)));
- gnc_g_date_time_fill_struct_tm (gdt, time);
- g_date_time_unref (gdt);
- return time;
+ auto time = static_cast<struct tm*>(calloc(1, sizeof (struct tm)));
+ try {
+ PTime pdt(unix_epoch.date(), boost::posix_time::hours(*secs / 3600) +
+ boost::posix_time::seconds(*secs % 3600));
+ *time = boost::posix_time::to_tm(pdt);
+ }
+ catch(boost::gregorian::bad_year)
+ {
+ return NULL; //Yeah, it should be nullptr, but this is a C-linkage func.
+ }
+ return time;
}
static void
@@ -318,10 +214,10 @@ normalize_struct_tm (struct tm* time)
gint last_day;
++time->tm_mon;
- /* GDateTime doesn't protect itself against out-of range years,
- * so clamp year into GDateTime's range.
+ /* Gregorian_date throws if it gets an out-of-range year
+ * so clamp year into gregorian_date's range.
*/
- if (year < 0) year = -year;
+ if (year < 1400) year += 1400;
if (year > 9999) year %= 10000;
normalize_time_component (&(time->tm_sec), &(time->tm_min), 60, 0);
@@ -348,68 +244,30 @@ normalize_struct_tm (struct tm* time)
time64
gnc_mktime (struct tm* time)
{
- GDateTime *gdt;
- time64 secs;
- normalize_struct_tm (time);
- gdt = gnc_g_date_time_new_local (time->tm_year + 1900, time->tm_mon,
- time->tm_mday, time->tm_hour,
- time->tm_min, (gdouble)(time->tm_sec));
- if (gdt == NULL)
- {
- g_warning("Invalid time passed to gnc_mktime");
- return -1;
- }
- time->tm_mon = time->tm_mon > 0 ? time->tm_mon - 1 : 11;
- // Watch out: struct tm has wday=0..6 with Sunday=0, but GDateTime has wday=1..7 with Sunday=7.
- time->tm_wday = g_date_time_get_day_of_week (gdt) % 7;
- time->tm_yday = g_date_time_get_day_of_year (gdt);
- time->tm_isdst = g_date_time_is_daylight_savings (gdt);
-
-#ifdef HAVE_STRUCT_TM_GMTOFF
- time->tm_gmtoff = g_date_time_get_utc_offset (gdt) / G_TIME_SPAN_SECOND;
-#endif
-
- secs = g_date_time_to_unix (gdt);
- g_date_time_unref (gdt);
- return secs;
+ normalize_struct_tm (time);
+ return time64_from_date_time(boost::posix_time::ptime_from_tm(*time));
}
time64
gnc_timegm (struct tm* time)
{
- GDateTime *gdt;
- time64 secs;
- normalize_struct_tm (time);
- gdt = g_date_time_new_utc (time->tm_year + 1900, time->tm_mon,
- time->tm_mday, time->tm_hour, time->tm_min,
- (gdouble)(time->tm_sec));
- time->tm_mon = time->tm_mon > 0 ? time->tm_mon - 1 : 11;
- // Watch out: struct tm has wday=0..6 with Sunday=0, but GDateTime has wday=1..7 with Sunday=7.
- time->tm_wday = g_date_time_get_day_of_week (gdt) % 7;
- time->tm_yday = g_date_time_get_day_of_year (gdt);
- time->tm_isdst = g_date_time_is_daylight_savings (gdt);
-
- secs = g_date_time_to_unix (gdt);
- g_date_time_unref (gdt);
- return secs;
+ auto newtime = *time;
+ newtime.tm_gmtoff = 0;
+ return gnc_mktime(&newtime);
}
-gchar*
+char*
gnc_ctime (const time64 *secs)
{
- GDateTime *gdt = gnc_g_date_time_new_from_unix_local (*secs);
- gchar *string = g_date_time_format (gdt, "%a %b %e %H:%M:%S %Y");
- g_date_time_unref (gdt);
- return string;
+ return gnc_print_time64(*secs, "%a %b %e %H:%M:%S %Y");
}
time64
gnc_time (time64 *tbuf)
{
- GDateTime *gdt = gnc_g_date_time_new_now_local ();
- time64 secs = g_date_time_to_unix (gdt);
- g_date_time_unref (gdt);
- if (tbuf != NULL)
+ auto pdt = boost::posix_time::second_clock::local_time();
+ auto secs = time64_from_date_time(pdt);
+ if (tbuf != nullptr)
*tbuf = secs;
return secs;
}
@@ -417,9 +275,8 @@ gnc_time (time64 *tbuf)
time64
gnc_time_utc (time64 *tbuf)
{
- GDateTime *gdt = g_date_time_new_now_utc ();
- time64 secs = g_date_time_to_unix (gdt);
- g_date_time_unref (gdt);
+ auto pdt = boost::posix_time::second_clock::universal_time();
+ auto secs = time64_from_date_time(pdt);
if (tbuf != NULL)
*tbuf = secs;
return secs;
@@ -434,17 +291,6 @@ gnc_difftime (const time64 secs1, const time64 secs2)
/****************************************************************************/
-GDateTime*
-gnc_g_date_time_new_from_timespec_local (Timespec ts)
-{
- GDateTime *gdt1 = gnc_g_date_time_new_from_unix_local (ts.tv_sec);
- double nsecs = ((double)ts.tv_nsec + 0.5)/ 1000000000.0L;
- GDateTime *gdt2 = g_date_time_add_seconds (gdt1, nsecs);
- g_date_time_unref (gdt1);
- g_assert (g_date_time_to_unix (gdt2) == ts.tv_sec + (nsecs >= 1.0 ? (gint64)nsecs : 0));
- return gdt2;
-}
-
const char*
gnc_date_dateformat_to_string(QofDateFormat format)
{
@@ -530,6 +376,24 @@ gnc_date_string_to_monthformat(const char *fmt_str, GNCDateMonthFormat *format)
return FALSE;
}
+char*
+gnc_print_time64(time64 time, const char* format)
+{
+ using Facet = boost::local_time::local_time_facet;
+ auto date_time = LDT_from_unix_local(time);
+ 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 << date_time;
+ auto sstr = ss.str();
+ //ugly C allocation so that the ptr can be freed at the other end
+ char* cstr = static_cast<char*>(malloc(sstr.length() + 1));
+ memset(cstr, 0, sstr.length() + 1);
+ strncpy(cstr, sstr.c_str(), sstr.length());
+ return cstr;
+}
+
/********************************************************************\
\********************************************************************/
@@ -1412,10 +1276,7 @@ qof_strftime(gchar *buf, gsize max, const gchar *format, const struct tm *tm)
gchar *
gnc_date_timestamp (void)
{
- GDateTime *gdt = gnc_g_date_time_new_now_local ();
- gchar *timestr = g_date_time_format (gdt, "%Y%m%d%H%M%S");
- g_date_time_unref (gdt);
- return timestr;
+ return gnc_print_time64(gnc_time(nullptr), "%Y-%M-%d %H:%M%S");
}
/********************************************************************\
@@ -1429,38 +1290,9 @@ gnc_date_timestamp (void)
Timespec
gnc_iso8601_to_timespec_gmt(const char *str)
{
- Timespec time = { 0L, 0L };
- GDateTime *gdt;
- gint hour = 0, minute = 0, day = 0, month = 0, year = 0;
- gchar zone[12];
- gdouble second = 0.0;
- gint fields;
-
- memset (zone, 0, sizeof (zone));
-
- if (!str)
- return time;
-
- fields = sscanf (str, ISO_DATE_FORMAT, &year, &month,
- &day, &hour, &minute, &second, zone);
- if (fields < 1)
- return time;
- else if (fields > 6 && strlen (zone) > 0) /* Date string included a timezone */
- {
- GTimeZone *tz = g_time_zone_new (zone);
- second += 5e-10;
- gdt = g_date_time_new (tz, year, month, day, hour, minute, second);
- }
- else /* No zone info, assume UTC */
- {
- second += 5e-10;
- gdt = g_date_time_new_utc (year, month, day, hour, minute, second);
- }
-
- time.tv_sec = g_date_time_to_unix (gdt);
- time.tv_nsec = g_date_time_get_microsecond (gdt) * 1000;
- g_date_time_unref (gdt);
- return time;
+ auto pdt = boost::posix_time::time_from_string(str);
+ auto time = time64_from_date_time(pdt);
+ return {time, 0};
}
/********************************************************************\
@@ -1469,28 +1301,20 @@ gnc_iso8601_to_timespec_gmt(const char *str)
char *
gnc_timespec_to_iso8601_buff (Timespec ts, char * buff)
{
- const gchar *fmt1 = "%Y-%m-%d %H:%M", *fmt2 = "%s:%02d.%06d %s";
- GDateTime *gdt;
- gchar *time_base, *tz;
+ constexpr size_t max_iso_date_length = 32;
+ std::string fmt1 = "%Y-%m-%d %H:%M";
g_return_val_if_fail (buff != NULL, NULL);
- gdt = gnc_g_date_time_new_from_timespec_local (ts);
- g_return_val_if_fail (gdt != NULL, NULL);
- time_base = g_date_time_format (gdt, fmt1);
+
#ifdef G_OS_WIN32
- tz = g_date_time_format (gdt, "%Z");
+ fmt1 += "%Z";
#else
- tz = g_date_time_format (gdt, "%z");
+ fmt1 += "%z";
#endif
- snprintf (buff, MAX_DATE_LENGTH, fmt2, time_base,
- g_date_time_get_second (gdt), g_date_time_get_microsecond (gdt),
- tz);
-
- g_free (time_base);
- g_free (tz);
- g_date_time_unref (gdt);
+ char* str = gnc_print_time64(ts.tv_sec, fmt1.c_str());
+ strncpy (buff, str, max_iso_date_length);
+ free(str);
return buff + strlen (buff);
-
}
void
@@ -1614,16 +1438,13 @@ GDate timespec_to_gdate (Timespec ts)
GDate* gnc_g_date_new_today ()
{
- GDateTime *gdt = gnc_g_date_time_new_now_local ();
- gint day, month, year;
- GDate *result;
- g_date_time_get_ymd (gdt, &year, &month, &day);
- result = g_date_new_dmy (day, static_cast<GDateMonth>(month), year);
- g_date_time_unref (gdt);
- g_assert(g_date_valid (result));
-
- return result;
+ auto pdt = boost::posix_time::second_clock::local_time();
+ auto ymd = pdt.date().year_month_day();
+ auto month = static_cast<GDateMonth>(ymd.month.as_number());
+ auto result = g_date_new_dmy (ymd.day, month, ymd.year);
+ g_assert(g_date_valid (result));
+ return result;
}
Timespec gdate_to_timespec (GDate d)
diff --git a/src/libqof/qof/gnc-date.h b/src/libqof/qof/gnc-date.h
index 3f5f27c..c25371a 100644
--- a/src/libqof/qof/gnc-date.h
+++ b/src/libqof/qof/gnc-date.h
@@ -238,12 +238,6 @@ time64 gnc_time_utc (time64 *tbuf);
*/
gdouble gnc_difftime (const time64 secs1, const time64 secs2);
-/** Wrapper for g_date_time_new_from_unix_local() that takes special care on
- * windows to take the local timezone into account. On unix, it just calles the
- * g_date function. */
-GDateTime*
-gnc_g_date_time_new_from_unix_local (time64 time);
-
/** \brief free a struct tm* created with gnc_localtime() or gnc_gmtime()
* \param time: The struct tm* to be freed.
*/
@@ -280,6 +274,19 @@ Note the reversed return values!
*/
gboolean gnc_date_string_to_monthformat(const gchar *format_string,
GNCDateMonthFormat *format);
+
+/** \brief print a time64 as a date string per format
+ * \param time
+ * \param format A date format conforming to the strftime format rules.
+ * \return a raw heap-allocated char* which must be freed.
+ */
+char* gnc_print_time64(time64 time, const char* format);
+
+/** Returns a newly allocated date of the current clock time, taken from
+ * time(2). The caller must g_date_free() the object afterwards. */
+GDate* gnc_g_date_new_today (void);
+
+
// @}
/* Datatypes *******************************************************/
@@ -338,10 +345,6 @@ void timespecFromTime64 (Timespec *ts, time64 t );
/** Turns a Timespec into a time64 */
time64 timespecToTime64 (Timespec ts);
-/** Returns a newly allocated date of the current clock time, taken from
- * time(2). The caller must g_date_free() the object afterwards. */
-GDate* gnc_g_date_new_today (void);
-
/** Turns a Timespec into a GDate */
GDate timespec_to_gdate (Timespec ts);
commit 6673128b9f643df888bb97e6a3f8fea6cc3b39b6
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Feb 7 11:27:57 2015 -0800
Rewrite gnc_gdate_set_time64 to not depend upon GDateTime.
diff --git a/src/backend/xml/sixtp-dom-generators.c b/src/backend/xml/sixtp-dom-generators.c
index 6217697..48311ef 100644
--- a/src/backend/xml/sixtp-dom-generators.c
+++ b/src/backend/xml/sixtp-dom-generators.c
@@ -131,17 +131,10 @@ commodity_ref_to_dom_tree(const char *tag, const gnc_commodity *c)
* but we want to serialize it un-normalized, so we make a partial
* copy.
*/
-gchar *
+char *
timespec_sec_to_string(const Timespec *ts)
{
- gchar *time_string;
- GDateTime *gdt;
- Timespec sts = { ts->tv_sec, 0};
- gdt = gnc_g_date_time_new_from_timespec_local (sts);
- g_return_val_if_fail (gdt != NULL, NULL);
- time_string = g_date_time_format (gdt, "%Y-%m-%d %H:%M:%S %z");
- g_date_time_unref (gdt);
- return time_string;
+ return gnc_print_time64(ts->tv_sec, "%Y-%m-%d %H:%M:%S %z");
}
gchar *
diff --git a/src/core-utils/gnc-gdate-utils.c b/src/core-utils/gnc-gdate-utils.c
index 059275a..ae415fd 100644
--- a/src/core-utils/gnc-gdate-utils.c
+++ b/src/core-utils/gnc-gdate-utils.c
@@ -37,11 +37,10 @@ gnc_gdate_set_today (GDate* gd)
void
gnc_gdate_set_time64 (GDate* gd, time64 time)
{
- GDateTime *gdt = gnc_g_date_time_new_from_unix_local (time);
- gint y, m, d;
- g_date_time_get_ymd (gdt, &y, &m, &d);
- g_date_set_dmy (gd, d, m, y);
- g_date_time_unref (gdt);
+ struct tm tm;
+ gnc_localtime_r(&time, &tm);
+ g_date_set_dmy (gd, tm.tm_mday, tm.tm_mon, tm.tm_year + 1900);
+
}
gboolean
diff --git a/src/gnome-utils/gnc-main-window.c b/src/gnome-utils/gnc-main-window.c
index e17b56c..e028e78 100644
--- a/src/gnome-utils/gnc-main-window.c
+++ b/src/gnome-utils/gnc-main-window.c
@@ -1653,10 +1653,6 @@ static gchar *generate_statusbar_lastmodified_message()
int r = stat(filepath, &statbuf);
if (r == 0)
{
- // File mtime could be accessed ok
- gint64 mtime = statbuf.st_mtime;
- GDateTime *gdt = gnc_g_date_time_new_from_unix_local (mtime);
- gchar *dummy_strftime_has_ampm = g_date_time_format (gdt, "%P");
/* Translators: This is the date and time that is shown in
the status bar after opening a file: The date and time of
last modification. The string is the format string for
@@ -1664,20 +1660,14 @@ static gchar *generate_statusbar_lastmodified_message()
explanation of the modifiers. First string is for a locale
that has the a.m. or p.m. string in its locale, second
string is for locales that do not have that string. */
- gchar *time_string =
- g_date_time_format (gdt, (dummy_strftime_has_ampm &&
- strlen(dummy_strftime_has_ampm) > 0)
- ? _("Last modified on %a, %b %e, %Y at %I:%M%P")
- : _("Last modified on %x %X"));
-
- g_date_time_unref (gdt);
-
+ char *time_string =
+ gnc_print_time64(statbuf.st_mtime,
+ _("Last modified on %a, %b %e, %Y at %I:%M%P"));
//g_warning("got time %ld, str=%s\n", mtime, time_string);
/* Translators: This message appears in the status bar after opening the file. */
message = g_strdup_printf(_("File %s opened. %s"),
filename, time_string);
- g_free(time_string);
- g_free(dummy_strftime_has_ampm);
+ free(time_string);
}
else
{
commit 19f64ad3951c7ebe0260d876aaba2ee4e1fa1218
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Jan 31 15:02:21 2015 -0800
Restore GLIB_CFLAGS to test_kvp_value, required for GVALUE stuff.
diff --git a/src/libqof/qof/test/Makefile.am b/src/libqof/qof/test/Makefile.am
index 6738fe1..15ed8fc 100644
--- a/src/libqof/qof/test/Makefile.am
+++ b/src/libqof/qof/test/Makefile.am
@@ -52,6 +52,7 @@ endif
test_kvp_value_CPPFLAGS = \
-I$(GTEST_HEADERS) \
-I$(top_srcdir)/$(MODULEPATH) \
+ $(GLIB_CFLAGS) \
$(BOOST_CPPFLAGS)
check_PROGRAMS += test-kvp-value
commit 2061026f2101f0c78728c5505b1a484d026f2806
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Jan 31 15:00:57 2015 -0800
Make TimeZoneProvider::get const noexcept.
diff --git a/src/libqof/qof/gnc-timezone.cpp b/src/libqof/qof/gnc-timezone.cpp
index e720f26..077291f 100644
--- a/src/libqof/qof/gnc-timezone.cpp
+++ b/src/libqof/qof/gnc-timezone.cpp
@@ -598,7 +598,7 @@ TimeZoneProvider::TimeZoneProvider(const std::string& tzname) : zone_vector {}
TZ_Ptr
-TimeZoneProvider::get(int year)
+TimeZoneProvider::get(int year) const noexcept
{
auto iter = find_if(zone_vector.begin(), zone_vector.end(),
[=](TZ_Entry e) { return e.first >= year; });
diff --git a/src/libqof/qof/gnc-timezone.hpp b/src/libqof/qof/gnc-timezone.hpp
index 400f0c9..9988b87 100644
--- a/src/libqof/qof/gnc-timezone.hpp
+++ b/src/libqof/qof/gnc-timezone.hpp
@@ -54,7 +54,7 @@ public:
TimeZoneProvider(const TimeZoneProvider&&) = delete;
TimeZoneProvider operator=(const TimeZoneProvider&) = delete;
TimeZoneProvider operator=(const TimeZoneProvider&&) = delete;
- TZ_Ptr get (int year);
+ TZ_Ptr get (int year) const noexcept;
private:
TZ_Vector zone_vector;
#if PLATFORM(WINDOWS)
commit d98ddd12a7d7d6ed8a7e9b7a26a3e06f54336f49
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Jan 27 16:05:00 2015 -0800
Implement TimezoneProvider for POSIX.
diff --git a/src/libqof/qof/gnc-timezone.cpp b/src/libqof/qof/gnc-timezone.cpp
index c35973a..e720f26 100644
--- a/src/libqof/qof/gnc-timezone.cpp
+++ b/src/libqof/qof/gnc-timezone.cpp
@@ -24,7 +24,8 @@
#include <string>
#include <cstdint>
-#include <ostream>
+#include <istream>
+#include <algorithm>
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace gnc::date;
@@ -33,6 +34,17 @@ using time_zone = boost::local_time::custom_time_zone;
using dst_offsets = boost::local_time::dst_adjustment_offsets;
using calc_rule_ptr = boost::local_time::dst_calc_rule_ptr;
+template<typename T>
+T*
+endian_swap(T* t)
+{
+#if ! WORDS_BIGENDIAN
+ auto memp = reinterpret_cast<unsigned char*>(t);
+ std::reverse(memp, memp + sizeof(T));
+#endif
+ return t;
+}
+
#if PLATFORM(WINDOWS)
/* libstdc++ to_string is broken on MinGW with no real interest in fixing it.
* See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52015
@@ -271,7 +283,7 @@ namespace IANAParser
struct TTInfo
{
- uint32_t gmtoff;
+ int32_t gmtoff;
uint8_t isdst;
uint8_t abbrind;
};
@@ -290,135 +302,139 @@ namespace IANAParser
uint8_t index;
};
- static std::ifstream
+ static std::unique_ptr<char[]>
find_tz_file(const std::string& name)
{
+ std::ifstream ifs;
if (name.empty())
- return std::ifstream("/etc/localtime", std::ios::binary);
-
- std::string tzname = name;
+ {
+ ifs.open("/etc/localtime",
+ std::ios::in|std::ios::binary|std::ios::ate);
+ }
+ else
+ {
+ std::string tzname = name;
//POSIX specifies that that identifier should begin with ':', but we
//should be liberal. If it's there, it's not part of the filename.
- if (tzname[0] == ':')
- tzname.erase(tzname.begin());
- if (tzname[0] == '/') //Absolute filename
- return std::ifstream(tzname, std::ios::binary);
-
- std::string tzdir = std::getenv("TZDIR");
- if (tzdir.empty())
- tzdir = "/usr/share/zoneinfo";
+ if (tzname[0] == ':')
+ tzname.erase(tzname.begin());
+ if (tzname[0] == '/') //Absolute filename
+ {
+ ifs.open(tzname, std::ios::in|std::ios::binary|std::ios::ate);
+ }
+ else
+ {
+ const char* tzdir_c = std::getenv("TZDIR");
+ std::string tzdir = tzdir_c ? tzdir_c : "/usr/share/zoneinfo";
//Note that we're not checking the filename.
- return std::ifstream(std::move(tzdir + "/" + tzname), std::ios::binary);
+ ifs.open(std::move(tzdir + "/" + tzname),
+ std::ios::in|std::ios::binary|std::ios::ate);
+ }
+ }
+ if (! ifs.is_open())
+ throw std::invalid_argument("The timezone string failed to resolve to a valid filename");
+ std::streampos filesize = ifs.tellg();
+ std::unique_ptr<char[]>fileblock(new char[filesize]);
+ ifs.seekg(0, std::ios::beg);
+ ifs.read(fileblock.get(), filesize);
+ ifs.close();
+ return fileblock;
}
- struct IANAParser
+ using TZInfoVec = std::vector<TZInfo>;
+ using TZInfoIter = TZInfoVec::iterator;
+
+ struct IANAParser
{
IANAParser(const std::string& name) : IANAParser(find_tz_file(name)) {}
- IANAParser(std::ifstream ifs);
+ IANAParser(std::unique_ptr<char[]>);
std::vector<Transition>transitions;
- std::vector<TZInfo>tzinfo;
+ TZInfoVec tzinfo;
int last_year;
};
- IANAParser::IANAParser(std::ifstream ifs)
+ IANAParser::IANAParser(std::unique_ptr<char[]>fileblock)
{
- if (! ifs)
- throw std::invalid_argument("The timezone string failed to resolve to a valid filename");
-
- TZHead tzh;
- auto timesize = sizeof(int32_t);
+ unsigned int fb_index = 0;
+ TZHead tzh = *reinterpret_cast<TZHead*>(&fileblock[fb_index]);
last_year = 2037; //Constrained by 32-bit time_t.
- ifs.get(reinterpret_cast<char*>(&tzh), sizeof(tzh));
- auto time_count = *reinterpret_cast<uint32_t*>(tzh.timecnt);
- auto type_count = *reinterpret_cast<uint32_t*>(tzh.typecnt);
- auto char_count = *reinterpret_cast<uint32_t*>(tzh.charcnt);
- auto isgmt_count = *reinterpret_cast<uint32_t*>(tzh.ttisgmtcnt);
- auto isstd_count = *reinterpret_cast<uint32_t*>(tzh.ttisstdcnt);
- auto leap_count = *reinterpret_cast<uint32_t*>(tzh.leapcnt);
+
+ auto time_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.timecnt)));
+ auto type_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.typecnt)));
+ auto char_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.charcnt)));
+ auto isgmt_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.ttisgmtcnt)));
+ auto isstd_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.ttisstdcnt)));
+ auto leap_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.leapcnt)));
if (tzh.version == '2' && sizeof(time_t) == sizeof(int64_t))
{
- ifs.seekg(sizeof(tzh) +
- timesize + sizeof(uint8_t) * time_count +
- sizeof(TTInfo) * type_count +
- sizeof(char) * char_count +
- sizeof(uint8_t) * isgmt_count +
- sizeof(uint8_t) * isstd_count +
- 2 * timesize * leap_count +
- sizeof(tzh));
- timesize = sizeof(int64_t);
- //This might change at some point in the probably very distant future.
+ fb_index = (sizeof(tzh) +
+ sizeof(time_t) + sizeof(uint8_t) * time_count +
+ sizeof(TTInfo) * type_count +
+ sizeof(char) * char_count +
+ sizeof(uint8_t) * isgmt_count +
+ sizeof(uint8_t) * isstd_count +
+ 2 * sizeof(time_t) * leap_count);
+
+ //This might change at some point in the probably very
+ //distant future.
+ tzh = *reinterpret_cast<TZHead*>(&fileblock[fb_index]);
last_year = 2499;
+ time_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.timecnt)));
+ type_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.typecnt)));
+ char_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.charcnt)));
+ isgmt_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.ttisgmtcnt)));
+ isstd_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.ttisstdcnt)));
+ leap_count = *(endian_swap(reinterpret_cast<uint32_t*>(tzh.leapcnt)));
}
-
+ fb_index += sizeof(tzh);
+
transitions.reserve(time_count);
tzinfo.reserve(type_count);
-
- for(auto tr : transitions)
- {
- uint8_t time[sizeof(time_t)];
- ifs.get(reinterpret_cast<char*>(time), timesize);
- tr.timestamp = *reinterpret_cast<time_t*>(time);
- }
-
- for (auto tr : transitions)
+ auto start_index = fb_index;
+ auto info_index_zero = start_index + time_count * sizeof(time_t);
+ for(auto index = 0; index < time_count; ++index)
{
- char idx;
- ifs.get(idx);
- tr.index = std::move(idx);
+ fb_index = start_index + index * sizeof(time_t);
+ auto info_index = info_index_zero + index;
+ transitions.push_back(
+ {*(endian_swap(reinterpret_cast<time_t*>(&fileblock[fb_index]))),
+ static_cast<uint8_t>(fileblock[info_index])});
}
- for(auto tz : tzinfo)
- {
- char infochars[sizeof(TTInfo)];
- ifs.get(infochars, sizeof(TTInfo));
- tz.info = *reinterpret_cast<TTInfo*>(infochars);
- }
-
- try
- {
- std::unique_ptr<char[]>abbrev(new char[char_count]);
- ifs.get(abbrev.get(), char_count);
-
- for (auto tz : tzinfo)
- {
- tz.name = abbrev[tz.info.abbrind];
- }
- }
- catch(std::bad_alloc)
+ //Add in the tzinfo indexes consumed in the previous loop
+ start_index = info_index_zero + time_count;
+ //Can't use sizeof(TZInfo) because it's padded out to 8 bytes.
+ static const size_t tzinfo_size = 6;
+ auto abbrev = start_index + type_count * tzinfo_size;
+ auto std_dist = abbrev + char_count;
+ auto gmt_dist = std_dist + type_count;
+ for(auto index = 0; index < type_count; ++index)
{
- ;
+ fb_index = start_index + index * tzinfo_size;
+ TTInfo info = *reinterpret_cast<TTInfo*>(&fileblock[fb_index]);
+ endian_swap(&info.gmtoff);
+ tzinfo.push_back(
+ {info, &fileblock[abbrev + info.abbrind],
+ fileblock[std_dist + index] != '\0',
+ fileblock[gmt_dist + index] != '\0'});
}
- if (isstd_count == type_count)
- {
- char foo;
- for (auto tz : tzinfo)
- {
- ifs.get(foo);
- tz.isstd = foo != '\0';
- }
- for (auto tz : tzinfo)
- {
- ifs.get(foo);
- tz.isgmt = foo != '\0';
- }
- }
}
}
namespace DSTRule
{
using gregorian_date = boost::gregorian::date;
- using IANAParser::TZInfo;
+ using IANAParser::TZInfoIter;
using ndate = boost::gregorian::nth_day_of_the_week_in_month;
using week_num =
boost::date_time::nth_kday_of_month<boost::gregorian::date>::week_num;
struct Transition
{
- Transition() : month(0), dow(0), week(static_cast<week_num>(0)) {}
+ Transition() : month(1), dow(0), week(static_cast<week_num>(0)) {}
Transition(gregorian_date date);
- bool operator==(const Transition& rhs);
+ bool operator==(const Transition& rhs) const noexcept;
ndate get();
boost::gregorian::greg_month month;
boost::gregorian::greg_weekday dow;
@@ -431,7 +447,7 @@ namespace DSTRule
{}
bool
- Transition::operator==(const Transition& rhs)
+ Transition::operator==(const Transition& rhs) const noexcept
{
return (month == rhs.month && dow == rhs.dow && week == rhs.week);
}
@@ -445,7 +461,7 @@ namespace DSTRule
struct DSTRule
{
DSTRule();
- DSTRule(const TZInfo& info1, const TZInfo& info2,
+ DSTRule(TZInfoIter info1, TZInfoIter info2,
ptime date1, ptime date2);
bool operator==(const DSTRule& rhs) const noexcept;
bool operator!=(const DSTRule& rhs) const noexcept;
@@ -453,29 +469,31 @@ namespace DSTRule
Transition to_dst;
duration to_std_time;
duration to_dst_time;
- const TZInfo& std_info;
- const TZInfo& dst_info;
+ TZInfoIter std_info;
+ TZInfoIter dst_info;
};
DSTRule::DSTRule() : to_std(), to_dst(), to_std_time {}, to_dst_time {},
std_info (), dst_info () {};
- DSTRule::DSTRule (const TZInfo& info1, const TZInfo& info2,
+ DSTRule::DSTRule (TZInfoIter info1, TZInfoIter info2,
ptime date1, ptime date2) :
to_std(date1.date()), to_dst(date2.date()),
to_std_time(date1.time_of_day()), to_dst_time(date2.time_of_day()),
std_info(info1), dst_info(info2)
{
- if (info1.info.isdst == info2.info.isdst)
+ if (info1->info.isdst == info2->info.isdst)
throw(std::invalid_argument("Both infos have the same dst value."));
- if (info1.info.isdst && !info2.info.isdst)
+ if (info1->info.isdst && !info2->info.isdst)
{
std::swap(to_std, to_dst);
std::swap(to_std_time, to_dst_time);
std::swap(std_info, dst_info);
}
- if (dst_info.isgmt) to_dst_time += boost::posix_time::seconds(dst_info.info.gmtoff);
- if (std_info.isgmt) to_std_time += boost::posix_time::seconds(std_info.info.gmtoff);
+ if (dst_info->isgmt)
+ to_dst_time += boost::posix_time::seconds(dst_info->info.gmtoff);
+ if (std_info->isgmt)
+ to_std_time += boost::posix_time::seconds(std_info->info.gmtoff);
}
@@ -486,8 +504,8 @@ namespace DSTRule
to_dst == rhs.to_dst &&
to_std_time == rhs.to_std_time &&
to_dst_time == rhs.to_dst_time &&
- &std_info == &rhs.std_info &&
- &dst_info == &rhs.dst_info);
+ std_info == rhs.std_info &&
+ dst_info == rhs.dst_info);
}
bool
@@ -498,14 +516,13 @@ namespace DSTRule
}
static TZ_Entry
-zone_no_dst(int year, IANAParser::TZInfo std_info)
+zone_no_dst(int year, IANAParser::TZInfoIter std_info)
{
- using boost::local_time::dst_calc_rule;
-
- time_zone_names names(std_info.name, std_info.name, nullptr, nullptr);
- duration std_off(0, 0, std_info.info.gmtoff);
- dst_offsets offsets(NULL);
- TZ_Ptr tz(new time_zone(names, std_off, offsets, dst_calc_rule));
+ time_zone_names names(std_info->name, std_info->name, "", "");
+ duration std_off(0, 0, std_info->info.gmtoff);
+ dst_offsets offsets({0, 0, 0}, {0, 0, 0}, {0, 0, 0});
+ boost::local_time::dst_calc_rule_ptr calc_rule(nullptr);
+ TZ_Ptr tz(new time_zone(names, std_off, offsets, calc_rule));
return std::make_pair(year, tz);
}
@@ -517,11 +534,11 @@ zone_from_rule(int year, DSTRule::DSTRule rule)
using nth_day_rule =
boost::local_time::nth_day_of_the_week_in_month_dst_rule;
- time_zone_names names(rule.std_info.name, rule.std_info.name,
- rule.dst_info.name, rule.dst_info.name);
- duration std_off(0, 0, rule.std_info.info.gmtoff);
+ time_zone_names names(rule.std_info->name, rule.std_info->name,
+ rule.dst_info->name, rule.dst_info->name);
+ duration std_off(0, 0, rule.std_info->info.gmtoff);
duration dlt_off(0, 0,
- rule.dst_info.info.gmtoff - rule.std_info.info.gmtoff);
+ rule.dst_info->info.gmtoff - rule.std_info->info.gmtoff);
dst_offsets offsets(dlt_off, rule.to_dst_time, rule.to_std_time);
calc_rule_ptr dates(new nth_day_rule(rule.to_dst.get(), rule.to_std.get()));
TZ_Ptr tz(new time_zone(names, std_off, offsets, dates));
@@ -531,18 +548,17 @@ zone_from_rule(int year, DSTRule::DSTRule rule)
TimeZoneProvider::TimeZoneProvider(const std::string& tzname) : zone_vector {}
{
IANAParser::IANAParser parser(tzname);
- auto last_info = std::find_if(parser.tzinfo,
- [](IANAParser::TZInfo& tz)
+ auto last_info = std::find_if(parser.tzinfo.begin(), parser.tzinfo.end(),
+ [](IANAParser::TZInfo tz)
{return !tz.info.isdst;});
auto last_time = ptime();
DSTRule::DSTRule last_rule;
for (auto txi = parser.transitions.begin();
txi != parser.transitions.end(); ++txi)
{
- auto this_info = parser.tzinfo[txi->index];
+ auto this_info = parser.tzinfo.begin() + txi->index;
auto this_time = boost::posix_time::from_time_t(txi->timestamp);
auto this_year = this_time.date().year();
- auto last_year = last_time.date().year();
//Initial case, gap in transitions > 1 year, non-dst zone
//change. In the last case the exact date of the change will be
//wrong because boost::local_date::timezone isn't able to
@@ -551,8 +567,8 @@ TimeZoneProvider::TimeZoneProvider(const std::string& tzname) : zone_vector {}
//was 1946, but we have to handle the case in order to parse
//the tz file.
if (last_time.is_not_a_date_time() ||
- this_year - last_year > 1 ||
- last_info.info.isdst == this_info.info.isdst)
+ this_year - last_time.date().year() > 1 ||
+ last_info->info.isdst == this_info->info.isdst)
{
zone_vector.push_back(zone_no_dst(this_year, last_info));
}
@@ -560,7 +576,7 @@ TimeZoneProvider::TimeZoneProvider(const std::string& tzname) : zone_vector {}
else
{
DSTRule::DSTRule new_rule(last_info, this_info,
- last_time.date(), this_time.date());
+ last_time, this_time);
if (new_rule != last_rule)
{
last_rule = new_rule;
diff --git a/src/libqof/qof/test/gtest-gnc-timezone.cpp b/src/libqof/qof/test/gtest-gnc-timezone.cpp
index 5696cd2..b20f11a 100644
--- a/src/libqof/qof/test/gtest-gnc-timezone.cpp
+++ b/src/libqof/qof/test/gtest-gnc-timezone.cpp
@@ -38,12 +38,22 @@ TEST(gnc_timezone_constructors, test_default_constructor)
TEST(gnc_timezone_constructors, test_pacific_time_constructor)
{
- TimeZoneProvider tzp ("Pacific Standard Time");
+#if PLATFORM(WINDOWS)
+ std::string timzone("Pacific Standard Time");
+#else
+ std::string timezone("America/Los_Angeles");
+#endif
+ TimeZoneProvider tzp (timezone);
EXPECT_NO_THROW (tzp.get(2006));
TZ_Ptr tz = tzp.get (2006);
EXPECT_FALSE(tz->std_zone_abbrev().empty());
- EXPECT_TRUE(tz->std_zone_abbrev() == "Pacific Standard Time");
+#if PLATFORM(WINDOWS)
+ EXPECT_TRUE(tz->std_zone_abbrev() == timezone);
+#else
+ EXPECT_TRUE(tz->std_zone_abbrev() == "PST");
+ EXPECT_TRUE(tz->dst_zone_abbrev() == "PDT");
+#endif
EXPECT_TRUE(tz->base_utc_offset().hours() == -8);
}
commit 280b7223bfc7e4d16a0a0fdb93d8aa083131090d
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Jan 24 15:12:43 2015 -0800
Partial posix implementation
diff --git a/configure.ac b/configure.ac
index ae6efd8..a98d210 100644
--- a/configure.ac
+++ b/configure.ac
@@ -371,7 +371,7 @@ update to latest darwin])
;;
darwin*)
platform=darwin
- AC_DEFINE(PLATFORM_OSX,1,[Running on OSX, either X11 or Quartz])
+ AC_DEFINE(GNC_PLATFORM_OSX, 1,[Running on OSX, either X11 or Quartz])
AC_DEFINE(GNC_PLATFORM_POSIX, 1, [POSIX-compliant OS])
AC_DEFINE(GNC_PLATFORM_DARWIN, 1, [Darwin-based OS])
AC_MSG_RESULT($platform)
diff --git a/src/libqof/qof/gnc-timezone.cpp b/src/libqof/qof/gnc-timezone.cpp
index 4b07894..c35973a 100644
--- a/src/libqof/qof/gnc-timezone.cpp
+++ b/src/libqof/qof/gnc-timezone.cpp
@@ -28,6 +28,11 @@
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace gnc::date;
+using duration = boost::posix_time::time_duration;
+using time_zone = boost::local_time::custom_time_zone;
+using dst_offsets = boost::local_time::dst_adjustment_offsets;
+using calc_rule_ptr = boost::local_time::dst_calc_rule_ptr;
+
#if PLATFORM(WINDOWS)
/* libstdc++ to_string is broken on MinGW with no real interest in fixing it.
* See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52015
@@ -115,10 +120,9 @@ windows_tz_names (HKEY key)
static TZ_Ptr
zone_from_regtzi (const RegTZI& regtzi, time_zone_names names)
{
- using duration = boost::posix_time::time_duration;
using ndate = boost::gregorian::nth_day_of_the_week_in_month;
using nth_day_rule = boost::local_time::nth_day_of_the_week_in_month_dst_rule;
- using time_zone = boost::local_time::custom_time_zone;
+ using make_week_num = static_cast<boost::date_time::nth_kday_of_month<boost::gregorian::date>::week_num>;
duration std_off (0, regtzi.StandardBias - regtzi.Bias, 0);
duration dlt_off (0, regtzi.DaylightBias, 0);
@@ -126,15 +130,14 @@ zone_from_regtzi (const RegTZI& regtzi, time_zone_names names)
regtzi.StandardDate.wSecond);
duration end_time (regtzi.DaylightDate.wHour, regtzi.DaylightDate.wMinute,
regtzi.DaylightDate.wSecond);
- boost::local_time::dst_adjustment_offsets offsets (dlt_off, start_time,
- end_time);
- auto std_week_num = static_cast<boost::date_time::nth_kday_of_month<boost::gregorian::date>::week_num>(regtzi.StandardDate.wDay);
- auto dlt_week_num = static_cast<boost::date_time::nth_kday_of_month<boost::gregorian::date>::week_num>(regtzi.DaylightDate.wDay);
+ dst_offsets offsets (dlt_off, start_time, end_time);
+ auto std_week_num = make_week_num(regtzi.StandardDate.wDay);
+ auto dlt_week_num = make_week_num(regtzi.DaylightDate.wDay);
ndate start (std_week_num, regtzi.StandardDate.wDayOfWeek,
regtzi.StandardDate.wMonth);
ndate end(dlt_week_num, regtzi.DaylightDate.wDayOfWeek,
regtzi.DaylightDate.wMonth);
- boost::local_time::dst_calc_rule_ptr dates(new nth_day_rule (start, end));
+ calc_rule_ptr dates(new nth_day_rule (start, end));
return TZ_Ptr(new time_zone(names, std_off, offsets, dates));
}
@@ -210,6 +213,8 @@ TimeZoneProvider::load_windows_classic_tz (HKEY key, time_zone_names names)
RegCloseKey (key);
}
+TimeZoneProvider::TimeZoneProvider () : TimeZoneProvider ("")) {}
+
TimeZoneProvider::TimeZoneProvider (const std::string& identifier) :
zone_vector ()
{
@@ -241,14 +246,341 @@ TimeZoneProvider::TimeZoneProvider (const std::string& identifier) :
else
throw std::invalid_argument ("No data for TZ " + key_name);
}
-#else
+#elif PLATFORM(POSIX)
using std::to_string;
-TimeZoneProvider::TimeZoneProvider(const std::string& tzname)
+#include <istream>
+#include <cstdlib>
+
+using boost::posix_time::ptime;;
+//To enable using Transition with different meanings for IANA files
+//and for DSTRules.
+namespace IANAParser
+{
+ struct TZHead
+ {
+ char magic[4];
+ char version;
+ uint8_t reserved[15];
+ uint8_t ttisgmtcnt[4];
+ uint8_t ttisstdcnt[4];
+ uint8_t leapcnt[4];
+ uint8_t timecnt[4];
+ uint8_t typecnt[4];
+ uint8_t charcnt[4];
+ };
+
+ struct TTInfo
+ {
+ uint32_t gmtoff;
+ uint8_t isdst;
+ uint8_t abbrind;
+ };
+
+ struct TZInfo
+ {
+ TTInfo info;
+ std::string name;
+ bool isstd;
+ bool isgmt;
+ };
+
+ struct Transition
+ {
+ time_t timestamp;
+ uint8_t index;
+ };
+
+ static std::ifstream
+ find_tz_file(const std::string& name)
+ {
+ if (name.empty())
+ return std::ifstream("/etc/localtime", std::ios::binary);
+
+ std::string tzname = name;
+//POSIX specifies that that identifier should begin with ':', but we
+//should be liberal. If it's there, it's not part of the filename.
+ if (tzname[0] == ':')
+ tzname.erase(tzname.begin());
+ if (tzname[0] == '/') //Absolute filename
+ return std::ifstream(tzname, std::ios::binary);
+
+ std::string tzdir = std::getenv("TZDIR");
+ if (tzdir.empty())
+ tzdir = "/usr/share/zoneinfo";
+//Note that we're not checking the filename.
+ return std::ifstream(std::move(tzdir + "/" + tzname), std::ios::binary);
+ }
+
+ struct IANAParser
+ {
+ IANAParser(const std::string& name) : IANAParser(find_tz_file(name)) {}
+ IANAParser(std::ifstream ifs);
+ std::vector<Transition>transitions;
+ std::vector<TZInfo>tzinfo;
+ int last_year;
+ };
+
+ IANAParser::IANAParser(std::ifstream ifs)
+ {
+ if (! ifs)
+ throw std::invalid_argument("The timezone string failed to resolve to a valid filename");
+
+ TZHead tzh;
+ auto timesize = sizeof(int32_t);
+ last_year = 2037; //Constrained by 32-bit time_t.
+ ifs.get(reinterpret_cast<char*>(&tzh), sizeof(tzh));
+ auto time_count = *reinterpret_cast<uint32_t*>(tzh.timecnt);
+ auto type_count = *reinterpret_cast<uint32_t*>(tzh.typecnt);
+ auto char_count = *reinterpret_cast<uint32_t*>(tzh.charcnt);
+ auto isgmt_count = *reinterpret_cast<uint32_t*>(tzh.ttisgmtcnt);
+ auto isstd_count = *reinterpret_cast<uint32_t*>(tzh.ttisstdcnt);
+ auto leap_count = *reinterpret_cast<uint32_t*>(tzh.leapcnt);
+ if (tzh.version == '2' && sizeof(time_t) == sizeof(int64_t))
+ {
+ ifs.seekg(sizeof(tzh) +
+ timesize + sizeof(uint8_t) * time_count +
+ sizeof(TTInfo) * type_count +
+ sizeof(char) * char_count +
+ sizeof(uint8_t) * isgmt_count +
+ sizeof(uint8_t) * isstd_count +
+ 2 * timesize * leap_count +
+ sizeof(tzh));
+ timesize = sizeof(int64_t);
+ //This might change at some point in the probably very distant future.
+ last_year = 2499;
+ }
+
+ transitions.reserve(time_count);
+ tzinfo.reserve(type_count);
+
+ for(auto tr : transitions)
+ {
+ uint8_t time[sizeof(time_t)];
+ ifs.get(reinterpret_cast<char*>(time), timesize);
+ tr.timestamp = *reinterpret_cast<time_t*>(time);
+ }
+
+ for (auto tr : transitions)
+ {
+ char idx;
+ ifs.get(idx);
+ tr.index = std::move(idx);
+ }
+
+ for(auto tz : tzinfo)
+ {
+ char infochars[sizeof(TTInfo)];
+ ifs.get(infochars, sizeof(TTInfo));
+ tz.info = *reinterpret_cast<TTInfo*>(infochars);
+ }
+
+ try
+ {
+ std::unique_ptr<char[]>abbrev(new char[char_count]);
+ ifs.get(abbrev.get(), char_count);
+
+ for (auto tz : tzinfo)
+ {
+ tz.name = abbrev[tz.info.abbrind];
+ }
+ }
+ catch(std::bad_alloc)
+ {
+ ;
+ }
+
+ if (isstd_count == type_count)
+ {
+ char foo;
+ for (auto tz : tzinfo)
+ {
+ ifs.get(foo);
+ tz.isstd = foo != '\0';
+ }
+ for (auto tz : tzinfo)
+ {
+ ifs.get(foo);
+ tz.isgmt = foo != '\0';
+ }
+ }
+ }
+}
+
+namespace DSTRule
{
+ using gregorian_date = boost::gregorian::date;
+ using IANAParser::TZInfo;
+ using ndate = boost::gregorian::nth_day_of_the_week_in_month;
+ using week_num =
+ boost::date_time::nth_kday_of_month<boost::gregorian::date>::week_num;
+
+ struct Transition
+ {
+ Transition() : month(0), dow(0), week(static_cast<week_num>(0)) {}
+ Transition(gregorian_date date);
+ bool operator==(const Transition& rhs);
+ ndate get();
+ boost::gregorian::greg_month month;
+ boost::gregorian::greg_weekday dow;
+ week_num week;
+ };
+
+ Transition::Transition(gregorian_date date) :
+ month(date.month()), dow(date.day_of_week()),
+ week(static_cast<week_num>((7 + date.day() - date.day_of_week()) / 7 + 1))
+ {}
+
+ bool
+ Transition::operator==(const Transition& rhs)
+ {
+ return (month == rhs.month && dow == rhs.dow && week == rhs.week);
+ }
+
+ ndate
+ Transition::get()
+ {
+ return ndate(week, dow, month);
+ }
+
+ struct DSTRule
+ {
+ DSTRule();
+ DSTRule(const TZInfo& info1, const TZInfo& info2,
+ ptime date1, ptime date2);
+ bool operator==(const DSTRule& rhs) const noexcept;
+ bool operator!=(const DSTRule& rhs) const noexcept;
+ Transition to_std;
+ Transition to_dst;
+ duration to_std_time;
+ duration to_dst_time;
+ const TZInfo& std_info;
+ const TZInfo& dst_info;
+ };
+
+ DSTRule::DSTRule() : to_std(), to_dst(), to_std_time {}, to_dst_time {},
+ std_info (), dst_info () {};
+
+ DSTRule::DSTRule (const TZInfo& info1, const TZInfo& info2,
+ ptime date1, ptime date2) :
+ to_std(date1.date()), to_dst(date2.date()),
+ to_std_time(date1.time_of_day()), to_dst_time(date2.time_of_day()),
+ std_info(info1), dst_info(info2)
+ {
+ if (info1.info.isdst == info2.info.isdst)
+ throw(std::invalid_argument("Both infos have the same dst value."));
+ if (info1.info.isdst && !info2.info.isdst)
+ {
+ std::swap(to_std, to_dst);
+ std::swap(to_std_time, to_dst_time);
+ std::swap(std_info, dst_info);
+ }
+ if (dst_info.isgmt) to_dst_time += boost::posix_time::seconds(dst_info.info.gmtoff);
+ if (std_info.isgmt) to_std_time += boost::posix_time::seconds(std_info.info.gmtoff);
+
+ }
+
+ bool
+ DSTRule::operator==(const DSTRule& rhs) const noexcept
+ {
+ return (to_std == rhs.to_std &&
+ to_dst == rhs.to_dst &&
+ to_std_time == rhs.to_std_time &&
+ to_dst_time == rhs.to_dst_time &&
+ &std_info == &rhs.std_info &&
+ &dst_info == &rhs.dst_info);
+ }
+
+ bool
+ DSTRule::operator!=(const DSTRule& rhs) const noexcept
+ {
+ return ! operator==(rhs);
+ }
+}
+
+static TZ_Entry
+zone_no_dst(int year, IANAParser::TZInfo std_info)
+{
+ using boost::local_time::dst_calc_rule;
+
+ time_zone_names names(std_info.name, std_info.name, nullptr, nullptr);
+ duration std_off(0, 0, std_info.info.gmtoff);
+ dst_offsets offsets(NULL);
+ TZ_Ptr tz(new time_zone(names, std_off, offsets, dst_calc_rule));
+ return std::make_pair(year, tz);
+}
+
+static TZ_Entry
+zone_from_rule(int year, DSTRule::DSTRule rule)
+{
+ using boost::gregorian::partial_date;
+ using boost::local_time::partial_date_dst_rule;
+ using nth_day_rule =
+ boost::local_time::nth_day_of_the_week_in_month_dst_rule;
+
+ time_zone_names names(rule.std_info.name, rule.std_info.name,
+ rule.dst_info.name, rule.dst_info.name);
+ duration std_off(0, 0, rule.std_info.info.gmtoff);
+ duration dlt_off(0, 0,
+ rule.dst_info.info.gmtoff - rule.std_info.info.gmtoff);
+ dst_offsets offsets(dlt_off, rule.to_dst_time, rule.to_std_time);
+ calc_rule_ptr dates(new nth_day_rule(rule.to_dst.get(), rule.to_std.get()));
+ TZ_Ptr tz(new time_zone(names, std_off, offsets, dates));
+ return std::make_pair(year, tz);
}
+TimeZoneProvider::TimeZoneProvider(const std::string& tzname) : zone_vector {}
+{
+ IANAParser::IANAParser parser(tzname);
+ auto last_info = std::find_if(parser.tzinfo,
+ [](IANAParser::TZInfo& tz)
+ {return !tz.info.isdst;});
+ auto last_time = ptime();
+ DSTRule::DSTRule last_rule;
+ for (auto txi = parser.transitions.begin();
+ txi != parser.transitions.end(); ++txi)
+ {
+ auto this_info = parser.tzinfo[txi->index];
+ auto this_time = boost::posix_time::from_time_t(txi->timestamp);
+ auto this_year = this_time.date().year();
+ auto last_year = last_time.date().year();
+ //Initial case, gap in transitions > 1 year, non-dst zone
+ //change. In the last case the exact date of the change will be
+ //wrong because boost::local_date::timezone isn't able to
+ //represent it. For GnuCash's purposes this isn't likely to be
+ //important as the last time this sort of transition happened
+ //was 1946, but we have to handle the case in order to parse
+ //the tz file.
+ if (last_time.is_not_a_date_time() ||
+ this_year - last_year > 1 ||
+ last_info.info.isdst == this_info.info.isdst)
+ {
+ zone_vector.push_back(zone_no_dst(this_year, last_info));
+ }
+
+ else
+ {
+ DSTRule::DSTRule new_rule(last_info, this_info,
+ last_time.date(), this_time.date());
+ if (new_rule != last_rule)
+ {
+ last_rule = new_rule;
+ zone_vector.push_back(zone_from_rule (this_time.date().year(),
+ new_rule));
+ }
+ }
+ last_time = this_time;
+ last_info = this_info;
+ }
+
+ if (last_time.is_not_a_date_time() ||
+ last_time.date().year() < parser.last_year)
+ zone_vector.push_back(zone_no_dst(9999, last_info));
+ else //Last DST rule forever after.
+ zone_vector.push_back(zone_from_rule(9999, last_rule));
+}
#endif
+
TZ_Ptr
TimeZoneProvider::get(int year)
{
commit 5983df7ad304055aa8365af6001ea9311d2d583d
Author: John Ralls <jralls at ceridwen.us>
Date: Sun Jan 18 12:33:47 2015 -0800
Windows implementation of TimeZoneProvider.
diff --git a/src/libqof/qof/Makefile.am b/src/libqof/qof/Makefile.am
index 0c37dfd..7744427 100644
--- a/src/libqof/qof/Makefile.am
+++ b/src/libqof/qof/Makefile.am
@@ -6,8 +6,7 @@ lib_LTLIBRARIES = libgnc-qof.la
libgnc_qof_la_LDFLAGS= \
-version-info \
- $(LIBQOF_LIBRARY_VERSION) \
- $(BOOST_LDFLAGS)
+ $(LIBQOF_LIBRARY_VERSION)
libgnc_qof_common_libs = \
$(GLIB_LIBS) \
@@ -27,6 +26,7 @@ libgnc_qof_la_SOURCES = \
gnc-int128.cpp \
gnc-numeric.cpp \
gnc-rational.cpp \
+ gnc-timezone.cpp \
guid.cpp \
kvp-util.cpp \
kvp_frame.cpp \
@@ -53,6 +53,7 @@ qofinclude_HEADERS = \
gnc-date.h \
gnc-numeric.h \
gnc-rational.hpp \
+ gnc-timezone.hpp \
guid.h \
kvp-util-p.h \
kvp-util.h \
diff --git a/src/libqof/qof/gnc-timezone.cpp b/src/libqof/qof/gnc-timezone.cpp
new file mode 100644
index 0000000..4b07894
--- /dev/null
+++ b/src/libqof/qof/gnc-timezone.cpp
@@ -0,0 +1,261 @@
+/********************************************************************\
+ * gnc-timezone.cpp - Retrieve timezone information from OS. *
+ * Copyright 2014 John Ralls <jralls at ceridwen.us> *
+ * Based on work done with Arnel Borja for GLib's gtimezone in 2012.*
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+\********************************************************************/
+
+#include "gnc-timezone.hpp"
+
+#include <string>
+#include <cstdint>
+#include <ostream>
+#include <boost/date_time/gregorian/gregorian.hpp>
+using namespace gnc::date;
+
+#if PLATFORM(WINDOWS)
+/* libstdc++ to_string is broken on MinGW with no real interest in fixing it.
+ * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52015
+ */
+#if ! COMPILER(MINGW)
+using std::to_string;
+#else
+template<typename T> inline std::string to_string(T num);
+
+template<>
+inline std::string
+to_string<unsigned int>(unsigned int num)
+{
+ constexpr unsigned int numchars = sizeof num * 3 + 1;
+ char buf [numchars] {};
+ snprintf (buf, numchars, "%u", num);
+ return std::string(buf);
+}
+
+template<>
+inline std::string
+to_string<int>(int num)
+{
+ constexpr unsigned int numchars = sizeof num * 3 + 1;
+ char buf [numchars];
+ snprintf (buf, numchars, "%d", num);
+ return std::string(buf);
+}
+#endif
+
+static std::string
+windows_default_tzname (void)
+{
+ const char *subkey =
+ "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation";
+ constexpr size_t keysize {128};
+ HKEY key;
+ char key_name[keysize] {};
+ unsigned long tz_keysize = keysize;
+ if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, subkey, 0,
+ KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
+ {
+ if (RegQueryValueExA (key, "TimeZoneKeyName", nullptr, nullptr,
+ (LPBYTE)key_name, &tz_keysize) != ERROR_SUCCESS)
+ {
+ memset (key_name, 0, tz_keysize);
+ }
+ RegCloseKey (key);
+ }
+ return std::string(key_name);
+}
+
+typedef struct
+{
+ LONG Bias;
+ LONG StandardBias;
+ LONG DaylightBias;
+ SYSTEMTIME StandardDate;
+ SYSTEMTIME DaylightDate;
+} RegTZI;
+
+static time_zone_names
+windows_tz_names (HKEY key)
+{
+ /* The weird sizeof arg is because C++ won't find a type's
+ * element, just an object's.
+ */
+ constexpr auto s_size = sizeof (((TIME_ZONE_INFORMATION*)0)->StandardName);
+ char std_name[s_size];
+ unsigned long size = s_size;
+ if (RegQueryValueExA (key, "Std", NULL, NULL,
+ (LPBYTE)&(std_name), &size) != ERROR_SUCCESS)
+ throw std::invalid_argument ("Registry contains no standard name.");
+
+ constexpr auto d_size = sizeof (((TIME_ZONE_INFORMATION*)0)->DaylightName);
+ char dlt_name[d_size];
+ size = d_size;
+ if (RegQueryValueExA (key, "Dlt", NULL, NULL,
+ (LPBYTE)&(dlt_name), &size) != ERROR_SUCCESS)
+ throw std::invalid_argument ("Registry contains no daylight name.");
+
+ return time_zone_names (std_name, std_name, dlt_name, dlt_name);
+}
+
+static TZ_Ptr
+zone_from_regtzi (const RegTZI& regtzi, time_zone_names names)
+{
+ using duration = boost::posix_time::time_duration;
+ using ndate = boost::gregorian::nth_day_of_the_week_in_month;
+ using nth_day_rule = boost::local_time::nth_day_of_the_week_in_month_dst_rule;
+ using time_zone = boost::local_time::custom_time_zone;
+
+ duration std_off (0, regtzi.StandardBias - regtzi.Bias, 0);
+ duration dlt_off (0, regtzi.DaylightBias, 0);
+ duration start_time (regtzi.StandardDate.wHour, regtzi.StandardDate.wMinute,
+ regtzi.StandardDate.wSecond);
+ duration end_time (regtzi.DaylightDate.wHour, regtzi.DaylightDate.wMinute,
+ regtzi.DaylightDate.wSecond);
+ boost::local_time::dst_adjustment_offsets offsets (dlt_off, start_time,
+ end_time);
+ auto std_week_num = static_cast<boost::date_time::nth_kday_of_month<boost::gregorian::date>::week_num>(regtzi.StandardDate.wDay);
+ auto dlt_week_num = static_cast<boost::date_time::nth_kday_of_month<boost::gregorian::date>::week_num>(regtzi.DaylightDate.wDay);
+ ndate start (std_week_num, regtzi.StandardDate.wDayOfWeek,
+ regtzi.StandardDate.wMonth);
+ ndate end(dlt_week_num, regtzi.DaylightDate.wDayOfWeek,
+ regtzi.DaylightDate.wMonth);
+ boost::local_time::dst_calc_rule_ptr dates(new nth_day_rule (start, end));
+ return TZ_Ptr(new time_zone(names, std_off, offsets, dates));
+}
+
+void
+TimeZoneProvider::load_windows_dynamic_tz (HKEY key, time_zone_names names)
+{
+ DWORD first, last;
+
+ try
+ {
+ unsigned long size = sizeof first;
+ if (RegQueryValueExA (key, "FirstEntry", NULL, NULL,
+ (LPBYTE) &first, &size) != ERROR_SUCCESS)
+ throw std::invalid_argument ("No first entry.");
+
+ size = sizeof last;
+ if (RegQueryValueExA (key, "LastEntry", NULL, NULL,
+ (LPBYTE) &last, &size) != ERROR_SUCCESS)
+ throw std::invalid_argument ("No last entry.");
+
+ TZ_Ptr tz {};
+ for (unsigned int year = first; year <= last; year++)
+ {
+ auto s = to_string(year);
+ auto ystr = s.c_str();
+ RegTZI regtzi {};
+ size = sizeof regtzi;
+ auto err_val = RegQueryValueExA (key, ystr, NULL, NULL,
+ (LPBYTE) ®tzi, &size);
+ if (err_val != ERROR_SUCCESS)
+ {
+ break;
+ }
+ tz = zone_from_regtzi (regtzi, names);
+ if (year == first)
+ zone_vector.push_back (std::make_pair(0, tz));
+ zone_vector.push_back (std::make_pair(year, tz));
+ }
+ zone_vector.push_back (std::make_pair(9999, tz));
+ }
+ catch (std::invalid_argument)
+ {
+ RegCloseKey (key);
+ throw;
+ }
+ catch (std::bad_alloc)
+ {
+ RegCloseKey (key);
+ throw;
+ }
+ RegCloseKey (key);
+}
+
+void
+TimeZoneProvider::load_windows_classic_tz (HKEY key, time_zone_names names)
+{
+ RegTZI regtzi {};
+ unsigned long size = sizeof regtzi;
+ try
+ {
+ if (RegQueryValueExA (key, "TZI", NULL, NULL,
+ (LPBYTE) ®tzi, &size) == ERROR_SUCCESS)
+ {
+ zone_vector.push_back(
+ std::make_pair(0, zone_from_regtzi (regtzi, names)));
+ }
+ }
+ catch (std::bad_alloc)
+ {
+ RegCloseKey (key);
+ throw;
+ }
+ RegCloseKey (key);
+}
+
+TimeZoneProvider::TimeZoneProvider (const std::string& identifier) :
+ zone_vector ()
+{
+ HKEY key;
+ const std::string reg_key =
+ "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\";
+
+ auto key_name = (identifier.empty() ? windows_default_tzname () :
+ identifier);
+
+ if (key_name.empty())
+ throw std::invalid_argument ("No identifier or default tzname.");
+
+ std::string subkey = reg_key + key_name;
+ if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, subkey.c_str(), 0,
+ KEY_QUERY_VALUE, &key) != ERROR_SUCCESS)
+ throw std::invalid_argument ("No TZ in registry named " + key_name);
+
+ time_zone_names names {windows_tz_names (key)};
+ RegCloseKey (key);
+
+ std::string subkey_dynamic = subkey + "\\Dynamic DST";
+ if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, subkey_dynamic.c_str(), 0,
+ KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
+ this->load_windows_dynamic_tz (key, names);
+ else if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, subkey.c_str(), 0,
+ KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
+ this->load_windows_classic_tz (key, names);
+ else
+ throw std::invalid_argument ("No data for TZ " + key_name);
+}
+#else
+using std::to_string;
+TimeZoneProvider::TimeZoneProvider(const std::string& tzname)
+{
+}
+
+#endif
+
+TZ_Ptr
+TimeZoneProvider::get(int year)
+{
+ auto iter = find_if(zone_vector.begin(), zone_vector.end(),
+ [=](TZ_Entry e) { return e.first >= year; });
+ if (iter == zone_vector.end())
+ throw std::out_of_range ("Year " + to_string(year) +
+ " isn't covered by this time zone.");
+ return iter->second;
+}
diff --git a/src/libqof/qof/gnc-timezone.hpp b/src/libqof/qof/gnc-timezone.hpp
new file mode 100644
index 0000000..400f0c9
--- /dev/null
+++ b/src/libqof/qof/gnc-timezone.hpp
@@ -0,0 +1,66 @@
+/********************************************************************\
+ * gnc-timezone.cpp - Retrieve timezone information from OS. *
+ * Copyright 2014 John Ralls <jralls at ceridwen.us> *
+ * Based on work done with Arnel Borja for GLib's gtimezone in 2012.*
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+\********************************************************************/
+
+#ifndef __GNC_TIMEZONE_HPP__
+#define __GNC_TIMEZONE_HPP__
+extern "C"
+{
+#include <platform.h>
+#if PLATFORM(WINDOWS)
+#include <windows.h>
+#endif
+}
+
+#define BOOST_ERROR_CODE_HEADER_ONLY
+#include <boost/date_time/local_time/local_time.hpp>
+
+namespace gnc
+{
+ namespace date
+ {}
+}// Move these later
+using TZ = boost::local_time::time_zone;
+using TZ_Ptr = boost::local_time::time_zone_ptr;
+using TZ_Entry = std::pair<int, TZ_Ptr>;
+using TZ_Vector = std::vector<TZ_Entry>;
+using time_zone_names = boost::local_time::time_zone_names;
+
+class TimeZoneProvider
+{
+public:
+ // The default constructor provides the time zone for the current locale
+ TimeZoneProvider() : TimeZoneProvider (static_cast<std::string>("")) {}
+ TimeZoneProvider(const std::string& tzname); //create a provider for a specified TZ.
+ TimeZoneProvider(const TimeZoneProvider&) = delete;
+ TimeZoneProvider(const TimeZoneProvider&&) = delete;
+ TimeZoneProvider operator=(const TimeZoneProvider&) = delete;
+ TimeZoneProvider operator=(const TimeZoneProvider&&) = delete;
+ TZ_Ptr get (int year);
+private:
+ TZ_Vector zone_vector;
+#if PLATFORM(WINDOWS)
+ void load_windows_dynamic_tz(HKEY, time_zone_names);
+ void load_windows_classic_tz(HKEY, time_zone_names);
+#endif
+};
+
+#endif //__GCN_TIMEZONE_HPP__
diff --git a/src/libqof/qof/test/gtest-gnc-timezone.cpp b/src/libqof/qof/test/gtest-gnc-timezone.cpp
index 11b6f6a..5696cd2 100644
--- a/src/libqof/qof/test/gtest-gnc-timezone.cpp
+++ b/src/libqof/qof/test/gtest-gnc-timezone.cpp
@@ -22,6 +22,7 @@
*******************************************************************/
#include <gtest/gtest.h>
+#include <string>
#include "../gnc-timezone.hpp"
TEST(gnc_timezone_constructors, test_default_constructor)
commit 45170bb5ebfc08e3fd9789e34c600d58c7886fa3
Author: John Ralls <jralls at ceridwen.us>
Date: Sun Jan 4 16:30:02 2015 -0800
Basic tests for TimeZoneProvider.
diff --git a/configure.ac b/configure.ac
index 889f815..ae6efd8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -372,12 +372,15 @@ update to latest darwin])
darwin*)
platform=darwin
AC_DEFINE(PLATFORM_OSX,1,[Running on OSX, either X11 or Quartz])
+ AC_DEFINE(GNC_PLATFORM_POSIX, 1, [POSIX-compliant OS])
+ AC_DEFINE(GNC_PLATFORM_DARWIN, 1, [Darwin-based OS])
AC_MSG_RESULT($platform)
AC_MSG_CHECKING(For GDK-Quartz)
platform=osx
_gdk_tgt=`$PKG_CONFIG --variable=target gdk-2.0`
if test "x$_gdk_tgt" = xquartz; then
platform=darwin/quartz
+ AC_DEFINE(GNC_PLATFORM_COCOA, 1, [Cocoa/Nexstep/GnuStep framework])
AC_MSG_RESULT(yes)
AC_DEFINE(GDK_QUARTZ,,[Using GDK Quartz (not X11)])
PKG_CHECK_MODULES([GTK_MAC], gtk-mac-integration-gtk2,
@@ -402,6 +405,7 @@ update to latest darwin])
mingw*|cygwin*)
platform=win32
AC_MSG_RESULT($platform)
+ AC_DEFINE(GNC_PLATFORM_WINDOWS, 1, [Microsoft Windows OS])
LT_PROG_RC
AC_MSG_CHECKING(for native win32)
@@ -443,6 +447,7 @@ update to latest darwin])
*)
platform=linux/other
+ AC_DEFINE(GNC_PLATFORM_POSIX, 1, [POSIX-compliant OS])
AC_MSG_RESULT($platform)
;;
esac
diff --git a/src/libqof/qof/test/Makefile.am b/src/libqof/qof/test/Makefile.am
index 05174d6..6738fe1 100644
--- a/src/libqof/qof/test/Makefile.am
+++ b/src/libqof/qof/test/Makefile.am
@@ -41,8 +41,8 @@ test_kvp_value_SOURCES = \
test_kvp_value_LDADD = \
$(top_builddir)/$(MODULEPATH)/libgnc-qof.la \
$(GLIB_LIBS) \
- $(GTEST_LIBS) \
$(BOOST_LDFLAGS)
+
if !GOOGLE_TEST_LIBS
nodist_test_kvp_value_SOURCES = \
${GTEST_SRC}/src/gtest_main.cc
@@ -52,28 +52,39 @@ endif
test_kvp_value_CPPFLAGS = \
-I$(GTEST_HEADERS) \
-I$(top_srcdir)/$(MODULEPATH) \
- $(BOOST_CPPFLAGS) \
- $(GLIB_CFLAGS)
+ $(BOOST_CPPFLAGS)
check_PROGRAMS += test-kvp-value
test_gnc_int128_SOURCES = \
$(top_srcdir)/${MODULEPATH}/gnc-int128.cpp \
gtest-gnc-int128.cpp
-test_gnc_int128_CPPFLAGS = \
- -I${GTEST_HEADERS} \
- ${GLIB_CFLAGS}
+test_gnc_int128_CPPFLAGS = -I${GTEST_HEADERS}
+
-test_gnc_int128_LDADD = \
- ${GLIB_LIBS} \
- $(GTEST_LIBS)
+test_gnc_int128_LDADD = $(GTEST_LIBS)
if !GOOGLE_TEST_LIBS
nodist_test_gnc_int128_SOURCES = \
${GTEST_SRC}/src/gtest_main.cc
test_gnc_int128_LDADD += $(top_builddir)/src/test-core/libgtest.a
endif
-
check_PROGRAMS += test-gnc-int128
+
+test_gnc_timezone_SOURCES = \
+ $(top_srcdir)/${MODULEPATH}/gnc-timezone.cpp \
+ gtest-gnc-timezone.cpp
+
+test_gnc_timezone_CPPFLAGS = \
+ -I${GTEST_HEADERS} \
+ -I${top_srcdir}/src \
+ $(BOOST_CPPFLAGS)
+test_gnc_timezone_LDADD = $(GTEST_LIBS)
+if !GOOGLE_TEST_LIBS
+nodist_test_gnc_timezone_SOURCES = \
+ ${GTEST_SRC}/src/gtest_main.cc
+test_gnc_timezone_LDADD += $(top_builddir)/src/test-core/libgtest.a
+endif
+check_PROGRAMS += test-gnc-timezone
endif
test_qofdir = ${GNC_LIBEXECDIR}/${MODULEPATH}/test
diff --git a/src/libqof/qof/test/gtest-gnc-timezone.cpp b/src/libqof/qof/test/gtest-gnc-timezone.cpp
new file mode 100644
index 0000000..11b6f6a
--- /dev/null
+++ b/src/libqof/qof/test/gtest-gnc-timezone.cpp
@@ -0,0 +1,53 @@
+/********************************************************************
+ * Gtest-gnc-int128.cpp -- unit tests for the GncInt128 class *
+ * Copyright (C) 2014 John Ralls <jralls at ceridwen.us> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+ * *
+ *******************************************************************/
+
+#include <gtest/gtest.h>
+#include "../gnc-timezone.hpp"
+
+TEST(gnc_timezone_constructors, test_default_constructor)
+{
+ TimeZoneProvider tzp {};
+ EXPECT_NO_THROW (tzp.get(2014));
+ TZ_Ptr tz = tzp.get (2014);
+
+//Can't really test anything explicit, we don't know what to expect
+//from the default TZ.
+ EXPECT_FALSE(tz->std_zone_abbrev().empty());
+}
+
+TEST(gnc_timezone_constructors, test_pacific_time_constructor)
+{
+ TimeZoneProvider tzp ("Pacific Standard Time");
+ EXPECT_NO_THROW (tzp.get(2006));
+ TZ_Ptr tz = tzp.get (2006);
+
+ EXPECT_FALSE(tz->std_zone_abbrev().empty());
+ EXPECT_TRUE(tz->std_zone_abbrev() == "Pacific Standard Time");
+ EXPECT_TRUE(tz->base_utc_offset().hours() == -8);
+}
+
+TEST(gnc_timezone_constructors, test_bogus_time_constructor)
+{
+ EXPECT_THROW (TimeZoneProvider tzp ("New York Standard Time"),
+ std::invalid_argument);
+}
Summary of changes:
configure.ac | 7 +-
src/backend/sql/gnc-backend-sql.c | 11 +-
src/backend/sql/test/utest-gnc-backend-sql.c | 41 +-
src/backend/xml/sixtp-dom-generators.c | 15 +-
src/core-utils/gnc-gdate-utils.c | 9 +-
src/engine/Transaction.c | 10 +-
src/engine/gncBillTerm.c | 4 +-
src/engine/test-core/test-engine-stuff.c | 15 +-
src/engine/test/test-date.c | 8 +-
src/gnc-module/test/test-dynload.c | 2 +-
src/gnome-utils/gnc-main-window.c | 22 +-
src/import-export/aqb/gnc-ab-utils.c | 2 +-
.../aqb/test/file-book-hbcislot.gnucash | 2 +-
src/libqof/qof/Makefile.am | 8 +-
src/libqof/qof/gnc-date-p.h | 10 +-
src/libqof/qof/gnc-date.cpp | 507 +++-----
src/libqof/qof/gnc-date.h | 46 +-
src/libqof/qof/gnc-datetime.cpp | 284 +++++
src/libqof/qof/gnc-datetime.hpp | 157 +++
src/libqof/qof/gnc-timezone.cpp | 615 +++++++++
src/libqof/qof/gnc-timezone.hpp | 66 +
src/libqof/qof/test/Makefile.am | 51 +-
src/libqof/qof/test/gtest-gnc-datetime.cpp | 89 ++
.../{qofevent-p.h => test/gtest-gnc-timezone.cpp} | 54 +-
src/libqof/qof/test/test-gnc-date.c | 1341 ++++++++------------
25 files changed, 2033 insertions(+), 1343 deletions(-)
create mode 100644 src/libqof/qof/gnc-datetime.cpp
create mode 100644 src/libqof/qof/gnc-datetime.hpp
create mode 100644 src/libqof/qof/gnc-timezone.cpp
create mode 100644 src/libqof/qof/gnc-timezone.hpp
create mode 100644 src/libqof/qof/test/gtest-gnc-datetime.cpp
copy src/libqof/qof/{qofevent-p.h => test/gtest-gnc-timezone.cpp} (53%)
More information about the gnucash-changes
mailing list