From 69bf156eb0a8523f64a8f90a3a183d7901be86d6 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 | 13 +++++++++++-- libgnucash/engine/gnc-datetime.hpp | 9 +++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/libgnucash/engine/gnc-datetime.cpp b/libgnucash/engine/gnc-datetime.cpp index 308ec24e4ef..e5d6cc789d1 100644 --- a/libgnucash/engine/gnc-datetime.cpp +++ b/libgnucash/engine/gnc-datetime.cpp @@ -77,13 +77,16 @@ static constexpr auto ticks_per_second = INT64_C(1000000); static constexpr auto ticks_per_second = INT64_C(1000000000); #endif -/* Vector of date formats understood by gnucash and corresponding regex - * to parse each from an external source +/* Vector of date formats understood by gnucash and corresponding + * boost string->date or regex to parse each from an external source * Note: while the format names are using a "-" as separator, the * regexes will accept any of "-/.' " and will also work for dates * 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 date"), boost::gregorian::from_string }, GncDateFormat { N_("y-m-d"), "(?:" // either y-m-d @@ -617,6 +620,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..677fdd59a3a 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 StringToDate = std::function; + 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, StringToDate 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; + std::optional m_str_to_date; friend class GncDateImpl; };