Haven’t anticipated the addition of timezone info has caused so much grief for me, though lots of “fun” are uncovered during the process.
Four years later: GDateTime
structure will be used to simplify cross
platform handling of such date / time issue. Let’s see how far it can go.
strftime()
is not very platform neutral
strftime()
on Windows is less capable then the Unix ones. For
compatibility, the date / time format would need to be expressed as
%Y-%m-%d %H:%M:%S
in place of just %F %T
(supporting ISO C89
standard but not C99); nor does it print numerical time zones.
TZ
environment variable on Windows is crap
Nowadays systems don’t use TZ
variable for common purpose anymore. 1
Linux / BSD make use of Olson time zone database which
automatically handles GMT offset and
DST,
while TZ
can also be set in well-defined manner to temporarily override
system setting. Windows users would be familiar with Control Panel settings
instead. But TZ
variable in Windows is arbitrary and there is no
rigorous checking 2, resulting in hilarious scenarios:
-
For example, I can happily use the value
ABC123XYZ
as timezone and it would be accepted as a timezone having -123 hours offset from UTC. The letters are merely junk — except that using 4 letters (likeEEST
which is a valid timezone in Istanbul) would cause functions utilitizingTZ
variable to wreak havoc. -
Compare these 2 commands:
set TZ=
set TZ=The first line unsets TZ variable as expected, so that Windows would retrieve regional setting from control panel. But with an extra space in 2nd line, timezone is set to UTC with Daylight Saving Time forcefully turned on!!! It costs me days of head scratching and several faulty “fixes”.
_timeb
structure does not respect TZ
variable
The DST value returned from _timeb
structure is faulty, in that it
only respects the timezone setting from Control Panel and not TZ
variable. That’s one of the bug addressed in 0.6.1 version.
The following table shows how the values of _timeb.dstflag
and
tm.tm_isdst
vary with TZ
and Control Panel settings (undesirable
values marked in red background):
Control Panel | |||
---|---|---|---|
Use DST | No DST | ||
TZ |
(unset) | 1 | 0 |
UTC | 1 | 0 | |
PST8PDT | 1 | 0 |
Control Panel | |||
---|---|---|---|
Use DST | No DST | ||
TZ |
(unset) | 1 | 0 |
UTC | 0 | 0 | |
PST8PDT | 1 | 1 |
It is immediately apparent that _timeb.timezone
ignores TZ
completely.
OTOH tm.tm_isdst
consults both settings, so is reliable enough for use
in rifiuti2
.
Nice stuff: INFO
file stores UTC time since 95
Enough Windows bashing. Actually, Microsoft developers are surprisingly
forward-thinking in some aspects.
The INFO
file (in Win95, predates INFO2
used in Win98) already uses
64-bit FILETIME
, when 32-bit systems were still not mature yet.
And this FILETIME
stores UTC time, not local time which is still dominant
in system time of current Windows. That saved lots of headache when
constructing event timeline.
Date | ChangeLog |
---|---|
2015-05-28 |
Add description about problem in _timeb |
2019-06-04 |
Use of GDateTime to replace the whole mess |
-
TZ
variable used to be a common mechanism to set time zone for Windows 3.1. Same applies to ancient Linux systems. ↩ -
Format of
TZ
variable is documented in_tzset()
function. However, it doesn’t mention the behavior if supplied value does not satisfy documented format. In fact virtually infinite randomly invented values would be accepted. ↩