首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Erlang:带时区算法的时间戳

Erlang:带时区算法的时间戳
EN

Stack Overflow用户
提问于 2011-03-29 06:35:15
回答 1查看 2.7K关注 0票数 5

关于Erlang时区,向特定时间戳添加/减去单元的最佳方法是什么?

据我所发现,stdlib的日历可以使用本地时区或UTC时区,不再使用。此外,推荐算法只在UTC时区执行(原因很明显)。

例如,如果我需要在{{2011,3,24},{11,13,15} in加上1个月,比方说,CET (中欧时间)和地方(系统)时区不是CET,我该怎么办?这甚至不同于将此时间戳转换为UTC,增加31 * 24 * 60 *60秒,并转换回CET (这将使{2011,4,24},{12,13,15},而不是{2011,4,24},{11,13,15}})。顺便说一句,如果CET不是stdlib的本地时区,我们甚至不能这样做。

我在谷歌上找到的答案是:

使本地时区=所需时区(这首先很难看;然后它只允许将所需的时区转换为utc,并将各自的算法转换为utc ),而不允许将所需的时间zone)

  • open_port转换为linux的date util和do算法(并不那么难看;相当慢;需要进行一些解析,因为erlang和date之间的协议将是文本的)使用标准库

  • 端口驱动程序或erl_interface到C(一点都不难看;但我没有准备好使用解决方案,我也不太擅长编写

理想的解决方案是在Erlang中使用OS时区信息编写,但我没有找到任何解决方案。

现在,我只能使用解决方案2 (open_port到date )。有更好的办法吗?

提前谢谢。

也有类似的问题,但Time zone list issue没有很好的答案。

EN

回答 1

Stack Overflow用户

发布于 2011-03-30 10:17:36

port_helper.erl

代码语言:javascript
复制
-module(port_helper).
-export([get_stdout/1]).
get_stdout(Port) ->
    loop(Port, []).
loop(Port, DataAcc) ->
    receive
        {Port, {data, Data}} ->
            loop(Port, DataAcc ++ Data);
        {Port, eof} ->
            DataAcc
    end.

timestamp_with_time_zone.erl

代码语言:javascript
复制
-module(timestamp_with_time_zone).
-export([to_time_zone/2, to_universal_time/1, modify/2]).
to_time_zone({{{Year, Month, Day}, {Hour, Minute, Second}}, TimeZone}, OutputTimeZone) ->
    InputPattern = "~4.10.0B-~2.10.0B-~2.10.0B ~2.10.0B:~2.10.0B:~2.10.0B",
    InputDeep = io_lib:format(InputPattern, [Year, Month, Day, Hour, Minute, Second]),
    Input = lists:flatten(InputDeep),
    {external_date(Input, TimeZone, OutputTimeZone), OutputTimeZone}.
to_universal_time({{{Year, Month, Day}, {Hour, Minute, Second}}, TimeZone}) ->
    {Timestamp, "UTC"} = to_time_zone({{{Year, Month, Day}, {Hour, Minute, Second}}, TimeZone}, "UTC"),
    Timestamp.
modify({{{Year, Month, Day}, {Hour, Minute, Second}}, TimeZone}, {Times, Unit}) ->
    if
        Times > 0 ->
            TimesModifier = "";
        Times < 0 ->
            TimesModifier = " ago"
    end,
    InputPattern = "~4.10.0B-~2.10.0B-~2.10.0B ~2.10.0B:~2.10.0B:~2.10.0B ~.10B ~s~s",
    InputDeep = io_lib:format(InputPattern, [Year, Month, Day, Hour, Minute, Second, abs(Times), Unit, TimesModifier]),
    Input = lists:flatten(InputDeep),
    external_date(Input, TimeZone, TimeZone).

external_date(Input, InputTimeZone, OutputTimeZone) ->
    CmdPattern = "date --date 'TZ=\"~s\" ~s' +%Y%m%d%H%M%S",
    CmdDeep = io_lib:format(CmdPattern, [InputTimeZone, Input]),
    Cmd = lists:flatten(CmdDeep),
    Port = open_port({spawn, Cmd}, [{env, [{"TZ", OutputTimeZone}]}, eof, stderr_to_stdout]),
    ResultString = port_helper:get_stdout(Port),
    case io_lib:fread("~4d~2d~2d~2d~2d~2d", ResultString) of
        {ok, [YearNew, MonthNew, DayNew, HourNew, MinuteNew, SecondNew], _LeftOverChars} ->
            {{YearNew, MonthNew, DayNew}, {HourNew, MinuteNew, SecondNew}}
    end.
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5468791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档