diff --git a/libgnucash/engine/gnc-date.cpp b/libgnucash/engine/gnc-date.cpp index 56383edcf3..d7ae1a3dca 100644 --- a/libgnucash/engine/gnc-date.cpp +++ b/libgnucash/engine/gnc-date.cpp @@ -1329,19 +1329,19 @@ gnc_time64_get_day_end (time64 time_val) void gnc_tm_get_today_start (struct tm *tm) { - gnc_tm_get_day_start(tm, time(NULL)); + gnc_tm_get_day_start(tm, gnc_time(nullptr)); } void gnc_tm_get_today_neutral (struct tm *tm) { - gnc_tm_get_day_neutral(tm, time(NULL)); + gnc_tm_get_day_neutral(tm, gnc_time(nullptr)); } void gnc_tm_get_today_end (struct tm *tm) { - gnc_tm_get_day_end(tm, time(NULL)); + gnc_tm_get_day_end(tm, gnc_time(nullptr)); } time64 @@ -1349,7 +1349,7 @@ gnc_time64_get_today_start (void) { struct tm tm; - gnc_tm_get_day_start(&tm, time(NULL)); + gnc_tm_get_day_start(&tm, gnc_time(nullptr)); return gnc_mktime(&tm); } @@ -1358,7 +1358,7 @@ gnc_time64_get_today_end (void) { struct tm tm; - gnc_tm_get_day_end(&tm, time(NULL)); + gnc_tm_get_day_end(&tm, gnc_time(nullptr)); return gnc_mktime(&tm); } diff --git a/libgnucash/engine/gnc-date.h b/libgnucash/engine/gnc-date.h index 0b06af4a88..2193d0de10 100644 --- a/libgnucash/engine/gnc-date.h +++ b/libgnucash/engine/gnc-date.h @@ -29,10 +29,7 @@ Utility functions to handle date and time (adjusting, getting the current date, printing the date and time, etc.) - Overall, this file is quite a mess. Note, however, that other - applications, besides just GnuCash, use this file. In particular, - GnoTime (gttr.sourcefore.net) uses this file, and this file is - formally a part of QOF (qof.sourceforge.net). + Overall, this file is quite a mess. An important note about time-keeping: The general goal of any program that works with numeric time values SHOULD BE to always @@ -80,9 +77,12 @@ extern "C" /** - * Many systems, including Microsoft Windows and BSD-derived Unixes - * like Darwin, are retaining the int-32 typedef for time_t. Since - * this stops working in 2038, we define our own: + * Most systems that are currently maintained, including Microsoft Windows, + * BSD-derived Unixes and Linux, support 64-bit time_t even on 32-bit + * architectures. See https://en.wikipedia.org/wiki/Year_2038_problem + * + * For practical reasons -- as not all have made the transition to 64-bit -- + * we define our own 64-bit time type. */ typedef gint64 time64; /* A bit of a hack to create a type separate from the alias of int64_t so that @@ -165,7 +165,7 @@ typedef enum * 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 + * \param secs: Seconds since 00:00:00 UTC 01 January 1970 (negative values * are seconds before that moment). * \return A struct tm*, allocated on the heap. Must be freed with gnc_tm_free(). * The time is adjusted for the current local time zone. @@ -173,7 +173,7 @@ typedef enum struct tm* gnc_localtime (const time64 *secs); /** \brief fill out a time struct from a 64-bit time value adjusted for the current time zone. - * \param secs: Seconds since 00:00:01 UTC 01 January 1970 (negative values + * \param secs: Seconds since 00:00:00 UTC 01 January 1970 (negative values * are seconds before that moment) * \param time: A struct tm* for the function to fill. * The time is adjusted for the current local time zone. @@ -181,7 +181,7 @@ struct tm* gnc_localtime (const time64 *secs); struct tm* gnc_localtime_r (const time64 *secs, struct tm* time); /** \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 + * \param secs: Seconds since 00:00:00 UTC 01 January 1970 (negative values * are seconds before that moment) * \return A struct tm*, allocated on the heap. Must be freed with gnc_tm_free() * The time is UTC. @@ -196,7 +196,7 @@ gint gnc_start_of_week (void); /** \brief calculate seconds from the epoch given a time struct * \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 + * \return Seconds since 00:00:00 UTC 01 January 1970 (negative values * are seconds before that moment). */ time64 gnc_mktime (struct tm* time); @@ -204,13 +204,13 @@ time64 gnc_mktime (struct tm* time); /** \brief calculate seconds from the epoch given a time struct * \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 + * \return Seconds since 00:00:00 UTC 01 January 1970 (negative values * are seconds before that moment). */ time64 gnc_timegm (struct tm* time); /** \brief Return a string representation of a date from a 64-bit time value - * \param secs: Seconds since 00:00:01 UTC 01 January 1970 (negative values + * \param secs: Seconds since 00:00:00 UTC 01 January 1970 (negative values * are seconds before that moment) * \return A string, which must be freed with g_free(), representing the date * in the following format: @@ -219,19 +219,19 @@ time64 gnc_timegm (struct tm* time); */ gchar* gnc_ctime (const time64 *secs); -/** \brief get the current local time +/** \brief get the current 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 + * \return Seconds since 00:00:00 UTC 01 January 1970 (negative values * are seconds before that moment) */ time64 gnc_time (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) + * 00:00:00 UTC 01 January 1970 (negative values are seconds before that moment) * \param secs2: The second time value, in Seconds since - * 00:00:01 UTC 01 January 1970 (negative values are seconds before that moment) + * 00:00:00 UTC 01 January 1970 (negative values are seconds before that moment) * \return The difference in seconds between secs1 and secs2. If secs2 is * later than secs1 the value will be negative. */ diff --git a/libgnucash/engine/test/gtest-gnc-datetime.cpp b/libgnucash/engine/test/gtest-gnc-datetime.cpp index 7a5128d6b3..70b8b1a614 100644 --- a/libgnucash/engine/test/gtest-gnc-datetime.cpp +++ b/libgnucash/engine/test/gtest-gnc-datetime.cpp @@ -23,6 +23,7 @@ \********************************************************************/ #include "../gnc-datetime.hpp" +#include "../gnc-date.h" #include /* Backdoor to enable unittests to temporarily override the timezone: */ @@ -253,7 +254,7 @@ TEST(gnc_date_operators, test_move_assignment) TEST(gnc_datetime_constructors, test_default_constructor) { GncDateTime atime; - long time_now = time(nullptr); + time64 time_now = gnc_time(nullptr); EXPECT_EQ(static_cast(atime), static_cast(time_now)); } diff --git a/libgnucash/engine/test/gtest-gnc-option.cpp b/libgnucash/engine/test/gtest-gnc-option.cpp index 1c7f67904f..6d2005b602 100644 --- a/libgnucash/engine/test/gtest-gnc-option.cpp +++ b/libgnucash/engine/test/gtest-gnc-option.cpp @@ -934,6 +934,13 @@ TEST(GncOptionDate, test_gnc_relative_date_from_storage_string) EXPECT_EQ(RelativeDatePeriod::END_ACCOUNTING_PERIOD, gnc_relative_date_from_storage_string("end-prev-fin-year")); } +TEST(GncOptionDate, test_not_using_32bit_time_t_in_2038) +{ + // tests below call time() to initialize GDate. + // make sure the tests fail if that could cause a problem + EXPECT_FALSE(sizeof (time_t) == 4 && time(nullptr) <= 0) << "Time to upgrade 32bit time_t!"; +} + TEST(GncOptionDate, test_gnc_relative_date_to_time64) { GDate date; diff --git a/libgnucash/engine/test/test-gnc-date.c b/libgnucash/engine/test/test-gnc-date.c index 93c379e0ce..558217196a 100644 --- a/libgnucash/engine/test/test-gnc-date.c +++ b/libgnucash/engine/test/test-gnc-date.c @@ -344,7 +344,7 @@ test_gnc_time (void) time64 secs1, secs2; secs1 = gnc_time (&secs2); g_assert_cmpint (secs1, ==, secs2); - g_assert_cmpint (secs1, ==, time(0)); + g_assert_cmpint (secs1, ==, gnc_time(NULL)); } /* gnc_difftime and gnc_tm_free are just too simple to bother testing. */