This is a clarification of the issue reported in #47.
CL-USER> (defun utc-string (timestamp) (local-time:format-timestring nil timestamp :timezone local-time:+utc-zone+))
UTC-STRING
CL-USER> (defparameter *cet* (local-time:find-timezone-by-location-name "Europe/Stockholm"))
*CET*
CL-USER> (utc-string (local-time:encode-timestamp 0 0 0 0 30 3 2014 :timezone *cet*))
"2014-03-29T23:00:00.000000Z" ; correct, CET is 1 hour ahead of UTC
CL-USER> (utc-string (local-time:encode-timestamp 0 0 0 4 30 3 2014 :timezone *cet*))
"2014-03-30T02:00:00.000000Z" ; correct, CET with dayligth saving time is 2 hours head of UTC
CL-USER> (utc-string (local-time:encode-timestamp 0 0 0 1 30 3 2014 :timezone *cet*))
"2014-03-29T23:00:00.000000Z" ; incorrect, dayligth saving time transititon is not until 2.
The root cause of this bug is that the internal function %guess-offset finds the wrong subtimezone when the local time is near the transition to/from daylight saving time. Converting from UTC to local time is always correct, but going the other way is not as easy because the transition times in are in UTC. To complicate thing even further, when the local time is adjusted backwards, there is a period where the same local time correspond to two different UTC time stamps.
Not sure how to best solve this problem. The code in glibc for doing this conversion is quite tricky to understand: https://github.com/lattera/glibc/blob/master/time/mktime.c
One obvious solution would be to simple call mktime, but this doesn't work since mktime doesn't take a time zone parameter.
This is a clarification of the issue reported in #47.
The root cause of this bug is that the internal function
%guess-offsetfinds the wrong subtimezone when the local time is near the transition to/from daylight saving time. Converting from UTC to local time is always correct, but going the other way is not as easy because the transition times in are in UTC. To complicate thing even further, when the local time is adjusted backwards, there is a period where the same local time correspond to two different UTC time stamps.Not sure how to best solve this problem. The code in glibc for doing this conversion is quite tricky to understand: https://github.com/lattera/glibc/blob/master/time/mktime.c
One obvious solution would be to simple call
mktime, but this doesn't work sincemktimedoesn't take a time zone parameter.