gnucash maint: Multiple changes pushed
John Ralls
jralls at code.gnucash.org
Fri Apr 27 18:00:50 EDT 2018
Updated via https://github.com/Gnucash/gnucash/commit/9c4469d0 (commit)
via https://github.com/Gnucash/gnucash/commit/83e993fb (commit)
via https://github.com/Gnucash/gnucash/commit/f6855bc0 (commit)
from https://github.com/Gnucash/gnucash/commit/3e41bb01 (commit)
commit 9c4469d0399164697f6716d0e960daa7fbe259f2
Author: John Ralls <jralls at ceridwen.us>
Date: Fri Apr 27 13:27:47 2018 -0700
Bug 795405 - All Dates in Price Database Off-By-One After 3.0 Upgrade
Also Bug 791825 - Accounting Period dates off by 1.
The DST start/end dates were reversed *and* the DST offset had the wrong
sign in Windows, resulting in the effective timezone always being one to
the west off (i.e. PDT was -9 and PST was -8).
diff --git a/libgnucash/engine/gnc-timezone.cpp b/libgnucash/engine/gnc-timezone.cpp
index 3d6959f..876df2a 100644
--- a/libgnucash/engine/gnc-timezone.cpp
+++ b/libgnucash/engine/gnc-timezone.cpp
@@ -150,9 +150,15 @@ zone_from_regtzi (const RegTZI& regtzi, time_zone_names names)
{
using ndate = boost::gregorian::nth_day_of_the_week_in_month;
using nth_day_rule = boost::local_time::nth_day_of_the_week_in_month_dst_rule;
-
+ /* Note that Windows runs its biases backwards from POSIX and
+ * boost::date_time: It's the value added to the local time to get
+ * GMT rather than the value added to GMT to get local time; for
+ * the same reason the DaylightBias is negative as one generally
+ * adds an hour less to the local time to get GMT. Biases are in
+ * minutes.
+ */
duration std_off (0, regtzi.StandardBias - regtzi.Bias, 0);
- duration dlt_off (0, regtzi.DaylightBias, 0);
+ duration dlt_off (0, -regtzi.DaylightBias, 0);
duration start_time (regtzi.StandardDate.wHour, regtzi.StandardDate.wMinute,
regtzi.StandardDate.wSecond);
duration end_time (regtzi.DaylightDate.wHour, regtzi.DaylightDate.wMinute,
@@ -165,10 +171,10 @@ zone_from_regtzi (const RegTZI& regtzi, time_zone_names names)
{
try
{
- ndate start (std_week_num, regtzi.StandardDate.wDayOfWeek,
- regtzi.StandardDate.wMonth);
- ndate end(dlt_week_num, regtzi.DaylightDate.wDayOfWeek,
- regtzi.DaylightDate.wMonth);
+ ndate start (dlt_week_num, regtzi.DaylightDate.wDayOfWeek,
+ regtzi.DaylightDate.wMonth);
+ ndate end(std_week_num, regtzi.StandardDate.wDayOfWeek,
+ regtzi.StandardDate.wMonth);
dates.reset(new nth_day_rule (start, end));
}
catch (boost::gregorian::bad_month& err)
diff --git a/libgnucash/engine/test/gtest-gnc-timezone.cpp b/libgnucash/engine/test/gtest-gnc-timezone.cpp
index 963466c..a676ff1 100644
--- a/libgnucash/engine/test/gtest-gnc-timezone.cpp
+++ b/libgnucash/engine/test/gtest-gnc-timezone.cpp
@@ -46,17 +46,21 @@ TEST(gnc_timezone_constructors, test_pacific_time_constructor)
TimeZoneProvider tzp (timezone);
EXPECT_NO_THROW (tzp.get(2012));
TZ_Ptr tz = tzp.get (2012);
-
EXPECT_FALSE(tz->std_zone_abbrev().empty());
#if PLATFORM(WINDOWS)
EXPECT_TRUE(tz->std_zone_abbrev() == timezone);
+ EXPECT_TRUE(tz->dst_zone_abbrev() == "Pacific Daylight Time");
#else
EXPECT_TRUE(tz->std_zone_abbrev() == "PST");
EXPECT_TRUE(tz->dst_zone_abbrev() == "PDT");
#endif
EXPECT_EQ(-8, tz->base_utc_offset().hours());
-
+ auto dst_offset = tz->base_utc_offset() + tz->dst_offset();
+ EXPECT_EQ(-7, dst_offset.hours());
EXPECT_EQ(12, tz->dst_local_start_time (2017).date().day());
+ EXPECT_EQ(3, tz->dst_local_start_time (2017).date().month());
+ EXPECT_EQ(5, tz->dst_local_end_time (2017).date().day());
+ EXPECT_EQ(11, tz->dst_local_end_time (2017).date().month());
}
#if !PLATFORM(WINDOWS)
@@ -284,8 +288,13 @@ TEST(gnc_timezone_constructors, test_IANA_Minsk_tz)
TEST(gnc_timezone_constructors, test_bogus_time_constructor)
{
+#if PLATFORM(WINDOWS)
+ EXPECT_THROW(TimeZoneProvider tzp ("New York Standard Time"),
+ std::invalid_argument);
+#else
TimeZoneProvider tzp ("New York Standard Time");
TimeZoneProvider machine ("");
EXPECT_EQ(machine.get(2006)->std_zone_abbrev(),
tzp.get(2006)->std_zone_abbrev());
+#endif
}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index dc896a7..9cdb537 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -449,7 +449,6 @@ gnucash/report/report-system/html-acct-table.scm
gnucash/report/report-system/html-barchart.scm
gnucash/report/report-system/html-document.scm
gnucash/report/report-system/html-fonts.scm
-gnucash/report/report-system/html-jqplot.scm
gnucash/report/report-system/html-linechart.scm
gnucash/report/report-system/html-piechart.scm
gnucash/report/report-system/html-scatter.scm
commit 83e993fb80ebc94c13fd4239e0321406bdf4bc6f
Author: John Ralls <jralls at ceridwen.us>
Date: Fri Apr 27 13:27:28 2018 -0700
Add a TimeZoneProvider::dump().
Because gdb can't always see clearly inside m_zone_vector.
diff --git a/libgnucash/engine/gnc-timezone.cpp b/libgnucash/engine/gnc-timezone.cpp
index a60436a..3d6959f 100644
--- a/libgnucash/engine/gnc-timezone.cpp
+++ b/libgnucash/engine/gnc-timezone.cpp
@@ -739,3 +739,10 @@ TimeZoneProvider::get(int year) const noexcept
return m_zone_vector.front().second;
return iter->second;
}
+
+void
+TimeZoneProvider::dump() const noexcept
+{
+ for (auto zone : m_zone_vector)
+ std::cout << zone.first << ": " << zone.second->to_posix_string() << "\n";
+}
diff --git a/libgnucash/engine/gnc-timezone.hpp b/libgnucash/engine/gnc-timezone.hpp
index 425bd94..c533cfd 100644
--- a/libgnucash/engine/gnc-timezone.hpp
+++ b/libgnucash/engine/gnc-timezone.hpp
@@ -55,6 +55,7 @@ public:
TimeZoneProvider operator=(const TimeZoneProvider&) = delete;
TimeZoneProvider operator=(const TimeZoneProvider&&) = delete;
TZ_Ptr get (int year) const noexcept;
+ void dump() const noexcept;
static const unsigned int min_year; //1400
static const unsigned int max_year; //9999
private:
commit f6855bc0f8eaf39cf3a4670d37e113c5b056af56
Author: John Ralls <jralls at ceridwen.us>
Date: Fri Apr 27 13:23:33 2018 -0700
Rename zone_vector to m_zone_vector.
To comply with coding spec.
diff --git a/libgnucash/engine/gnc-timezone.cpp b/libgnucash/engine/gnc-timezone.cpp
index 96f164c..a60436a 100644
--- a/libgnucash/engine/gnc-timezone.cpp
+++ b/libgnucash/engine/gnc-timezone.cpp
@@ -214,10 +214,10 @@ TimeZoneProvider::load_windows_dynamic_tz (HKEY key, time_zone_names names)
}
tz = zone_from_regtzi (regtzi, names);
if (year == first)
- zone_vector.push_back (std::make_pair(0, tz));
- zone_vector.push_back (std::make_pair(year, tz));
+ m_zone_vector.push_back (std::make_pair(0, tz));
+ m_zone_vector.push_back (std::make_pair(year, tz));
}
- zone_vector.push_back (std::make_pair(max_year, tz));
+ m_zone_vector.push_back (std::make_pair(max_year, tz));
}
catch (std::invalid_argument)
{
@@ -242,7 +242,7 @@ TimeZoneProvider::load_windows_classic_tz (HKEY key, time_zone_names names)
if (RegQueryValueExA (key, "TZI", NULL, NULL,
(LPBYTE) ®tzi, &size) == ERROR_SUCCESS)
{
- zone_vector.push_back(
+ m_zone_vector.push_back(
std::make_pair(max_year, zone_from_regtzi (regtzi, names)));
}
}
@@ -267,11 +267,11 @@ TimeZoneProvider::load_windows_default_tz()
auto dlt_name = utf_to_utf<char>(tzi.DaylightName,
tzi.DaylightName + sizeof(tzi.DaylightName));
time_zone_names names (std_name, std_name, dlt_name, dlt_name);
- zone_vector.push_back(std::make_pair(max_year, zone_from_regtzi(regtzi, names)));
+ m_zone_vector.push_back(std::make_pair(max_year, zone_from_regtzi(regtzi, names)));
}
TimeZoneProvider::TimeZoneProvider (const std::string& identifier) :
- zone_vector ()
+ m_zone_vector ()
{
HKEY key;
const std::string reg_key =
@@ -632,13 +632,13 @@ TimeZoneProvider::parse_file(const std::string& tzname)
//Initial case
if (last_time.is_not_a_date_time())
{
- zone_vector.push_back(zone_no_dst(this_year - 1, last_info));
- zone_vector.push_back(zone_no_dst(this_year, this_info));
+ m_zone_vector.push_back(zone_no_dst(this_year - 1, last_info));
+ m_zone_vector.push_back(zone_no_dst(this_year, this_info));
}
// No change in is_dst means a permanent zone change.
else if (last_info->info.isdst == this_info->info.isdst)
{
- zone_vector.push_back(zone_no_dst(this_year, this_info));
+ m_zone_vector.push_back(zone_no_dst(this_year, this_info));
}
/* If there have been no transitions in at least a year
* then we need to create a no-DST rule with last_info to
@@ -647,9 +647,9 @@ TimeZoneProvider::parse_file(const std::string& tzname)
else if (this_time - last_time > one_year)
{
auto year = last_time.date().year();
- if (zone_vector.back().first == year)
+ if (m_zone_vector.back().first == year)
year = year + 1; // no operator ++ or +=, sigh.
- zone_vector.push_back(zone_no_dst(year, last_info));
+ m_zone_vector.push_back(zone_no_dst(year, last_info));
}
/* It's been less than a year, so it's probably a DST
* cycle. This consumes two transitions so we want only
@@ -663,7 +663,7 @@ TimeZoneProvider::parse_file(const std::string& tzname)
{
last_rule = new_rule;
auto year = last_time.date().year();
- zone_vector.push_back(zone_from_rule(year, new_rule));
+ m_zone_vector.push_back(zone_from_rule(year, new_rule));
}
}
}
@@ -678,9 +678,9 @@ TimeZoneProvider::parse_file(const std::string& tzname)
* period then the zone rescinded DST and we need a final no-dstzone.
*/
if (last_time.is_not_a_date_time())
- zone_vector.push_back(zone_no_dst(max_year, last_info));
+ m_zone_vector.push_back(zone_no_dst(max_year, last_info));
else if (last_time.date().year() < parser.last_year)
- zone_vector.push_back(zone_no_dst(last_time.date().year(), last_info));
+ m_zone_vector.push_back(zone_no_dst(last_time.date().year(), last_info));
}
bool
@@ -695,7 +695,7 @@ TimeZoneProvider::construct(const std::string& tzname)
try
{
TZ_Ptr zone(new PTZ(tzname));
- zone_vector.push_back(std::make_pair(max_year, zone));
+ m_zone_vector.push_back(std::make_pair(max_year, zone));
}
catch(std::exception& err)
{
@@ -705,7 +705,7 @@ TimeZoneProvider::construct(const std::string& tzname)
return true;
}
-TimeZoneProvider::TimeZoneProvider(const std::string& tzname) : zone_vector {}
+TimeZoneProvider::TimeZoneProvider(const std::string& tzname) : m_zone_vector {}
{
if(construct(tzname))
return;
@@ -722,7 +722,7 @@ TimeZoneProvider::TimeZoneProvider(const std::string& tzname) : zone_vector {}
{
DEBUG("/etc/localtime invalid, resorting to GMT.");
TZ_Ptr zone(new PTZ("UTC0"));
- zone_vector.push_back(std::make_pair(max_year, zone));
+ m_zone_vector.push_back(std::make_pair(max_year, zone));
}
}
#endif
@@ -731,11 +731,11 @@ TimeZoneProvider::TimeZoneProvider(const std::string& tzname) : zone_vector {}
TZ_Ptr
TimeZoneProvider::get(int year) const noexcept
{
- if (zone_vector.empty())
+ if (m_zone_vector.empty())
return TZ_Ptr(new PTZ("UTC0"));
- auto iter = find_if(zone_vector.rbegin(), zone_vector.rend(),
+ auto iter = find_if(m_zone_vector.rbegin(), m_zone_vector.rend(),
[=](TZ_Entry e) { return e.first <= year; });
- if (iter == zone_vector.rend())
- return zone_vector.front().second;
+ if (iter == m_zone_vector.rend())
+ return m_zone_vector.front().second;
return iter->second;
}
diff --git a/libgnucash/engine/gnc-timezone.hpp b/libgnucash/engine/gnc-timezone.hpp
index 9bb0ead..425bd94 100644
--- a/libgnucash/engine/gnc-timezone.hpp
+++ b/libgnucash/engine/gnc-timezone.hpp
@@ -60,7 +60,7 @@ public:
private:
void parse_file(const std::string& tzname);
bool construct(const std::string& tzname);
- TZ_Vector zone_vector;
+ TZ_Vector m_zone_vector;
#if PLATFORM(WINDOWS)
void load_windows_dynamic_tz(HKEY, time_zone_names);
void load_windows_classic_tz(HKEY, time_zone_names);
Summary of changes:
libgnucash/engine/gnc-timezone.cpp | 67 ++++++++++++++++-----------
libgnucash/engine/gnc-timezone.hpp | 3 +-
libgnucash/engine/test/gtest-gnc-timezone.cpp | 13 +++++-
po/POTFILES.in | 1 -
4 files changed, 53 insertions(+), 31 deletions(-)
More information about the gnucash-changes
mailing list