Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reliable way to convert javascript timestamp into a date tuple

I want to convert javascript time stamps to erlang dates. I am using the qdate library to help me do that since it also provides functions for date arithmetic.

Calling it's to_date function first before midnight and then after midnight results in time displacement of 24 hrs. For example:-

 qdate:to_date(Timestamp div 1000). 

 %% {2015,5,2} before midnight

 qdate:to_date(After_midnight_Timestamp div 1000) 

 %%{2015,5,2} after midnight should be 3 instead of 2

I googled around a bit and found this in the erlang calender docs

The time functions local_time/0 and universal_time/0 provided in this module both return date and time. The reason for this is that separate functions for date and time may result in a date/time combination which is displaced by 24 hours. This happens if one of the functions is called before midnight, and the other after midnight. This problem also applies to the Erlang BIFs date/0 and time/0, and their use is strongly discouraged if a reliable date/time stamp is required.

I am having trouble understanding this. Which one of the functions from local_time/0 and universal_time/0 always gives the correct results? By correct I mean I want the right date to be shown after midnight. The resolution of the time is only {y,m,d}. Don't care for hours, minutes and seconds or anything finer than that.

So how do I reliably convert a javascript timestamp to a date in erlang?

like image 341
Akshat Jiwan Sharma Avatar asked Sep 07 '26 16:09

Akshat Jiwan Sharma


1 Answers

Looks like it was just a timezone issue :) Since I was working with javascript timestamps the default timezone of the javscript time stamp is my localtimzone which is "IST". Now internally when qdate sees an integer in qdate:to_date(Timestamp). it automatically selects a UTC timezone for it. Relevant code on line 256:-

raw_to_date(Unixtime) when is_integer(Unixtime) ->
    unixtime_to_date(Unixtime);

%% other clauses

and on line 654

unixtime_to_now(T) when is_integer(T) ->
    MegaSec = floor(T/1000000),
    Secs = T - MegaSec*1000000,
    {MegaSec,Secs,0}.

unixtime_to_date(T) ->
    Now = unixtime_to_now(T),
    calendar:now_to_datetime(Now).

The final clue comes from the erlang calendar documentation itself

now_to_datetime(Now) -> datetime1970()

Types: Now = erlang:timestamp()

This function returns Universal Coordinated Time (UTC) converted from the return value from erlang:now().

So the solution to this problem was to simply supply an IST string with qdate:to_date() like so:-

qdate:to_date("IST",Timestamp div 1000)

and it started returning correct dates. I wasn't sure of the solution so I ran a test with qdate:to_date(erlang:now()) and the value returned was exactly 5:30 hrs behind my clock time. So it seems that supplying the timezone string works :)

like image 123
Akshat Jiwan Sharma Avatar answered Sep 10 '26 05:09

Akshat Jiwan Sharma



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!