Получение текущей даты или времени в Эликсире

83

Это кажется действительно глупым вопросом, но как получить и отобразить текущую дату или время в Elixir? Я попытался просмотреть документы, но ничего не нашел. Нужно ли мне использовать функцию Erlang?

Грэм Конзетт
источник

Ответы:

56

Чтобы ответить на ваш вопрос более конкретно (хотя я очень ценю рекомендацию Onorio использовать Timex!), Вы можете получить текущую дату и время из стандартной библиотеки Erlang, используя :calendar.universal_time()или :calendar.local_time(). В модуле есть ряд полезных функций для работы с datetimeтипом Erlang calendar, но они несколько ограничены и не предоставляют ничего для синтаксического анализа или форматирования дат, в чем и вступает Timex.

Bitwalker
источник
1
Отличный ответ, спасибо вам обоим, и я обязательно проверю Timex!
Грэм Конзетт
17

NaiveDateTime

Если вам не важен часовой пояс и вам нужны только дата и время в чистом виде, используйте NaiveDateTime:

NaiveDateTime.utc_now
# => ~N[2017-11-30 20:49:54.660724]

DateTime

Если вам также нужны данные о DateTimeчасовом поясе , используйте , который также вернет такие вещи, как имя часового пояса, смещение UTC, смещение STD и аббревиатуру часового пояса:

DateTime.utc_now
# => %DateTime{calendar: Calendar.ISO, day: 30, hour: 20, microsecond: {667345, 6}, minute: 51, month: 11, second: 58, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0, year: 2017, zone_abbr: "UTC"}

Затем вы также можете вызвать to_date/1и to_time/1из этих модулей, чтобы получить конкретные значения даты и времени из структур datetime.

Шехарьяр
источник
12

Я думаю, что вам лучше всего использовать библиотеку timex Пола Шенфельдера (также известную как BitWalker) для Elixir. Библиотека находится здесь: https://github.com/bitwalker/timex, и вы можете получить пакет из hex.pm https://hex.pm/packages/timex . Пол любезно предоставил хорошее объяснение того, как использовать библиотеку на странице readme этого репозитория github.

Вы можете вызывать собственные библиотеки Erlang, но я думаю, что библиотека Пола лучше, когда вы имеете дело с Elixir.

Онорио Катеначчи
источник
5
Спасибо за рекомендацию Онорио! Для всех, кто читает это, я очень открыт для внесения вклада, чтобы мы могли сделать Timex доступным для библиотеки для даты / времени в Elixir и, возможно, однажды объединить его со стандартной библиотекой Elixir, если она должна быть на должном уровне. Если вы хотите помочь, отправьте мне сообщение или погрузитесь в систему отслеживания проблем на GitHub и отправьте несколько запросов на включение!
Bitwalker
1
@bitwalker Да, в Erlang / Elixir есть много вещей, которые нужно сделать для библиотеки даты / времени. И я надеюсь, что timex можно будет объединить с Elixir :)
Тони Хан
11

Это зависит от того, в каком формате вы его хотите.

Вы можете использовать любую функцию из стандартной библиотеки Erlang из Elixir. Обычно вы получаете время с помощью now/0функции:

iex(1)> :erlang.now
{1487, 549978, 29683}

Это составляет time_t1,487,549,978,29683, что составляет 19 минут 38,29683 секунды после полуночи по всемирному координированному времени в понедельник, 20 февраля 2017 года.

Однако, начиная с Erlang / OTP 18, эта функция устарела; Одна из причин заключается в том, что Erlang гарантирует, что возвращаемое значение будет увеличиваться с каждым вызовом. Если вызвать его в жестком цикле на машине, достаточно быстро, чтобы вызывать его чаще, чем один раз в микросекунду, возвращенная временная метка будет опережать реальное время.

Замена - API с большей точностью и контролем . Основным интерфейсом к этому новому API является os:system_time/0функция, которая возвращает время эпохи в единицах измерения, определенных системой:

iex(2)> :os.system_time
1487549978296838000

Однако вы можете запросить конкретную единицу с помощью system_time/1:

iex(3)> :os.system_time(:millisecond)
1487549978296

Начиная с Elixir 1.2, эти функции также доступны в собственном Systemмодуле :

iex(4)> System.system_time(:second)
1487549978

Для более дружелюбного, но все же родного интерфейса Elixir используйте calendarмодуль, который предоставит вам кортежи:

iex(5)> :calendar.universal_time
{{2017, 2, 20}, {0, 19, 38}}

Начиная с версии 1.3, в Elixir есть собственный набор модулей для управления датой и временем: Dateи DateTime. Вы можете использовать его функции для получения текущей даты или времени следующим образом:

iex(6)> Date.utc_today
~D[2017-02-20]
iex(7)> DateTime.utc_now
#DateTime<2017-02-20 00:19:38.29683Z>
Марк Рид
источник
8

Чтобы получить количество миллисекунд (временная метка Unix):

DateTime.utc_now() |> DateTime.to_unix(:millisecond)
Сэм Хьюстон
источник
1
Хороший Сэм, именно то, что я искал;)
Деннис
7

Вы также можете использовать :os.timestamp\0, который возвращается {megaseconds, seconds, microseconds}из UTC. :os.timestamp |> :calendar.now_to_datetimeдаст вам теперь в стандартном {{YYYY, MM, DD}, {HH, MM, SS}}формате erlang .

G Amini
источник
3
И чтобы записать это в
Henrik N
6

Если вам нужно иметь дело с летним временем или часовыми поясами, я сделал для этого библиотеку: Календарь .

Чтобы получить текущее время, вы должны использовать, например, Calendar.DateTime.now("America/Los_Angeles")для текущего времени в Лос-Анджелесе или Calendar.DateTime.now_utcдля текущего времени в UTC.

Лау
источник
2

Чтобы получить временную метку unix

DateTime.to_unix(DateTime.utc_now)
Radzserg
источник
0

Что ж, Timex обычно приходит на помощь, однако некоторые из приведенных ниже уловок могут помочь:

{erl_date, erl_time} = :calendar.local_time()
# {{2020, 11, 19}, {0, 6, 36}}

{:ok, time} = Time.from_erl(erl_time)
# {:ok, ~T[00:06:36]}

{:ok, date} = Date.from_erl(erl_date)
# {:ok, ~D[2020-11-19]}

Calendar.strftime(time, "%c", preferred_datetime: "%H:%M:%S")
# "00:06:36"


Calendar.strftime(date, "%c", preferred_datetime: "%m-%d-%Y")
# "11-19-2020"
Михаил Чупринский
источник