Replace date parse function with one from gnc_datetime

This commit is contained in:
Robert Fewell 2017-12-07 11:17:14 +00:00
parent 5b02021550
commit db079b5540
5 changed files with 6 additions and 130 deletions

View File

@ -608,10 +608,8 @@ CsvImpPriceAssist::CsvImpPriceAssist ()
/* Add in the date format combo box and hook it up to an event handler. */ /* Add in the date format combo box and hook it up to an event handler. */
date_format_combo = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new()); date_format_combo = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
for (int i = 0; i < num_date_formats_price; i++) for (auto& date_fmt : GncDate::c_formats)
{ gtk_combo_box_text_append_text (date_format_combo, _(date_fmt.m_fmt.c_str()));
gtk_combo_box_text_append_text (date_format_combo, _(date_format_user_price[i]));
}
gtk_combo_box_set_active (GTK_COMBO_BOX(date_format_combo), 0); gtk_combo_box_set_active (GTK_COMBO_BOX(date_format_combo), 0);
g_signal_connect (G_OBJECT(date_format_combo), "changed", g_signal_connect (G_OBJECT(date_format_combo), "changed",
G_CALLBACK(csv_price_imp_preview_date_fmt_sel_cb), this); G_CALLBACK(csv_price_imp_preview_date_fmt_sel_cb), this);

View File

