Consistently handle DST start time in wxDateTime::Set().
Always move the dates invalid due to DST (i.e. falling into the "missing" hour on the DST start date) forward, as GNU libc does, even when using a different CRT implementation, such as MSVC one which moves the invalid dates backwards. This seems more expected and also fixes an especially bad problem which happened due to moving the date backwards in Brazilian time zone where DST starts at midnight as doing this changed the day and totally broke ParseDate() assumption that setting wxDateTime to 00:00:00 at the given date really did set it to this date. Closes #15419. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74777 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1129,10 +1129,37 @@ wxDateTime& wxDateTime::Set(const struct tm& tm)
|
||||
|
||||
return *this;
|
||||
}
|
||||
else
|
||||
|
||||
// mktime() only adjusts tm_wday, tm_yday and tm_isdst fields normally, if
|
||||
// it changed anything else, it must have performed the DST adjustment. But
|
||||
// the trouble with this is that different implementations do it
|
||||
// differently, e.g. GNU libc moves the time forward if the specified time
|
||||
// is invalid in the local time zone, while MSVC CRT moves it backwards
|
||||
// which is especially pernicious as it can change the date if the DST
|
||||
// starts at midnight, as it does in some time zones (see #15419), and this
|
||||
// is completely unexpected for the code working with dates only.
|
||||
//
|
||||
// So standardize on moving the time forwards to have consistent behaviour
|
||||
// under all platforms and to avoid the problem above.
|
||||
if ( tm2.tm_hour != tm.tm_hour )
|
||||
{
|
||||
return Set(timet);
|
||||
tm2 = tm;
|
||||
tm2.tm_hour++;
|
||||
if ( tm2.tm_hour == 24 )
|
||||
{
|
||||
// This shouldn't normally happen as the DST never starts at 23:00
|
||||
// but if it does, we have a problem as we need to adjust the day
|
||||
// as well. However we stop here, i.e. we don't adjust the month
|
||||
// (or the year) because mktime() is supposed to take care of this
|
||||
// for us.
|
||||
tm2.tm_hour = 0;
|
||||
tm2.tm_mday++;
|
||||
}
|
||||
|
||||
timet = mktime(&tm2);
|
||||
}
|
||||
|
||||
return Set(timet);
|
||||
}
|
||||
|
||||
wxDateTime& wxDateTime::Set(wxDateTime_t hour,
|
||||
|
||||
Reference in New Issue
Block a user