Convert timestamp to datetime in erlang

前端 未结 3 941
予麋鹿
予麋鹿 2020-12-29 04:21

How can I convert a timestamp (number of milliseconds since 1 Jan 1970..., aka epoch) to Date or DateTime format in Erlang? Something like {Year,Month,Day}.

相关标签:
3条回答
  • 2020-12-29 04:48

    Roughly:

    msToDate(Milliseconds) ->
       BaseDate      = calendar:datetime_to_gregorian_seconds({{1970,1,1},{0,0,0}}),
       Seconds       = BaseDate + (Milliseconds div 1000),
       { Date,_Time} = calendar:gregorian_seconds_to_datetime(Seconds),
       Date.
    
    0 讨论(0)
  • 2020-12-29 04:50

    OTP 21.0 added this function

    calendar:system_time_to_universal_time(Time, TimeUnit) -> datetime()
    
    Types
        Time = integer()
        TimeUnit = erlang:time_unit()
    
    Converts a specified system time into universal date and time.
    

    Example:

    > os:system_time(1000).   
    1598512151718
    > calendar:system_time_to_universal_time(1598512151718, 1000).
    {{2020,8,27},{7,9,11}}
    

    Refrence: https://erlang.org/doc/man/calendar.html#system_time_to_universal_time-2

    0 讨论(0)
  • 2020-12-29 05:12

    It just so happens that I have a github gist with a bunch of datetime utilities for exactly this purpose: http://gist.github.com/104903. Calendar has most of the low level plumbing for this stuff.

    -module(date_util).
    -compile(export_all).
    
    epoch() ->
        now_to_seconds(now())
    .   
    
    epoch_hires() ->
        now_to_seconds_hires(now())
    .   
    
    now_to_seconds({Mega, Sec, _}) ->
        (Mega * 1000000) + Sec
    .   
    
    now_to_milliseconds({Mega, Sec, Micro}) ->
        now_to_seconds({Mega, Sec, Micro}) * 1000
    .   
    
    now_to_seconds_hires({Mega, Sec, Micro}) ->
        now_to_seconds({Mega, Sec, Micro}) + (Micro / 1000000)
    .   
    
    now_to_milliseconds_hires({Mega, Sec, Micro}) ->
        now_to_seconds_hires({Mega, Sec, Micro}) * 1000
    .   
    
    epoch_gregorian_seconds() ->
        calendar:datetime_to_gregorian_seconds({{1970,1,1}, {0,0,0}})
    .       
    
    now_to_gregorian_seconds() ->
        epoch_to_gregorian_seconds(now())
    .       
    
    epoch_to_gregorian_seconds({Mega, Sec, Micro}) ->
        epoch_to_gregorian_seconds(now_to_seconds({Mega, Sec, Micro}));
    epoch_to_gregorian_seconds(Now) ->
        EpochSecs = epoch_gregorian_seconds()
        , Now + EpochSecs
    .       
    
    gregorian_seconds_to_epoch(Secs) ->
        EpochSecs = epoch_gregorian_seconds()
        , Secs - EpochSecs
    .
    
    date_to_epoch(Date) ->
        datetime_to_epoch({Date, {0,0,0} })
    .
    
    datetime_to_epoch({Date, Time}) ->
        gregorian_seconds_to_epoch(
            calendar:datetime_to_gregorian_seconds({Date, Time}))
    .
    
    is_older_by(T1, T2, {days, N}) ->
        N1 = day_difference(T1, T2)
        , case N1 of
            N2 when (-N < N2) ->
                true;
            _ ->
                false
        end
    .
    
    is_sooner_by(T1, T2, {days, N}) ->
        case day_difference(T1, T2) of
            N1 when N > N1 ->
                true;
            _ ->
                false
        end
    .
    
    is_time_older_than({Date, Time}, Mark) ->
        is_time_older_than(calendar:datetime_to_gregorian_seconds({Date, Time})
            , Mark);
    is_time_older_than(Time, {DateMark, TimeMark}) ->
        is_time_older_than(Time
            , calendar:datetime_to_gregorian_seconds({DateMark, TimeMark}));
    is_time_older_than(Time, Mark)  when is_integer(Time), is_integer(Mark) ->
        Time < Mark
    .
    
    day_difference({D1, _}, D2) ->
        day_difference(D1, D2);
    day_difference(D1, {D2, _}) ->
        day_difference(D1, D2);
    day_difference(D1, D2) ->
        Days1 = calendar:date_to_gregorian_days(D1)
        , Days2 = calendar:date_to_gregorian_days(D2)
        , Days1 - Days2
    .
    
    is_time_sooner_than({Date, Time}, Mark) ->
        is_time_sooner_than(calendar:datetime_to_gregorian_seconds({Date, Time})
            , Mark);
    is_time_sooner_than(Time, {DateMark, TimeMark}) ->
        is_time_sooner_than(Time
            , calendar:datetime_to_gregorian_seconds({DateMark, TimeMark}));
    is_time_sooner_than(Time, Mark)  when is_integer(Time), is_integer(Mark) ->
        Time > Mark
    .
    
    subtract(Date, {days, N}) ->
        New = calendar:date_to_gregorian_days(Date) - N
        , calendar:gregorian_days_to_date(New)
    .
    
    add(Date, {days, N}) ->
        New = calendar:date_to_gregorian_days(Date) + N
        , calendar:gregorian_days_to_date(New)
    .
    
    0 讨论(0)
提交回复
热议问题