@ -46,14 +46,6 @@ extern "C" {
G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_IMPORT; G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_IMPORT;
const int num_date_formats_price = 5;
const gchar* date_format_user_price[] = {N_("y-m-d"),
N_("d-m-y"),
N_("m-d-y"),
N_("d-m"),
N_("m-d")
};
const int num_currency_formats_price = 3; const int num_currency_formats_price = 3;
const gchar* currency_format_user_price[] = {N_("Locale"), const gchar* currency_format_user_price[] = {N_("Locale"),
N_("Period: 123,456.78"), N_("Period: 123,456.78"),

View File

@ -49,10 +49,6 @@ extern "C" {
extern const int num_currency_formats_price; extern const int num_currency_formats_price;
extern const gchar* currency_format_user_price[]; extern const gchar* currency_format_user_price[];
/* A set of date formats that the user sees. */
extern const int num_date_formats_price;
extern const gchar* date_format_user_price[];
/** Tuple to hold /** Tuple to hold
* - a tokenized line of input * - a tokenized line of input
* - an optional error string * - an optional error string

View File

@ -50,116 +50,6 @@ std::map<GncPricePropType, const char*> gnc_price_col_type_strs = {
{ GncPricePropType::TO_CURRENCY, N_("Currency To") }, { GncPricePropType::TO_CURRENCY, N_("Currency To") },
}; };
/* Regular expressions used to parse dates per date format */
const char* date_regex_price[] = {
"(?:" // either y-m-d
"(?<YEAR>[0-9]+)[-/.' ]+"
"(?<MONTH>[0-9]+)[-/.' ]+"
"(?<DAY>[0-9]+)"
"|" // or CCYYMMDD
"(?<YEAR>[0-9]{4})"
"(?<MONTH>[0-9]{2})"
"(?<DAY>[0-9]{2})"
")",
"(?:" // either d-m-y
"(?<DAY>[0-9]+)[-/.' ]+"
"(?<MONTH>[0-9]+)[-/.' ]+"
"(?<YEAR>[0-9]+)"
"|" // or DDMMCCYY
"(?<DAY>[0-9]{2})"
"(?<MONTH>[0-9]{2})"
"(?<YEAR>[0-9]{4})"
")",
"(?:" // either m-d-y
"(?<MONTH>[0-9]+)[-/.' ]+"
"(?<DAY>[0-9]+)[-/.' ]+"
"(?<YEAR>[0-9]+)"
"|" // or MMDDCCYY
"(?<MONTH>[0-9]{2})"
"(?<DAY>[0-9]{2})"
"(?<YEAR>[0-9]{4})"
")",
"(?:" // either d-m(-y)
"(?<DAY>[0-9]+)[-/.' ]+"
"(?<MONTH>[0-9]+)(?:[-/.' ]+"
"(?<YEAR>[0-9]+))?"
"|" // or DDMM(CCYY)
"(?<DAY>[0-9]{2})"
"(?<MONTH>[0-9]{2})"
"(?<YEAR>[0-9]+)?"
")",
"(?:" // either m-d(-y)
"(?<MONTH>[0-9]+)[-/.' ]+"
"(?<DAY>[0-9]+)(?:[-/.' ]+"
"(?<YEAR>[0-9]+))?"
"|" // or MMDD(CCYY)
"(?<MONTH>[0-9]{2})"
"(?<DAY>[0-9]{2})"
"(?<YEAR>[0-9]+)?"
")",
};
/** Parses a string into a date, given a format. This function
* requires only knowing the order in which the year, month and day
* appear. For example, 01-02-2003 will be parsed the same way as
* 01/02/2003.
* @param date_str The string containing a date being parsed
* @param format An index specifying a format in date_format_user
* @exception std::invalid_argument if the string can't be parsed into a date.
* @return The parsed value of date_str on success, throws on failure
*/
time64 parse_date_price (const std::string &date_str, int format)
{
boost::regex r(date_regex_price[format]);
boost::smatch what;
if(!boost::regex_search(date_str, what, r))
throw std::invalid_argument (_("Value can't be parsed into a date using the selected date format.")); // regex didn't find a match
// Attention: different behavior from 2.6.x series !
// If date format without year was selected, the match
// should NOT have found a year.
if ((format >= 3) && (what.length("YEAR") != 0))
throw std::invalid_argument (_("Value appears to contain a year while the selected format forbids this."));
auto day = std::stoi (what.str("DAY"));
auto month = std::stoi (what.str("MONTH"));
int year;
if (format < 3)
{
/* The input dates have a year, so use that one */
year = std::stoi (what.str("YEAR"));
/* Handle two-digit years. */
if (year < 100)
{
/* We allow two-digit years in the range 1969 - 2068. */
if (year < 69)
year += 2000;
else
year += 1900;
}
}
else
{
/* The input dates don't have a year, so work with today's year.
*/
gnc_timespec2dmy(timespec_now(), nullptr, nullptr, &year);
}
auto ts = gnc_dmy2timespec_neutral(day, month, year);
if (ts.tv_sec == INT64_MAX)
throw std::invalid_argument (_("Value can't be parsed into a date using the selected date format."));
return ts.tv_sec;
}
/** Convert str into a GncNumeric using the user-specified (import) currency format. /** Convert str into a GncNumeric using the user-specified (import) currency format.
* @param str The string to be parsed * @param str The string to be parsed
* @param currency_format The currency format to use. * @param currency_format The currency format to use.
@ -257,7 +147,7 @@ void GncImportPrice::set (GncPricePropType prop_type, const std::string& value)
{ {
case GncPricePropType::DATE: case GncPricePropType::DATE:
m_date = boost::none; m_date = boost::none;
m_date = parse_date_price (value, m_date_format); // Throws if parsing fails m_date = GncDate(value, GncDate::c_formats[m_date_format].m_fmt); // Throws if parsing fails
break; break;
case GncPricePropType::AMOUNT: case GncPricePropType::AMOUNT:
@ -357,7 +247,7 @@ Result GncImportPrice::create_price (QofBook* book, GNCPriceDB *pdb, bool over)
} }
Timespec date; Timespec date;
timespecFromTime64 (&date, *m_date); timespecFromTime64 (&date, static_cast<time64>(GncDateTime(*m_date, DayPart::neutral)));
date.tv_nsec = 0; date.tv_nsec = 0;
bool rev = false; bool rev = false;

View File

@ -39,6 +39,7 @@ extern "C" {
#include <map> #include <map>
#include <memory> #include <memory>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <gnc-datetime.hpp>
#include <gnc-numeric.hpp> #include <gnc-numeric.hpp>
/** Enumeration for column types. These are the different types of /** Enumeration for column types. These are the different types of
@ -76,7 +77,6 @@ private:
const char *m_name; const char *m_name;
}; };
time64 parse_date_price (const std::string &date_str, int format);
gnc_commodity* parse_commodity_price_comm (const std::string& comm_str); gnc_commodity* parse_commodity_price_comm (const std::string& comm_str);
GncNumeric parse_amount_price (const std::string &str, int currency_format); GncNumeric parse_amount_price (const std::string &str, int currency_format);
@ -104,7 +104,7 @@ public:
private: private:
int m_date_format; int m_date_format;
int m_currency_format; int m_currency_format;
boost::optional<time64> m_date; boost::optional<GncDate> m_date;
boost::optional<GncNumeric> m_amount; boost::optional<GncNumeric> m_amount;
boost::optional<gnc_commodity*> m_from_commodity; boost::optional<gnc_commodity*> m_from_commodity;
boost::optional<gnc_commodity*> m_to_currency; boost::optional<gnc_commodity*> m_to_currency;