From 904384397517ded1e9d2e3b1c6fdf16eeb2dab67 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Sat, 14 Jul 2012 04:38:13 +0000 Subject: Fix support for leap seconds-aware timezones erlang:universaltime_to_localtime is leap seconds-aware (since 2008), however erlang:localtime_to_universaltime is not, which gives surprising results on systems configured with leap seconds-aware timezones: 1> erlang:universaltime_to_localtime({{2012,1,1},{0,0,0}}). {{2012,1,1},{0,0,0}} 2> erlang:localtime_to_universaltime({{2012,1,1},{0,0,0}}). {{2012,1,1},{0,0,24}} and completely breaks calendar:local_time_to_universal_time_dst: 3> calendar:local_time_to_universal_time_dst({{2011,1,1},{0,0,0}}). [] Signed-off-by: Piotr Sikora --- erts/configure.in | 5 +++-- erts/emulator/beam/erl_time_sup.c | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'erts') diff --git a/erts/configure.in b/erts/configure.in index b3289bf84c..07ba9214cb 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -1881,9 +1881,10 @@ AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlop pread pwrite writev memmove strerror strerror_r strncasecmp \ gethrtime localtime_r gmtime_r inet_pton mmap mremap memcpy mallopt \ sbrk _sbrk __sbrk brk _brk __brk \ - flockfile fstat strlcpy strlcat setsid posix2time setlocale nl_langinfo poll]) + flockfile fstat strlcpy strlcat setsid posix2time time2posix \ + setlocale nl_langinfo poll]) -AC_CHECK_DECLS([posix2time],,,[#include ]) +AC_CHECK_DECLS([posix2time, time2posix],,,[#include ]) disable_vfork=false if test "x$EMU_THR_LIB_NAME" != "x"; then diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c index 1d0735aa99..4a04103652 100644 --- a/erts/emulator/beam/erl_time_sup.c +++ b/erts/emulator/beam/erl_time_sup.c @@ -717,6 +717,11 @@ int univ_to_seconds(Sint year, Sint month, Sint day, Sint hour, Sint minute, Sin return 1; } +#if defined(HAVE_TIME2POSIX) && defined(HAVE_DECL_TIME2POSIX) && \ + !HAVE_DECL_TIME2POSIX +extern time_t time2posix(time_t); +#endif + int local_to_univ(Sint *year, Sint *month, Sint *day, Sint *hour, Sint *minute, Sint *second, int isdst) @@ -766,6 +771,11 @@ local_to_univ(Sint *year, Sint *month, Sint *day, return 0; } } + +#ifdef HAVE_TIME2POSIX + the_clock = time2posix(the_clock); +#endif + #ifdef HAVE_GMTIME_R tm = gmtime_r(&the_clock, &tmbuf); #else -- cgit v1.2.3