[erlang-bugs] Bug: local_to_univ does not handle -1 result from mktime (with patch)
Paul Guyot
pguyot@REDACTED
Sat Nov 1 07:50:22 CET 2008
Hello,
I found a bug in Erlang/OTP R12B-4 that occurs on FreeBSD 7.0 with TZ
set to UTC. On such systems, mktime(3) returns -1 when is_dst is set
to true. According to SUSv3, the OS can return -1 when the time since
Epoch cannot be represented, and therefore FreeBSD is perfectly
allowed to do so.
http://www.opengroup.org/onlinepubs/009695399/functions/mktime.html
In other words, erlang:localtime_to_universaltime/2 may return {{1969,
12, 31}, {23, 59, 59}} (-1) whenever the (DateTime, IsDST) combination
is invalid (DateTime is invalid or IsDST is true and there is no valid
DST representation for the given DateTime). This function is called by
calendar:local_time_to_universal_time_dst/1 which unexpectedly fails.
FreeBSD 7.0 with TZ set to UTC:
1> calendar:local_time_to_universal_time_dst({{2008, 8, 1}, {0, 0, 0}}).
** exception error: bad argument
in function erlang:universaltime_to_localtime/1
called as erlang:universaltime_to_localtime({{1969,12,31},
{23,59,59}})
in call from calendar:local_time_to_universal_time_dst/1
FreeBSD 7.0 with TZ set to Asia/Tokyo:
1> calendar:local_time_to_universal_time_dst({{2008, 8, 1}, {0, 0, 0}}).
[{{2008,7,31},{15,0,0}}]
The problem does not occur on MacOS X 10.5, with TZ set to UTC:
1> calendar:local_time_to_universal_time_dst({{2008, 8, 1}, {0, 0, 0}}).
[{{2008,8,1},{0,0,0}}]
The attached patch fixes the bug by modifying local_to_univ, so it
returns 0 when mktime returns -1. As a consequence,
erlang:localtime_to_universaltime/2 no longer returns {{1969, 12, 31},
{23, 59, 59}} but raises {error, badarg} instead. The patch also
modifies calendar:local_time_to_universal_time_dst/1, so it handles
the badarg exception thrown by erlang:localtime_to_universaltime/2. If
an exception is thrown, calendar:local_time_to_universal_time_dst/1
returns []. I chose to do so because it already is what is returned if
the provided date is invalid (a local time during a period that cannot
happen because of DST change).
Finally, I suggest to document the fact that badarg error can be
raised if the Date, Time and IsDst combination is invalid :
- Failure: badarg if Date1 or Time1 do not denote a valid date or time.
+ Failure: badarg if Date1, Time1 and IsDst do not denote a valid date
or time.
Paul
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch_mktime.diff
Type: application/octet-stream
Size: 1506 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20081101/c1bab4d9/attachment.obj>
-------------- next part --------------
More information about the erlang-bugs
mailing list