Дата и время
Работа с временем в Elixir.
Время
В Elixir есть несколько модулей для работы со временем. Начнём с получения текущего времени:
iex> Time.utc_now
~T[19:39:31.056226]
Обратите внимание на строковую метку, через которую также можно создать структуру Time
:
iex> ~T[19:39:31.056226]
~T[19:39:31.056226]
Вы можете узнать больше о строковых метках в уроке о строковых метках. Можно легко получить части этой структуры:
iex> t = ~T[19:39:31.056226]
~T[19:39:31.056226]
iex> t.hour
19
iex> t.minute
39
iex> t.day
** (KeyError) key :day not found in: ~T[19:39:31.056226]
Но тут есть загвоздка: как вы могли заметить, в этой структуре есть только время в пределах суток, поэтому нет числа/месяца/года.
Дата
В отличие от Time
, структура Date
содержит только текущую дату, без какой-либо информации о времени.
iex> Date.utc_today
~D[2028-10-21]
Кроме этого, есть полезные функции для работы с датами:
iex> {:ok, date} = Date.new(2020, 12, 12)
{:ok, ~D[2020-12-12]}
iex> Date.day_of_week date
6
iex> Date.leap_year? date
true
day_of_week/1
определяет день недели указанной даты.
В данном случае это суббота.
leap_year?/1
определяет, является ли год високосным.
Остальные функции вы можете найти в документации.
NaiveDateTime
В Elixir существует два вида структур, содержащих и время, и дату.
Первая - NaiveDateTime
.
Её недостаток - отсутствие поддержки часовых поясов:
iex> NaiveDateTime.utc_now
~N[2022-01-21 19:55:10.008965]
Но она содержит как время, так и дату, так что можете попробовать добавить времени, к примеру:
iex> NaiveDateTime.add(~N[2018-10-01 00:00:14], 30)
~N[2018-10-01 00:00:44]
DateTime
Вторая, как вы уже могли догадаться из названия раздела, называется DateTime
.
У неё нет ограничений, упомянутых в NaiveDateTime
: она хранит как время, так и дату, а также поддерживает часовые пояса.
Но будьте осторожны с часовыми поясами. Как сказано в официальной документации:
Многие функции в этом модуле требуют базы данных часовых поясов. По умолчанию они используют базу данных часовых поясов возвращаемую функцией
Calendar.get_time_zone_database/0
, которая по умолчанию равнаCalendar.UTCOnlyTimeZoneDatabase
, которая обрабатывает только “Etc/UTC” даты и возвращает{:error, :utc_only_time_zone_database}
для любого другого часового пояса.
Также обратите внимание, что можно создать DateTime
из NaiveDateTime
, только передав часовой пояс:
iex> DateTime.from_naive(~N[2016-05-24 13:26:08.003], "Etc/UTC")
{:ok, #DateTime<2016-05-24 13:26:08.003Z>}
Работаем с часовыми поясами
Как мы отмечали в предыдущей главе, по умолчанию в Elixir нет данных о часовых поясах. Чтобы решить эту проблему, нам нужно установить и настроить пакет tzdata. После его установки вы должны глобально настроить Elixir на использование Tzdata в качестве базы данных часовых поясов:
config :elixir, :time_zone_database, Tzdata.TimeZoneDatabase
Давайте теперь попробуем создать время в часовом поясе Парижа и преобразовать его в Нью-Йоркское время:
iex> paris_datetime = DateTime.from_naive!(~N[2019-01-01 12:00:00], "Europe/Paris")
#DateTime<2019-01-01 12:00:00+01:00 CET Europe/Paris>
iex> {:ok, ny_datetime} = DateTime.shift_zone(paris_datetime, "America/New_York")
{:ok, #DateTime<2019-01-01 06:00:00-05:00 EST America/New_York>}
iex> ny_datetime
#DateTime<2019-01-01 06:00:00-05:00 EST America/New_York>
Как видите, время изменилось с 12:00 по парижскому времени до 6:00, что правильно - разница во времени между двумя городами составляет 6 часов.
Вот и всё! Если вы хотите попробовать другие дополнительные функции, загляните в документацию Time, Date, DateTime и NaiveDateTime Также рекомендуем изучить Timex и Calendar - мощные библиотеки для работы с временем в Elixir.
Caught a mistake or want to contribute to the lesson? Edit this lesson on GitHub!