aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Sikora <[email protected]>2012-07-14 04:38:13 +0000
committerHenrik Nord <[email protected]>2012-08-01 10:01:29 +0200
commit904384397517ded1e9d2e3b1c6fdf16eeb2dab67 (patch)
treee25a8f5a4eb522b1e652633fb6f066045797dbfc
parentffcdf6f983bd9b7005abc2e69c4a0f187b8493f6 (diff)
downloadotp-904384397517ded1e9d2e3b1c6fdf16eeb2dab67.tar.gz
otp-904384397517ded1e9d2e3b1c6fdf16eeb2dab67.tar.bz2
otp-904384397517ded1e9d2e3b1c6fdf16eeb2dab67.zip
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 <[email protected]>
-rw-r--r--erts/configure.in5
-rw-r--r--erts/emulator/beam/erl_time_sup.c10
2 files changed, 13 insertions, 2 deletions
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 <time.h>])
+AC_CHECK_DECLS([posix2time, time2posix],,,[#include <time.h>])
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