DateTime
Реализация DateTime с часовым поясом.
Эта дата и время можно рассматривать как временный снимок даты и времени в заданном часовом поясе. Для таких целей она также включает UTC и стандартные смещения, а также поле сокращения зоны, используемое исключительно для форматирования.
Помните, что сравнения в Elixir с помощью ==, >, < и аналогичных функций являются структурными и основаны на полях структуры DateTime. Для правильного сравнения дат и времени используйте функцию compare/2.
Функции в этом модуле работают со структурой DateTime, а также с любой структурой, содержащей те же поля, что и структура DateTime. Такие функции ожидают Calendar.datetime/0 в своих типовec (вместо t/0).
Разработчики должны избегать непосредственного создания структуры DateTime и вместо этого полагаться на функции, предоставляемые этим модулем, а также функции сторонних библиотек для работы с календарем.
Где мои функции?
Вы заметите, что этот модуль содержит только функции преобразования, а также функции, работающие с UTC. Это связано с тем, что для правильной реализации DateTime требуется база данных часовых поясов, которая в настоящее время не предоставляется в составе Elixir.
Эта проблема может быть решена в будущих версиях. Тем временем, используйте сторонние пакеты для построения DateTime и аналогичной функциональности с поддержкой часовых поясов.
Обзор
Типы
- t()
Функции
- compare(datetime1, datetime2)
-
Сравнивает две структуры datetime
- convert(datetime, calendar)
-
Преобразует заданную
datetimeиз одного календаря в другой - convert!(datetime, calendar)
-
Преобразует заданную
datetimeиз одного календаря в другой - diff(datetime1, datetime2, unit \\ :second)
-
Вычисляет разницу между
datetime2иdatetime1 - from_iso8601(string, calendar \\ Calendar.ISO)
-
Парсит строку в формате «Дата и время суток» ISO 8601:2004.
- from_naive(naive_datetime, time_zone)
-
Преобразует заданную
NaiveDateTimeвDateTime - from_naive!(naive_datetime, time_zone)
-
Преобразует заданную
NaiveDateTimeвDateTime - from_unix(integer, unit \\ :second, calendar \\ Calendar.ISO)
-
Преобразует Unix-время в
DateTime - from_unix!(integer, unit \\ :second, calendar \\ Calendar.ISO)
-
Преобразует Unix-время в
DateTime - to_date(datetime)
- to_iso8601(datetime, format \\ :extended)
-
Преобразует заданную datetime в формат ISO 8601:2004
- to_naive(datetime)
-
Преобразует заданную
datetimeвNaiveDateTime - to_string(datetime)
-
Преобразует заданную
datetimeв строку в соответствии с её календарём - to_time(datetime)
- to_unix(datetime, unit \\ :second)
-
Преобразует заданную
datetimeв Unix-время - truncate(datetime, precision)
-
Возвращает заданную datetime с микросекундами, усечёнными до заданной точности (
:microsecond,millisecondили:second) - utc_now(calendar \\ Calendar.ISO)
-
Возвращает текущую datetime в UTC
Типы
t()
t() :: %DateTime{
calendar: Calendar.calendar(),
day: Calendar.day(),
hour: Calendar.hour(),
microsecond: Calendar.microsecond(),
minute: Calendar.minute(),
month: Calendar.month(),
second: Calendar.second(),
std_offset: Calendar.std_offset(),
time_zone: Calendar.time_zone(),
utc_offset: Calendar.utc_offset(),
year: Calendar.year(),
zone_abbr: Calendar.zone_abbr()
} Функции
compare(datetime1, datetime2)
compare(Calendar.datetime(), Calendar.datetime()) :: :lt | :eq | :gt
Сравнивает две структуры datetime.
Возвращает :gt если первая datetime позже второй и :lt в противном случае. Если две datetime равны, возвращается :eq.
Обратите внимание, что при сравнении учитываются как UTC, так и стандартные смещения.
Примеры
iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> dt2 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> DateTime.compare(dt1, dt2)
:gt convert(datetime, calendar)
convert(Calendar.datetime(), Calendar.calendar()) ::
{:ok, t()} | {:error, :incompatible_calendars} Преобразует заданную datetime из одного календаря в другой.
Если невозможно выполнить однозначное преобразование между календарями (см. Calendar.compatible_calendars?/2), возвращается кортеж {:error, :incompatible_calendars}.
Примеры
Представьте, что кто-то реализовал Calendar.Holocene, календарь, основанный на григорианском календаре, который добавляет ровно 10 000 лет к текущему григорианскому году:
iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> DateTime.convert(dt1, Calendar.Holocene)
{:ok, %DateTime{calendar: Calendar.Holocene, day: 29, hour: 23,
microsecond: {0, 0}, minute: 0, month: 2, second: 7, std_offset: 0,
time_zone: "America/Manaus", utc_offset: -14400, year: 12000,
zone_abbr: "AMT"}} convert!(datetime, calendar)
convert!(Calendar.datetime(), Calendar.calendar()) :: t() | no_return()
Преобразует заданную datetime из одного календаря в другой.
Если невозможно выполнить однозначное преобразование между календарями (см. Calendar.compatible_calendars?/2), генерируется исключение ArgumentError.
Примеры
Представьте, что кто-то реализовал Calendar.Holocene, календарь, основанный на григорианском календаре, который добавляет ровно 10 000 лет к текущему григорианскому году:
iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> DateTime.convert!(dt1, Calendar.Holocene)
%DateTime{calendar: Calendar.Holocene, day: 29, hour: 23,
microsecond: {0, 0}, minute: 0, month: 2, second: 7, std_offset: 0,
time_zone: "America/Manaus", utc_offset: -14400, year: 12000,
zone_abbr: "AMT"} diff(datetime1, datetime2, unit \\ :second)
Вычисляет разницу между datetime2 и datetime1.
Результат может быть возвращен в любой единице измерения unit из System.time_unit/0.
Функция возвращает разницу во времени в секундах, где секунды измеряются согласно Calendar.ISO.
Примеры
iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> dt2 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> DateTime.diff(dt1, dt2)
18000
iex> DateTime.diff(dt2, dt1)
-18000 from_iso8601(string, calendar \\ Calendar.ISO)
from_iso8601(String.t(), Calendar.calendar()) ::
{:ok, t(), Calendar.utc_offset()} | {:error, atom()} Парсит строку в формате «Дата и время суток» ISO 8601:2004.
Так как ISO 8601 не включает часовой пояс, заданная строка будет преобразована в UTC, а её смещение в секундах будет возвращено как часть этой функции. Поэтому информация о смещении должна быть присутствовать в строке.
Как указано в стандарте, разделитель «T» может быть опущен, если это не создаёт неоднозначности.
Представления времени с меньшей точностью не поддерживаются.
Обратите внимание, что, хотя ISO 8601 допускает указание даты и времени 24:00:00 как нулевого часа следующего дня, эта запись не поддерживается в Elixir.
Примеры
iex> {:ok, datetime, 0} = DateTime.from_iso8601("2015-01-23T23:50:07Z")
iex> datetime
#DateTime<2015-01-23 23:50:07Z>
iex> {:ok, datetime, 9000} = DateTime.from_iso8601("2015-01-23T23:50:07.123+02:30")
iex> datetime
#DateTime<2015-01-23 21:20:07.123Z>
iex> {:ok, datetime, 9000} = DateTime.from_iso8601("2015-01-23T23:50:07,123+02:30")
iex> datetime
#DateTime<2015-01-23 21:20:07.123Z>
iex> DateTime.from_iso8601("2015-01-23P23:50:07")
{:error, :invalid_format}
iex> DateTime.from_iso8601("2015-01-23 23:50:07A")
{:error, :invalid_format}
iex> DateTime.from_iso8601("2015-01-23T23:50:07")
{:error, :missing_offset}
iex> DateTime.from_iso8601("2015-01-23 23:50:61")
{:error, :invalid_time}
iex> DateTime.from_iso8601("2015-01-32 23:50:07")
{:error, :invalid_date}
iex> DateTime.from_iso8601("2015-01-23T23:50:07.123-00:00")
{:error, :invalid_format}
iex> DateTime.from_iso8601("2015-01-23T23:50:07.123-00:60")
{:error, :invalid_format} from_naive(naive_datetime, time_zone)
from_naive(NaiveDateTime.t(), Calendar.time_zone()) :: {:ok, t()} Преобразует заданную NaiveDateTime в DateTime.
Ожидается часовой пояс для размещения NaiveDateTime. В настоящее время поддерживается только «Etc/UTC».
Примеры
iex> {:ok, datetime} = DateTime.from_naive(~N[2016-05-24 13:26:08.003], "Etc/UTC")
iex> datetime
#DateTime<2016-05-24 13:26:08.003Z> from_naive!(naive_datetime, time_zone)
from_naive!(NaiveDateTime.t(), Calendar.time_zone()) :: t()
Преобразует заданную NaiveDateTime в DateTime.
Ожидается часовой пояс для размещения NaiveDateTime. В настоящее время поддерживается только «Etc/UTC».
Примеры
iex> DateTime.from_naive!(~N[2016-05-24 13:26:08.003], "Etc/UTC") #DateTime<2016-05-24 13:26:08.003Z>
from_unix(integer, unit \\ :second, calendar \\ Calendar.ISO)
from_unix(integer(), :native | System.time_unit(), Calendar.calendar()) ::
{:ok, t()} | {:error, atom()} Преобразует Unix-время в DateTime.
Целое число может быть задано в различных единицах измерения согласно System.convert_time_unit/3, и оно будет преобразовано во внутренние микросекунды.
Unix-время всегда в UTC, поэтому DateTime будет возвращено в UTC.
Примеры
iex> {:ok, datetime} = DateTime.from_unix(1464096368)
iex> datetime
#DateTime<2016-05-24 13:26:08Z>
iex> {:ok, datetime} = DateTime.from_unix(1432560368868569, :microsecond)
iex> datetime
#DateTime<2015-05-25 13:26:08.868569Z> Единица измерения также может быть целым числом, как в System.time_unit/0:
iex> {:ok, datetime} = DateTime.from_unix(143256036886856, 1024)
iex> datetime
#DateTime<6403-03-17 07:05:22.320Z> Поддерживаются отрицательные Unix-времена до -62167219200 секунд, что эквивалентно «0000-01-01T00:00:00Z» или 0 григорианских секунд.
from_unix!(integer, unit \\ :second, calendar \\ Calendar.ISO)
from_unix!(integer(), :native | System.time_unit(), Calendar.calendar()) :: t()
Преобразует Unix-время в DateTime.
Целое число может быть задано в различных единицах измерения в соответствии с System.convert_time_unit/3, и оно будет преобразовано во внутренние микросекунды.
Временные метки Unix всегда находятся в UTC, и поэтому DateTime будет возвращен в UTC.
Примеры
# An easy way to get the Unix epoch is passing 0 to this function iex> DateTime.from_unix!(0) #DateTime<1970-01-01 00:00:00Z> iex> DateTime.from_unix!(1464096368) #DateTime<2016-05-24 13:26:08Z> iex> DateTime.from_unix!(1432560368868569, :microsecond) #DateTime<2015-05-25 13:26:08.868569Z>
to_date(datetime)
to_date(t()) :: Date.t()
Поскольку Date не содержит информации о времени или часовом поясе, данные будут потеряны во время преобразования.
Примеры
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> DateTime.to_date(dt)
~D[2000-02-29] to_iso8601(datetime, format \\ :extended)
to_iso8601(Calendar.datetime(), :extended | :basic) :: String.t()
Преобразует заданную дату и время в формат ISO 8601:2004.
По умолчанию, DateTime.to_iso8601/2 возвращает даты и время в формате «расширенном» для удобства чтения. Он также поддерживает формат «базовый» через передачу параметра :basic.
Поддерживает преобразование только дат и времени в календаре ISO, попытка преобразования дат и времени из других календарей приведет к ошибке.
ВНИМАНИЕ: формат даты и времени ISO 8601 не содержит часового пояса ни в виде его названия, ни в виде его сокращения, что означает потерю информации при преобразовании в такой формат.
Примеры
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> DateTime.to_iso8601(dt)
"2000-02-29T23:00:07+01:00"
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "UTC",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
iex> DateTime.to_iso8601(dt)
"2000-02-29T23:00:07Z"
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> DateTime.to_iso8601(dt, :extended)
"2000-02-29T23:00:07-04:00"
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> DateTime.to_iso8601(dt, :basic)
"20000229T230007-0400" to_naive(datetime)
to_naive(t()) :: NaiveDateTime.t()
Преобразует заданное datetime в NaiveDateTime.
Поскольку NaiveDateTime не содержит информации о часовом поясе, любая информация, связанная с часовым поясом, будет потеряна во время преобразования.
Примеры
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 1},
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> DateTime.to_naive(dt)
~N[2000-02-29 23:00:07.0] to_string(datetime)
to_string(Calendar.datetime()) :: String.t()
Преобразует заданное datetime в строку в соответствии с его календарём.
Примеры
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> DateTime.to_string(dt)
"2000-02-29 23:00:07+01:00 CET Europe/Warsaw"
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "UTC",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
iex> DateTime.to_string(dt)
"2000-02-29 23:00:07Z"
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> DateTime.to_string(dt)
"2000-02-29 23:00:07-04:00 AMT America/Manaus" to_time(datetime)
to_time(t()) :: Time.t()
Поскольку Time не содержит информации о дате и часовом поясе, данные будут потеряны во время преобразования.
Примеры
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...> hour: 23, minute: 0, second: 7, microsecond: {0, 1},
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> DateTime.to_time(dt)
~T[23:00:07.0] to_unix(datetime, unit \\ :second)
to_unix(Calendar.datetime(), System.time_unit()) :: integer()
Преобразует заданное datetime в метку времени Unix.
Ожидается, что datetime использует календарь ISO с годом не меньше 0.
Будет возвращено целое число с указанной единицей измерения в соответствии с System.convert_time_unit/3.
Примеры
iex> 1464096368 |> DateTime.from_unix!() |> DateTime.to_unix()
1464096368
iex> dt = %DateTime{calendar: Calendar.ISO, day: 20, hour: 18, microsecond: {273806, 6},
...> minute: 58, month: 11, second: 19, time_zone: "America/Montevideo",
...> utc_offset: -10800, std_offset: 3600, year: 2014, zone_abbr: "UYST"}
iex> DateTime.to_unix(dt)
1416517099
iex> flamel = %DateTime{calendar: Calendar.ISO, day: 22, hour: 8, microsecond: {527771, 6},
...> minute: 2, month: 3, second: 25, std_offset: 0, time_zone: "Etc/UTC",
...> utc_offset: 0, year: 1418, zone_abbr: "UTC"}
iex> DateTime.to_unix(flamel)
-17412508655 truncate(datetime, precision)
truncate(t(), :microsecond | :millisecond | :second) :: t()
Возвращает заданную дату и время с микросекундами, усеченными до заданной точности (:microsecond, millisecond или :second).
Примеры
iex> dt1 = %DateTime{year: 2017, month: 11, day: 7, zone_abbr: "CET",
...> hour: 11, minute: 45, second: 18, microsecond: {123456, 6},
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Paris"}
iex> DateTime.truncate(dt1, :microsecond)
#DateTime<2017-11-07 11:45:18.123456+01:00 CET Europe/Paris>
iex> dt2 = %DateTime{year: 2017, month: 11, day: 7, zone_abbr: "CET",
...> hour: 11, minute: 45, second: 18, microsecond: {123456, 6},
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Paris"}
iex> DateTime.truncate(dt2, :millisecond)
#DateTime<2017-11-07 11:45:18.123+01:00 CET Europe/Paris>
iex> dt3 = %DateTime{year: 2017, month: 11, day: 7, zone_abbr: "CET",
...> hour: 11, minute: 45, second: 18, microsecond: {123456, 6},
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Paris"}
iex> DateTime.truncate(dt3, :second)
#DateTime<2017-11-07 11:45:18+01:00 CET Europe/Paris> utc_now(calendar \\ Calendar.ISO)
utc_now(Calendar.calendar()) :: t()
Возвращает текущую дату и время в UTC.
Примеры
iex> datetime = DateTime.utc_now() iex> datetime.time_zone "Etc/UTC"
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.6.6/DateTime.html