user75569
user75569

Reputation: 377

Convert timestamp to datetime in erlang

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}.

Upvotes: 25

Views: 18758

Answers (4)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79005

Depending on your requirement, you can use system_time_to_universal_time/2 or system_time_to_local_time/2. The difference between these two is the former returns the date-time in UTC while the later returns the date-time in local timezone e.g. right now, it is 2024-08-15T19:45 at UTC but 2024-08-16T01:15 in India. Therefore, if you run system_time_to_universal_time/2 and system_time_to_local_time/2 in India right now, you will get 2024-08-15 and 2024-08-16 respectively.

Demo (assuming the code is run in India right now):

{Date, Time} = calendar:system_time_to_universal_time(os:system_time(millisecond), millisecond). 
Date.

Output: {2024,8,15}

{Date, Time} = calendar:system_time_to_local_time(os:system_time(millisecond), millisecond). 
Date.

Output: {2024,8,16}

Upvotes: 1

user2317487
user2317487

Reputation:

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

Upvotes: 1

Jeremy Wall
Jeremy Wall

Reputation: 25237

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)
.

Upvotes: 10

tonys
tonys

Reputation: 3984

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.

Upvotes: 24

Related Questions