越南时区中,erlang中unix时间戳和日期转换问题
环境
系统: CENTOS 7
语言: ERLANG OTP 17.5.3
时区: Asia/Ho_Chi_Minh
问题
先来看一段代码
1 2 3 4 5 6 7 8 9 10 11
|
-define(SECONDS_FROM_0_TO_1970, 62167219200).
date_to_time({{_Y, _M, _D}, {_H, _Mi, _S}} = Date) -> calendar:datetime_to_gregorian_seconds(Date) - calendar:datetime_to_gregorian_seconds(calendar:universal_time_to_local_time({{1970,1,1}, {0,0,0}})).
seconds_to_localtime(Seconds) -> DateTime = calendar:gregorian_seconds_to_datetime(Seconds+?SECONDS_FROM_0_TO_1970), calendar:universal_time_to_local_time(DateTime).
|
这是日期和unix时间戳互转的代码,貌似没错,运行大部分时间也没错
但是修改为Asia/Ho_Chi_Minh
(东七区)(cp -f /usr/share/zoneinfo/Asia/Ho_Chi_Minh /etc/localtime
)
查看时区也确实是+0700
1 2
| [root@localhost ~]# date -R Mon, 22 May 2017 19:02:21 +0700
|
1 2
| 1> util:seconds_to_localtime(0). {{1970,1,1},{8,0,0}}
|
原因
经排查,发现calendar:universal_time_to_local_time/1
存在问题
1 2 3 4
| 39> calendar:universal_time_to_local_time({{1970,1,1},{0,0,0}}). {{1970,1,1},{8,0,0}}
%% 这里应该是{7,0,0}
|
解决方案
手动进行时区修正
1 2 3 4 5 6
| Now = erlang:now(), LocalTime = calendar:now_to_local_time(Now), UTCTime = calendar:now_to_universal_time(Now),
calendar:datetime_to_gregorian_seconds(LocalTime) - calendar:datetime_to_gregorian_seconds(UTCTime).
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
-define(SECONDS_FROM_0_TO_1970, 62167219200).
date_to_time({{_Y, _M, _D}, {_H, _Mi, _S}} = Date) -> Now = erlang:now(), LocalTime = calendar:now_to_local_time(Now), UTCTime = calendar:now_to_universal_time(Now), calendar:datetime_to_gregorian_seconds(Date) - calendar:datetime_to_gregorian_seconds({{1970,1,1}, {0,0,0}}) - calendar:datetime_to_gregorian_seconds(LocalTime) + calendar:datetime_to_gregorian_seconds(UTCTime).
seconds_to_localtime(Seconds) -> Now = erlang:now(), LocalTime = calendar:now_to_local_time(Now), UTCTime = calendar:now_to_universal_time(Now),
Second1 = Seconds + ?SECONDS_FROM_0_TO_1970 + calendar:datetime_to_gregorian_seconds(LocalTime) - calendar:datetime_to_gregorian_seconds(UTCTime), calendar:gregorian_seconds_to_datetime(Second1).
|