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) &regtzi, &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