[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