
Marcin 'Qrczak' Kowalczyk wrote:
Seth Kurtzberg
writes: So, a time zone, at least one based on geographical location, isn't sufficient. Accounting for daylight savings doesn't cover every case either; I gave a couple of examples but doubtless there are many others I don't know about.
Linux (glibc) tries to provide that information. It has lots of rules even for weird timezones.
I think the only way to handle it is with an argument that allows the user to override the offset that the machine itself uses.
It's fine to be able to override, but the default should definitely be taken from the OS.
It is possible to discover the offset which should be used for the given timestamp, but it's clumsy: do localtime() and gmtime(), and subtract the results:
diff = (((loc.tm_wday - gm.tm_wday) * 24 + (loc.tm_hour - gm.tm_hour)) * 60 + (loc.tm_min - gm.tm_min)) * 60 + (loc.tm_sec - gm.tm_sec); if (diff < -302400) diff += 604800; else if (diff >= 302400) diff -= 604800;
Linux has tm_gmtoff, it can be used instead if it's available - it's not portable.
You will not know which part of the difference is due to geographical location and which is due to DST, but usually it doesn't matter. You can only know whether DST is in effect or not: tm_isdst.
When converting in the other direction, from broken-down time to timestamp, sometimes the DST is not known, yet its useful to guess it, even though one hour in a year is ambiguous and another is impossible. Libc can be used for that: call mktime() with tm_isdst less than 0, and then either use tm_gmtoff or call gmtime() and subtract the results as before.
If the year is outside the range supported by libc, I'm afraid there is no OS-provided way to take DST into account, at least on Linux. You can sometimes infer the geographical timezone: call tzset() and use variable 'extern long timezone;', if it exists and has the correct type - it's not portable. Note: it has the opposite sign to tm_gmtoff.
True, it isn't portable, but no solution is portable. So you either don't handle it, or handle it in a similar way to what you suggest. Thinking about it, the time zone issue should be separated from this library, for the same reasons that it has been argued that a leap second table should be separate. And, as has been suggested for the leap second dilemma, you can use the functions in the low level library and enhance them for leap seconds, time zones, or whichever other variations that come up. One thing that this thread has emphasized is that working with time is complicated. I've been converted to the view of others in the thread that time library under discussion should handle the functions whose behavior is clear, and handle the things that are more controversial, or just less standardized, in a wrapper library (or libraries).