Skip to content

Commit

Permalink
[gnc-datetime] add boost UK/US/ISO date parsers
Browse files Browse the repository at this point in the history
Thus "30 Sep 2024" and "30 September 2024" are accepted.
But ICU's "30 Sept 2024" is rightfully rejected.
  • Loading branch information
christopherlam committed Sep 8, 2024
1 parent d935ede commit 2b9053e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
10 changes: 10 additions & 0 deletions libgnucash/engine/gnc-datetime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ static constexpr auto ticks_per_second = INT64_C(1000000000);
* without separators.
*/
const std::vector<GncDateFormat> 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
Expand Down Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions libgnucash/engine/gnc-datetime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#include <memory>
#include <string>
#include <vector>
#include <functional>
#include <optional>

#include <boost/date_time/gregorian/gregorian.hpp>

typedef struct
{
Expand Down Expand Up @@ -172,6 +176,8 @@ class GncDateTime
* GncDate::c_formats class variable and work with those.
*/

using OptionalStringToDate = std::optional<std::function<boost::gregorian::date(const std::string&)>>;

class GncDateFormat
{
public:
Expand All @@ -182,13 +188,16 @@ 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:
/** Regular expression associated with the format string. This is to and
* only be used internally by the gnc-datetime code.
*/
const std::string m_re;
OptionalStringToDate m_str_to_date;

friend class GncDateImpl;
};
Expand Down

0 comments on commit 2b9053e

Please sign in to comment.