gnucash stable: GncDateTime: New exceptions and a 32-bit time_t problem.

John Ralls jralls at code.gnucash.org
Sun Dec 28 19:01:02 EST 2025


Updated	 via  https://github.com/Gnucash/gnucash/commit/942313d0 (commit)
	from  https://github.com/Gnucash/gnucash/commit/1c9bcf62 (commit)



commit 942313d09969b829fb43cda01154b3637aad3060
Author: John Ralls <jralls at ceridwen.us>
Date:   Sun Dec 28 15:42:06 2025 -0800

    GncDateTime: New exceptions and a 32-bit time_t problem.
    
    Boost::date_time has changed to throwing a std::out_of_range instead of a
    boost::date_time::gregorian::bad_year when a date is outside of the
    1400-9999 year range it can deal with.
    
    We also recently discovered that it will use the system localtime function
    when creating a new date which can lead to a 2038 failure. Use std::chrono
    to resolve that problem.

diff --git a/libgnucash/engine/gnc-datetime.cpp b/libgnucash/engine/gnc-datetime.cpp
index a31d33f850..cbacd3d2a3 100644
--- a/libgnucash/engine/gnc-datetime.cpp
+++ b/libgnucash/engine/gnc-datetime.cpp
@@ -29,6 +29,7 @@
 #include <boost/date_time/local_time/local_time.hpp>
 #include <boost/locale.hpp>
 #include <boost/regex.hpp>
+#include <stdexcept>
 #include <unicode/smpdtfmt.h>
 #include <unicode/locid.h>
 #include <unicode/udat.h>
@@ -36,6 +37,7 @@
 #include <unicode/calendar.h>
 #include <libintl.h>
 #include <locale.h>
+#include<chrono>
 #include <map>
 #include <memory>
 #include <iostream>
@@ -176,6 +178,10 @@ LDT_from_unix_local(const time64 time)
     {
         throw(std::invalid_argument("Time value is outside the supported year range."));
     }
+    catch(std::out_of_range&)
+    {
+        throw(std::invalid_argument("Time value is outside the supported year range."));
+    }
 }
 /* If a date-time falls in a DST transition the LDT constructor will
  * fail because either the date-time doesn't exist (when starting DST
@@ -227,6 +233,10 @@ LDT_from_date_time(const Date& tdate, const Duration& tdur, const TZ_Ptr tz)
     {
         throw(std::invalid_argument("Time value is outside the supported year range."));
     }
+    catch(std::out_of_range&)
+    {
+        throw(std::invalid_argument("Time value is outside the supported year range."));
+    }
 
 }
 
@@ -274,6 +284,10 @@ LDT_from_struct_tm(const struct tm tm)
     {
         throw(std::invalid_argument{"Time value is outside the supported year range."});
     }
+    catch(std::out_of_range&)
+    {
+        throw(std::invalid_argument("Time value is outside the supported year range."));
+    }
 }
 
 void
@@ -291,7 +305,10 @@ _reset_tzp()
 class GncDateTimeImpl
 {
 public:
-    GncDateTimeImpl() : m_time(boost::local_time::local_sec_clock::local_time(tzp->get(boost::gregorian::day_clock::local_day().year()))) {}
+  /* Boost::date_time's localtime function relies on the C library's, so it may
+   * suffer from the 2038 failure. std::chrono is supposed to be immune to that.
+   */
+    GncDateTimeImpl() : m_time(LDT_from_unix_local(std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count())) {}
     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 GncDateImpl& date, DayPart part = DayPart::neutral);
@@ -451,6 +468,10 @@ GncDateTimeImpl::GncDateTimeImpl(const char* str) :
     {
         throw(std::invalid_argument("The date string was outside of the supported year range."));
     }
+    catch(std::out_of_range&)
+    {
+        throw(std::invalid_argument("The date string was outside of the supported year range."));
+    }
     /* Bug 767824: A GLib bug in parsing the UTC timezone on Windows may have
      * created a bogus timezone of a random number of minutes. Since there are
      * no fractional-hour timezones around the prime meridian we can safely
diff --git a/libgnucash/engine/gnc-timezone.cpp b/libgnucash/engine/gnc-timezone.cpp
index 5653e02c98..6c17e105ea 100644
--- a/libgnucash/engine/gnc-timezone.cpp
+++ b/libgnucash/engine/gnc-timezone.cpp
@@ -700,6 +700,9 @@ TimeZoneProvider::parse_file(const std::string& tzname)
             }
         }
         catch(const boost::gregorian::bad_year& err)
+        {
+            continue;
+        } catch (std::out_of_range &)
         {
             continue;
         }



Summary of changes:
 libgnucash/engine/gnc-datetime.cpp | 23 ++++++++++++++++++++++-
 libgnucash/engine/gnc-timezone.cpp |  3 +++
 2 files changed, 25 insertions(+), 1 deletion(-)



More information about the gnucash-changes mailing list