From 2b9053e15d9b47d3f23f7866ce3d5b6f65e6fb2c Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Sun, 8 Sep 2024 22:52:35 +0800 Subject: [PATCH] [gnc-datetime] add boost UK/US/ISO date parsers Thus "30 Sep 2024" and "30 September 2024" are accepted. But ICU's "30 Sept 2024" is rightfully rejected. --- libgnucash/engine/gnc-datetime.cpp | 10 ++++++++++ libgnucash/engine/gnc-datetime.hpp | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/libgnucash/engine/gnc-datetime.cpp b/libgnucash/engine/gnc-datetime.cpp index 308ec24e4ef..af0cd6ba0c0 100644 --- a/libgnucash/engine/gnc-datetime.cpp +++ b/libgnucash/engine/gnc-datetime.cpp @@ -84,6 +84,10 @@ static constexpr auto ticks_per_second = INT64_C(1000000000); * without separators. */ const std::vector GncDate::c_formats ({ + GncDateFormat { N_("UK date"), boost::gregorian::from_uk_string }, + GncDateFormat { N_("US date"), boost::gregorian::from_us_string }, + GncDateFormat { N_("ISO delimited date"), boost::gregorian::from_string }, + GncDateFormat { N_("ISO date"), boost::gregorian::from_undelimited_string }, GncDateFormat { N_("y-m-d"), "(?:" // either y-m-d @@ -617,6 +621,12 @@ GncDateImpl::GncDateImpl(const std::string str, const std::string fmt) : if (iter == GncDate::c_formats.cend()) throw std::invalid_argument(N_("Unknown date format specifier passed as argument.")); + if (iter->m_str_to_date) + { + m_greg = (*iter->m_str_to_date)(str); + return; + } + boost::regex r(iter->m_re); boost::smatch what; if(!boost::regex_search(str, what, r)) // regex didn't find a match diff --git a/libgnucash/engine/gnc-datetime.hpp b/libgnucash/engine/gnc-datetime.hpp index 77a6039b10a..edb4535133a 100644 --- a/libgnucash/engine/gnc-datetime.hpp +++ b/libgnucash/engine/gnc-datetime.hpp @@ -29,6 +29,10 @@ #include #include #include +#include +#include + +#include typedef struct { @@ -172,6 +176,8 @@ class GncDateTime * GncDate::c_formats class variable and work with those. */ +using OptionalStringToDate = std::optional>; + class GncDateFormat { public: @@ -182,6 +188,8 @@ class GncDateFormat */ GncDateFormat (const char* fmt, const char* re) : m_fmt(fmt), m_re(re) {} + GncDateFormat (const char* fmt, OptionalStringToDate str_to_date) : + m_fmt(fmt), m_str_to_date(str_to_date) {} /** A string representing the format. */ const std::string m_fmt; private: @@ -189,6 +197,7 @@ class GncDateFormat * only be used internally by the gnc-datetime code. */ const std::string m_re; + OptionalStringToDate m_str_to_date; friend class GncDateImpl; };