From ebb62db0fc2a03ff4e07fdfbe7e11815b98b6142 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 19 Apr 2017 16:47:36 +0200 Subject: [PATCH] Revert wrong fix for wxDateTime timezone conversion to/from local This reverts commit aaddf6be7f6a1b1ea4f7c316a25251d408e14825 as it broke handling of dates when local time zone is BST, whose offset not counting DST is 0, as for UTC, but which still should be handled as local timezone, see #17220. With the current wxDateTime handling of time zones, FromTimezone(Local) doesn't make much sense anyhow, so abandon attempts to try making it work as to really do it we need to specify the time zone being converted from too, as explained in the second point of #10445. See #16585. (cherry picked from commit f6d9d7962e2887976c7ad453c80011252d49b6a2) --- interface/wx/datetime.h | 29 ++++++++++++++++++++++------- src/common/datetime.cpp | 8 ++------ tests/datetime/datetimetest.cpp | 21 +++++++++++++++++++++ 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/interface/wx/datetime.h b/interface/wx/datetime.h index e8d43ec2c2..3b900cb3a6 100644 --- a/interface/wx/datetime.h +++ b/interface/wx/datetime.h @@ -1200,10 +1200,17 @@ public: //@{ /** - Transform the date from the given time zone to the local one. If - @a noDST is @true, no DST adjustments will be made. + Transform the date from the given time zone to the local one. - @return The date in the local time zone. + If @a noDST is @true, no DST adjustments will be made. + + Notice using wxDateTime::Local for @a tz parameter doesn't really make + sense and may result in unexpected results as it will return a + different object when DST is in use and @a noDST has its default value + of @false. + + @return The date adjusted by the different between the given and the + local time zones. */ wxDateTime FromTimezone(const TimeZone& tz, bool noDST = false) const; @@ -1221,7 +1228,9 @@ public: /** Modifies the object in place to represent the date in another time - zone. If @a noDST is @true, no DST adjustments will be made. + zone. + + If @a noDST is @true, no DST adjustments will be made. */ wxDateTime& MakeTimezone(const TimeZone& tz, bool noDST = false); @@ -1231,10 +1240,16 @@ public: wxDateTime& MakeUTC(bool noDST = false); /** - Transform the date to the given time zone. If @a noDST is @true, no DST - adjustments will be made. + Transform the date to the given time zone. - @return The date in the new time zone. + If @a noDST is @true, no DST adjustments will be made. + + Notice that, as with FromTimezone(), using wxDateTime::Local as @a tz + doesn't really make sense and may return a different object when DST is + in effect and @a noDST is @false. + + @return The date adjusted by the different between the local and the + given time zones. */ wxDateTime ToTimezone(const TimeZone& tz, bool noDST = false) const; diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 4446a33403..4d65d7e3b6 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -2088,11 +2088,7 @@ wxDateTime& wxDateTime::MakeTimezone(const TimeZone& tz, bool noDST) // include the DST offset (as it varies depending on the date), so we have // to handle DST manually, unless a special flag inhibiting this was // specified. - // - // Notice that we also shouldn't add the DST offset if we're already in the - // local time zone, as indicated by offset of 0, converting from local time - // to local time zone shouldn't change it, whether DST is in effect or not. - if ( !noDST && secDiff && (IsDST() == 1) ) + if ( !noDST && (IsDST() == 1) ) { // FIXME we assume that the DST is always shifted by 1 hour secDiff -= 3600; @@ -2106,7 +2102,7 @@ wxDateTime& wxDateTime::MakeFromTimezone(const TimeZone& tz, bool noDST) long secDiff = wxGetTimeZone() + tz.GetOffset(); // See comment in MakeTimezone() above, the logic here is exactly the same. - if ( !noDST && secDiff && (IsDST() == 1) ) + if ( !noDST && (IsDST() == 1) ) { // FIXME we assume that the DST is always shifted by 1 hour secDiff -= 3600; diff --git a/tests/datetime/datetimetest.cpp b/tests/datetime/datetimetest.cpp index 7005e81fbd..325e868387 100644 --- a/tests/datetime/datetimetest.cpp +++ b/tests/datetime/datetimetest.cpp @@ -232,6 +232,7 @@ private: CPPUNIT_TEST( TestTimeArithmetics ); CPPUNIT_TEST( TestDSTBug ); CPPUNIT_TEST( TestDateOnly ); + CPPUNIT_TEST( TestConvToFromLocalTZ ); CPPUNIT_TEST_SUITE_END(); void TestLeapYears(); @@ -252,6 +253,7 @@ private: void TestTimeArithmetics(); void TestDSTBug(); void TestDateOnly(); + void TestConvToFromLocalTZ(); DECLARE_NO_COPY_CLASS(DateTimeTestCase) }; @@ -1447,4 +1449,23 @@ void DateTimeTestCase::TestDateOnly() CPPUNIT_ASSERT_EQUAL( wxDateTime::Today(), wxDateTime::Now().GetDateOnly() ); } +void DateTimeTestCase::TestConvToFromLocalTZ() +{ + // Choose a date when the DST is on in many time zones: in this case, + // converting to/from local TZ does modify the object because it + // adds/subtracts DST to/from it, so to get the expected results we need to + // explicitly disable DST support in these functions. + wxDateTime dt(18, wxDateTime::Apr, 2017, 19); + + CPPUNIT_ASSERT_EQUAL( dt.FromTimezone(wxDateTime::Local, true), dt ); + CPPUNIT_ASSERT_EQUAL( dt.ToTimezone(wxDateTime::Local, true), dt ); + + // And another one when it is off: in this case, there is no need to pass + // "true" as "noDST" argument to these functions. + dt = wxDateTime(18, wxDateTime::Jan, 2018, 19); + + CPPUNIT_ASSERT_EQUAL( dt.FromTimezone(wxDateTime::Local), dt ); + CPPUNIT_ASSERT_EQUAL( dt.ToTimezone(wxDateTime::Local), dt ); +} + #endif // wxUSE_DATETIME