From b5bc6463a313beeb7b58470d0ff87f0c08135bc0 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Mon, 12 Sep 2022 18:17:12 -0700 Subject: [PATCH] [price-quotes] Rework date-time handling. A check of the F::Q modules found that the only ones that return a quote time return a bogus one and do so only to mollify GnuCash. Since there's no good way to determine the TZ of the exchange originating the quote there's no good way to decide if the quote is current or from a previous market session, so we just punt and use a time of 16:00 for all quotes. --- libgnucash/app-utils/gnc-quotes.cpp | 49 ++++++++++++++++++----------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/libgnucash/app-utils/gnc-quotes.cpp b/libgnucash/app-utils/gnc-quotes.cpp index 7d93f20a70..94dc064c83 100644 --- a/libgnucash/app-utils/gnc-quotes.cpp +++ b/libgnucash/app-utils/gnc-quotes.cpp @@ -410,32 +410,45 @@ parse_quote_json(PriceParams& p, const bpt::ptree& comm_pt) static time64 calc_price_time(const PriceParams& p) { - time64 quote_time; - std::string iso_date_str = GncDate().format ("%Y-%m-%d"); + /* Note that as of F::Q v. 1.52 the only sources that provide + * quote times are ftfunds (aka ukfunds), morningstarch, and + * mstaruk_fund, but it's faked with a comment "Set a dummy time + * as gnucash insists on having a valid format". It's also wrong, + * as it lacks seconds. Best ignored. + */ if (p.date) { - // Returned date is always in MM/DD/YYYY format according to F::Q man page, transform it to simplify conversion to GncDateTime + /* Returned date is always in MM/DD/YYYY format according to + * F::Q man page, transform it to simplify conversion to + * GncDateTime. + */ auto date_tmp = *p.date; - iso_date_str = date_tmp.substr (6, 4) + "-" + date_tmp.substr (0, 2) + "-" + date_tmp.substr (3, 2); + auto iso_date_str = date_tmp.substr (6, 4) + "-" + date_tmp.substr (0, 2) + + "-" + date_tmp.substr (3, 2); + try + { + auto close_time{GncDateTime(iso_date_str + " 16:00:00")}; + PINFO("Quote date included, using %s for %s:%s", + close_time.format("%Y-%m-%d %H:%M:%S").c_str(), p.ns, p.mnemonic); + return static_cast(close_time); + } + catch (...) + { + auto now{GncDateTime()}; + PWARN("Warning: failed to parse quote date '%s' for %s:%s - will use %s", + iso_date_str.c_str(), p.ns, p.mnemonic, now.format("%Y-%m-%d %H:%M%S").c_str()); + return static_cast(now); + } } else - PINFO("Info: no date was returned for %s:%s - will use today %s", - p.ns, p.mnemonic, - (iso_date_str += " " + (p.time ? *p.time : "12:00:00")).c_str()); - - auto can_convert = true; - try - { - quote_time = static_cast(GncDateTime{iso_date_str}); - } - catch (...) { - PINFO("Warning: failed to parse quote date and time '%s' for %s:%s - will use today", - iso_date_str.c_str(), p.ns, p.mnemonic); - quote_time = static_cast(GncDateTime()); + auto now{GncDateTime()}; + PINFO("Info: no date was returned for %s:%s - will use %s", + p.ns, p.mnemonic, now.format("%Y-%m-%d %H:%M%S").c_str()); + return static_cast(now); } - return quote_time; + return INT64_MAX; //Shouldn't be able to get here. } static boost::optional