установить точность даты и времени в миллисекундах - эликсир

Я пытаюсь получить дату и время, у которой только 3 цифры в доли секунды.
Используя timex, я получаю следующий результат:

iex(12)>   {:ok, date} = Timex.format(Timex.shift(Timex.local, days: 16), "{ISO:Extended}")
{:ok, "2017-04-22T09:00:44.403879+03:00"}

Как получить что-то вроде этого:
{:ok, "2017-04-22T09:00:44.403+03:00"}?


person fay    schedule 06.04.2017    source источник
comment
Вы пытались использовать строку формата, например: {:ok, date} = Timex.format(Timex.shift(Timex.local, days: 16), "%FT%T%:z", :strftime)   -  person Zubair Nabi    schedule 06.04.2017
comment
@ZubairNabi, это дает мне результат без миллисекунд, я не могу понять правильную строку формата, чтобы получить цифры в 3 миллисекунды   -  person fay    schedule 06.04.2017


Ответы (2)


DateTime имеет поле microsecond, которое представляет собой кортеж, содержащий значение и точность. Если вы измените точность на 3, вы получите 3 цифры в микросекундном выходе. Я не смог найти ни одной функции в Timex, которая делает это, но вы можете изменить значение вручную:

iex(1)> dt = %{microsecond: {us, precision}} = Timex.now
#<DateTime(2017-04-06T08:26:24.041004Z Etc/UTC)>
iex(2)> precision
6
iex(3)> dt2 = %{dt | microsecond: {us, 3}}
#<DateTime(2017-04-06T08:26:24.041Z Etc/UTC)>
iex(4)> dt2 |> Timex.format!("{ISO:Extended}")
"2017-04-06T08:26:24.041+00:00"
person Dogbert    schedule 06.04.2017
comment
Это отличная идея, но вы должны дополнить нулями значение микросекунды us. Я столкнулся с проблемой, когда миллисекундная часть отформатированной метки времени была смещена влево на одну цифру. Например, если dt равно #DateTime<2015-11-02 03:08:57.071819Z>, dt.microsecond равно {71819, 6}. Выполнение %{dt | microsecond: {71819, 3}} |> Timex.format("{ISO:Extended:Z}") дает "2015-11-02T03:08:57.718Z". Обратите внимание, что миллисекундная часть теперь равна 718 вместо 071. Чтобы исправить это, дополните значение нулями: %{dt | microsecond: {"071819", 3}} |> Timex.format!("{ISO:Extended:Z}") 2015-11-02T03:08:57.071Z - person Gordon Zheng; 28.09.2017
comment
@GordonZheng Я думаю, что правильным решением здесь будет разделить us на 10^<the number of digits that were reduced>, например. 6 -> 3 будет %{dt | microsecond: {div(us, 1000), 3}} |> Timex.format("{ISO:Extended:Z}"). Поскольку это работает, я предполагаю, что поведение моего ответа и ваш комментарий являются ошибкой - значение us должно быть не более 10^precision. - person Dogbert; 28.09.2017
comment
О, это гораздо лучшее решение. Спасибо @Dogbert! - person Gordon Zheng; 28.09.2017

Начиная с версии Elixir 1.6.0 функция truncate/2 присутствует в модулях Time, DateTime. и NativeDateTime для этого:

iex(1)> dt = Timex.now()
#DateTime<2018-02-16 19:03:51.430946Z>

iex(2)> dt2 = DateTime.truncate(dt, :millisecond)
#DateTime<2018-02-16 19:03:51.430Z>
person Alexandre L Telles    schedule 16.02.2018