diff --git a/include/wx/datetime.h b/include/wx/datetime.h index e6b271c60c..8ed8dfcbda 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -306,7 +306,9 @@ public: return tz; } - long GetOffset() const { return m_offset; } + bool IsLocal() const { return m_offset == -1; } + + long GetOffset() const; private: // offset for this timezone from GMT in seconds diff --git a/interface/wx/datetime.h b/interface/wx/datetime.h index 0f9eb55966..289ac1da48 100644 --- a/interface/wx/datetime.h +++ b/interface/wx/datetime.h @@ -254,6 +254,17 @@ public: /// Create a time zone with the given offset in seconds. static TimeZone Make(long offset); + /** + Return true if this is the local time zone. + + This method can be useful for distinguishing between UTC time zone + and local time zone in Great Britain, which use the same offset as + UTC (i.e. 0), but do use DST. + + @since 3.1.1 + */ + bool IsLocal() const; + /// Return the offset of this time zone from UTC, in seconds. long GetOffset() const; }; diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 1fda366782..5b6013b8a8 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -456,9 +456,8 @@ wxDateTime::TimeZone::TimeZone(wxDateTime::TZ tz) switch ( tz ) { case wxDateTime::Local: - // get the offset from C RTL: it returns the difference GMT-local - // while we want to have the offset _from_ GMT, hence the '-' - m_offset = -wxGetTimeZone(); + // Use a special value for local time zone. + m_offset = -1; break; case wxDateTime::GMT_12: @@ -503,6 +502,13 @@ wxDateTime::TimeZone::TimeZone(wxDateTime::TZ tz) } } +long wxDateTime::TimeZone::GetOffset() const +{ + // get the offset from C RTL: it returns the difference GMT-local + // while we want to have the offset _from_ GMT, hence the '-' + return m_offset == -1 ? -wxGetTimeZone() : m_offset; +} + // ---------------------------------------------------------------------------- // static functions // ---------------------------------------------------------------------------- @@ -1432,7 +1438,7 @@ unsigned long wxDateTime::GetAsDOS() const const tm* wxTryGetTm(tm& tmstruct, time_t t, const wxDateTime::TimeZone& tz) { - if ( tz.GetOffset() == -wxGetTimeZone() ) + if ( tz.IsLocal() ) { // we are working with local time return wxLocaltime_r(&t, &tmstruct); diff --git a/tests/datetime/datetimetest.cpp b/tests/datetime/datetimetest.cpp index fdcd9f70cb..0ae4321900 100644 --- a/tests/datetime/datetimetest.cpp +++ b/tests/datetime/datetimetest.cpp @@ -683,7 +683,7 @@ void DateTimeTestCase::TestTimeFormat() const long timeZonesOffsets[] = { - wxDateTime::TimeZone(wxDateTime::Local).GetOffset(), + -1, // This is pseudo-offset used for local time zone // Fictitious TimeZone offsets to ensure time zone formating and // interpretation works @@ -1638,4 +1638,27 @@ TEST_CASE("wxDateTime::SetOnDST", "[datetime][dst]") } } +// Tests random problems that used to appear in BST time zone during DST. +// This test is disabled by default as it only passes in BST time zone, due to +// the times hard-coded in it. +TEST_CASE("wxDateTime-BST-bugs", "[datetime][dst][BST][.]") +{ + SECTION("bug-17220") + { + wxDateTime dt; + dt.Set(22, wxDateTime::Oct, 2015, 10, 10, 10, 10); + REQUIRE( dt.IsDST() ); + + CHECK( dt.GetTm().hour == 10 ); + CHECK( dt.GetTm(wxDateTime::UTC).hour == 9 ); + + CHECK( dt.Format("%Y-%m-%d %H:%M:%S", wxDateTime::Local ) == "2015-10-22 10:10:10" ); + CHECK( dt.Format("%Y-%m-%d %H:%M:%S", wxDateTime::UTC ) == "2015-10-22 09:10:10" ); + + dt.MakeFromUTC(); + CHECK( dt.Format("%Y-%m-%d %H:%M:%S", wxDateTime::Local ) == "2015-10-22 11:10:10" ); + CHECK( dt.Format("%Y-%m-%d %H:%M:%S", wxDateTime::UTC ) == "2015-10-22 10:10:10" ); + } +} + #endif // wxUSE_DATETIME