Opened 17 months ago

Closed 17 months ago

Last modified 16 months ago

#15250 closed defect (fixed)

wxDateTime::Format: inconsistent output for %z on Windows

Reported by: cwalther Owned by: vadz
Priority: normal Milestone:
Component: base Version: 2.9.4
Keywords: wxDateTime Format %z time zone DST Cc:
Blocked By: Blocking:
Patch: no

Description

What is the expected output of the following program?

#include <iostream>
#include <wx/init.h>
#include <wx/datetime.h>

int main(int argc, char **argv) {
	wxInitializer init(argc, argv);
	if (!init.IsOk()) return 1;
	
	wxDateTime t((time_t)1371044961);
	std::cout << "UTC:   " << t.Format("%Y-%m-%d %H:%M:%S %z", wxDateTime::UTC) << std::endl;
	std::cout << "Local: " << t.Format("%Y-%m-%d %H:%M:%S %z") << std::endl;
	
	return 0;
}

On Linux, I get

UTC:   2013-06-12 13:49:21 +0000
Local: 2013-06-12 15:49:21 +0200

On Windows, I get

UTC:   2013-06-12 13:49:21 +0000
Local: 2013-06-12 15:49:21 +0100

The “Local” part of the Windows output is clearly inconsistent, because its time differs by two hours from UTC, but the UTC offset produced by the “%z” format is +0100.

Personally I would expect the Linux output, because to me, “local time” means “local time including whatever DST is in effect at the time”, and I’m in the Europe/Zurich time zone, which has UTC+1 in winter and UTC+2 in summer, and the chosen date is in summer.

However, it seems that, even though it’s not explicitly documented, wxDateTime::Local (the default argument to wxDateTime::Format), by being based on wxGetTimeZone() (which is not explicitly documented to do that either, but the comments in its source code and its consistent behavior on both Linux and Windows make it clear), actually means “local time as if no DST was ever in effect”. In that case, the expected output would be “Local: 2013-06-12 14:49:21 +0100”, which matches neither Linux nor Windows. (It would also be a somewhat useless output IMO, because nobody’s clock in my time zone actually shows that time.)

Can anyone comment on what the expected output from the point of view of wxWidgets would be? That would determine how to fix the inconsistent output on Windows.

I have to say, I find the terminology a bit confusing: There is wxDateTime::TimeZone and wxGetTimeZone(), but neither actually represent time zones, they just represent fixed UTC offsets. But the UTC offset isn’t constant for a particular time zone, it changes over the year in many of them. In other words, it is not possible to represent a local time zone that has DST as a wxDateTime::TimeZone, which would strictly speaking be required for achieving the output seen on Linux above (the useful output IMO).

Change History (3)

comment:1 Changed 17 months ago by vadz

  • Owner set to vadz
  • Status changed from new to accepted

The handling of time zones in wxDateTime is definitely confusing, I freely admit to having goofed up here.

However in this particular case the problem is at least simple to fix, we just need to account for the DST in our formatting code. I'm going to commit the fix soon.

Thanks a lot for your analysis and the example showing the bug!

comment:2 Changed 17 months ago by VZ

  • Resolution set to fixed
  • Status changed from accepted to closed

(In [74242]) Fix formatting of the local time zone when DST is in effect.

We must add DST offset manually as wxGetTimeZone() doesn't take DST into
account.

This fixes the handling of "%z" in format strings.

Closes #15250.

comment:3 Changed 16 months ago by cwalther

Verified – thanks, that was quick!

Note: See TracTickets for help on using tickets.