diff --git a/interface/wx/datetime.h b/interface/wx/datetime.h index f38ad46596..6a3778a653 100644 --- a/interface/wx/datetime.h +++ b/interface/wx/datetime.h @@ -1237,10 +1237,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; @@ -1258,7 +1265,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); @@ -1268,10 +1277,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 ae6b9a384b..a1ef82772b 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -2064,11 +2064,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; @@ -2082,7 +2078,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 1b3513bfb9..0206169ac2 100644 --- a/tests/datetime/datetimetest.cpp +++ b/tests/datetime/datetimetest.cpp @@ -233,6 +233,7 @@ private: CPPUNIT_TEST( TestDSTBug ); CPPUNIT_TEST( TestDateOnly ); CPPUNIT_TEST( TestTranslateFromUnicodeFormat ); + CPPUNIT_TEST( TestConvToFromLocalTZ ); CPPUNIT_TEST_SUITE_END(); void TestLeapYears(); @@ -254,6 +255,7 @@ private: void TestDSTBug(); void TestDateOnly(); void TestTranslateFromUnicodeFormat(); + void TestConvToFromLocalTZ(); wxDECLARE_NO_COPY_CLASS(DateTimeTestCase); }; @@ -1491,4 +1493,23 @@ void DateTimeTestCase::TestTranslateFromUnicodeFormat() #endif // ports having wxTranslateFromUnicodeFormat() } +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