How to get a date in yyyy-MM-dd'T'HH: mm: ss.SSSZ format

Viewed 487

I want to get the current time, and format it in the following way:

yyyy-MM-dd'T'HH:mm:ss.SSSZ

(where SSS is the milliseconds and Z the time zone)

the code so far I have it as follows:

formatted_date() ->
  {{Y,M,D},{H,Min,S}} = erlang:localtime(),
  {Ms, _, _} = os:timestamp(),
  {Days, {Hours, _,_}} = calendar:time_difference(erlang:universaltime(), erlang:localtime()),
  Difference = 24*Days + Hours,
  Tz = [case Difference < 0 of
          true ->
            $-;
          false ->
            $+
        end | io_lib:format("~2..0B00",[Difference])],
  io_lib:format("[~4..0B-~2..0B-~2..0BT~2..0B:~2..0B:~2..0B.~3..0B ~5.s]",
                              [Y, M, D, H, Min, S, Ms, Tz]).

The fact is that it always returns the same Ms, therefore, I think that I am not doing it well, and in other questions I only see how to obtain the total time in milliseconds, but not how to format it in this way.

Thank you.

1 Answers

The easiest way is to use the library function calendar:system_time_to_rfc3339/2 - it seems to fulfil all your requirements.

> calendar:system_time_to_rfc3339(os:system_time(millisecond), [{unit, millisecond}]).
"2021-03-03T18:42:08.497+05:30"

This function was added in Erlang/OTP 21.0, which was released in June 2018.


The reason your code always gets the same value for Ms is that the first value in the tuple returned by os:timestamp/0 is megaseconds, not milliseconds; the three values are megaseconds, seconds and microseconds. This comes from a time when Erlang did not support large integers, so splitting up the timestamp was necessary. These days you can just call os:system_time/1 or a number of other functions, depending on what kind of time you need, and get the result in a single integer.

Related