Spec-Zone.ru › Elixir 1.17

Источник DateTime

Реализация DateTime с часовым поясом.

Этот DateTime можно рассматривать как моментальное изображение даты и времени в заданном часовом поясе. Для этого он включает как смещения UTC, так и стандартного времени, а также поле аббревиатуры часового пояса, используемое исключительно для форматирования. Обратите внимание, что будущие DateTime не гарантированно существуют, так как часовые пояса могут меняться в любое время в будущем из-за геополитических причин. Дополнительную информацию см. в разделе «DateTime как снимки».

Помните, что сравнения в Elixir с использованием ==/2, >/2, </2 и аналогичных функций структурные и основаны на полях структуры DateTime. Для правильного сравнения DateTime используйте функцию compare/2. Наличие функции compare/2 в этом модуле также позволяет использовать функции Enum.min/2 и Enum.max/2 для получения минимальной и максимальной DateTime из Enum. Например:

iex> Enum.min([~U[2022-01-12 00:01:00.00Z], ~U[2021-01-12 00:01:00.00Z]], DateTime)
~U[2021-01-12 00:01:00.00Z]

Разработчики должны избегать создания структуры DateTime напрямую и вместо этого полагаться на функции, предоставляемые этим модулем, а также на функции сторонних библиотек календаря.

База данных часовых поясов

Многие функции в этом модуле требуют базы данных часовых поясов. По умолчанию используется базу данных часовых поясов, возвращаемая Calendar.get_time_zone_database/0, которая по умолчанию является Calendar.UTCOnlyTimeZoneDatabase, обрабатывающей только DateTime в «Etc/UTC» и возвращающей {:error, :utc_only_time_zone_database} для других часовых поясов.

Также можно настроить другие базы данных часовых поясов. Вот некоторые доступные варианты и библиотеки:

  • time_zone_info
  • tz
  • tzdata
  • zoneinfo — рекомендуется для встраиваемых устройств

Для их использования сначала убедитесь, что они добавлены в качестве зависимости в mix.exs. Затем их можно настроить либо через конфигурацию:

config :elixir, :time_zone_database, Tz.TimeZoneDatabase

или вызвав Calendar.put_time_zone_database/1:

Calendar.put_time_zone_database(Tz.TimeZoneDatabase)

См. правильные имена в инструкциях по установке библиотеки.

DateTime как снимки

В первом разделе мы описали DateTime как «моментальное изображение даты и времени в заданном часовом поясе». Чтобы точно понять, что мы имеем в виду, давайте рассмотрим пример.

Представьте себе человека в Польше, который хочет назначить встречу с кем-то в Бразилии в следующем году. Встреча состоится в 2:30 по польскому времени. В какое время состоится встреча в Бразилии?

Вы можете обратиться к базе данных часовых поясов на сегодня, на год вперёд, используя API в этом модуле, и он даст вам ответ, который действителен прямо сейчас. Однако этот ответ может не быть действительным в будущем. Почему? Потому что как Бразилия, так и Польша могут изменить правила часовых поясов, что в конечном счёте повлияет на результат. Например, страна может принять или отказаться от «перевода часов», это процесс, когда мы корректируем часы вперёд или назад на один час раз в год. Всякий раз, когда правила изменяются, точное время 2:30 по польскому времени в Бразилии может измениться.

Другими словами, при работе с будущими DateTime нет гарантии, что полученные результаты будут всегда верны до тех пор, пока событие не произойдёт. Поэтому, когда вы запрашиваете будущее время, получаемые ответы — это снимок, отражающий текущее состояние правил часовых поясов. Для DateTime в прошлом это не проблема, потому что правила часовых поясов не изменяются для прошлых событий.

Что ещё хуже, может оказаться, что 2:30 по польскому времени вообще не существует или является неоднозначным. Если в определённом часовом поясе действует «перевод часов», они переведут свои часы вперёд один раз в год. Когда это происходит, целый час не существует. Затем, когда они переводят часы назад, определённый час произойдёт дважды. Таким образом, если вы хотите назначить встречу на момент этого возвращения, вам нужно будет явно указать, о какой из 2:30 вы говорите: о той, которая в «Летнее время», которая происходит до сдвига, или о той, которая в «Зимнее время», которая происходит после него. Приложения, чувствительные к дате и времени, должны учитывать эти сценарии и правильно сообщать об этом пользователям.

Хорошая новость: Elixir содержит все необходимые инструменты для решения этих проблем. База данных часовых поясов по умолчанию, используемая Elixir, Calendar.UTCOnlyTimeZoneDatabase, работает только с UTC, которая не сталкивается с этими проблемами. Как только вы подключите надлежащую базу данных часовых поясов, функции в этом модуле обратятся к базе данных и вернут соответствующую информацию. Например, обратите внимание на то, как DateTime.new/4 возвращает разные результаты в зависимости от сценариев, описанных в этом разделе.

Преобразование между часовыми поясами

Учитывая предостережения выше и предполагая, что у вас есть полная база данных часовых поясов, вот несколько примеров распространённых сдвигов между часовыми поясами.

# Local time to UTC
new_york = DateTime.from_naive!(~N[2023-06-26T09:30:00], "America/New_York")
#=> #DateTime<2023-06-26 09:30:00-04:00 EDT America/New_York>

utc = DateTime.shift_zone!(new_york, "Etc/UTC")
#=> ~U[2023-06-26 13:30:00Z]

# UTC to local time
DateTime.shift_zone!(utc, "Europe/Paris")
#=> #DateTime<2023-06-26 15:30:00+02:00 CEST Europe/Paris>

Краткое описание

Типы

t()

Функции

add(datetime, amount_to_add, unit \\ :second, time_zone_database \\ Calendar.get_time_zone_database())

Добавляет указанное количество времени к DateTime.

after?(datetime1, datetime2)

Возвращает true, если первое значение datetime строго позже второго.

before?(datetime1, datetime2)

Возвращает true, если первое значение datetime строго раньше второго.

compare(datetime1, datetime2)

Сравнивает две структуры datetime.

convert(datetime, calendar)

Преобразует заданное datetime из одного календаря в другой.

convert!(datetime, calendar)

Преобразует заданное datetime из одного календаря в другой.

diff(datetime1, datetime2, unit \\ :second)

Вычитает datetime2 из datetime1.

from_gregorian_seconds(seconds, arg \\ {0, 0}, calendar \\ Calendar.ISO)

Преобразует количество грегорианских секунд в структуру DateTime.

from_iso8601(string, format_or_calendar \\ Calendar.ISO)

Парсит расширенный формат "Дата и время" согласно ISO 8601:2019.

from_iso8601(string, calendar, format)

Преобразует из ISO8601, задавая как календарь, так и режим.

from_naive(naive_datetime, time_zone, time_zone_database \\ Calendar.get_time_zone_database())

Преобразует заданный NaiveDateTime в DateTime.

from_naive!(naive_datetime, time_zone, time_zone_database \\ Calendar.get_time_zone_database())

Преобразует заданный NaiveDateTime в DateTime.

from_unix(integer, unit \\ :second, calendar \\ Calendar.ISO)

Преобразует заданное время Unix в DateTime.

from_unix!(integer, unit \\ :second, calendar \\ Calendar.ISO)

Преобразует заданное время Unix в DateTime.

new(date, time, time_zone \\ "Etc/UTC", time_zone_database \\ Calendar.get_time_zone_database())

Создаёт datetime из структур date и time.

new!(date, time, time_zone \\ "Etc/UTC", time_zone_database \\ Calendar.get_time_zone_database())

Создаёт datetime из структур date и time, генерируя исключения при ошибках.

now(time_zone, time_zone_database \\ Calendar.get_time_zone_database())

Возвращает текущее datetime в указанной временной зоне.

now!(time_zone, time_zone_database \\ Calendar.get_time_zone_database())

Возвращает текущее datetime в указанной временной зоне, или генерирует исключения при ошибках.

shift(datetime, duration, time_zone_database \\ Calendar.get_time_zone_database())

Смещает заданное datetime на duration в соответствии с его календарем.

shift_zone(datetime, time_zone, time_zone_database \\ Calendar.get_time_zone_database())

Изменяет временную зону DateTime.

shift_zone!(datetime, time_zone, time_zone_database \\ Calendar.get_time_zone_database())

Изменяет временную зону DateTime, или генерирует исключения при ошибках.

to_date(datetime)

Преобразует DateTime в Date.

to_gregorian_seconds(datetime)

Преобразует структуру DateTime в количество грегорианских секунд и микросекунд.

to_iso8601(datetime, format \\ :extended, offset \\ nil)

Преобразует заданное datetime в формат ISO 8601:2019.

to_naive(datetime)

Преобразует данное datetime в NaiveDateTime.

to_string(datetime)

Преобразует заданное datetime в строку в соответствии с его календарем.

to_time(datetime)

Преобразует DateTime в Time.

to_unix(datetime, unit \\ :second)

Преобразует заданное datetime в время Unix.

truncate(datetime, precision)

Возвращает заданное datetime с усечённым полем микросекунд до заданной точности (:microsecond, :millisecond или :second).

utc_now(calendar_or_time_unit \\ Calendar.ISO)

Возвращает текущее datetime в UTC.

utc_now(time_unit, calendar)

Возвращает текущее datetime в UTC, поддерживая конкретный календарь и точность.

Типы

t()Источник

@type 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()
}

Функции

add(datetime, amount_to_add, unit \\ :second, time_zone_database \\ Calendar.get_time_zone_database())Source

@spec add(
  Calendar.datetime(),
  integer(),
  :day | :hour | :minute | System.time_unit(),
  Calendar.time_zone_database()
) :: t()

Добавляет заданное количество времени к DateTime.

Принимает amount_to_add в любом unit. unit может быть :day, :hour, :minute, :second или любой точностью долей секунды из System.time_unit/0. По умолчанию :second. Отрицательные значения будут перемещать во времени назад.

Эта функция всегда рассматривает единицу измерения, вычисляемую согласно Calendar.ISO.

Эта функция использует непрерывное представление времени, игнорируя время отображения и изменения часового пояса. Например, если вы добавите один день, когда происходят изменения летнего/зимнего времени, то время также изменится вперёд или назад на один час, так что пройдёт ровно 24 часа. Аналогично, добавление всего нескольких секунд к дате и времени непосредственно перед «переходом на летнее время» может привести к тому, что время отображения увеличится более чем на час.

Хотя это означает, что эта функция точна с точки зрения прошедшего времени, её результат может быть вводящим в заблуждение в определённых случаях использования. Например, если пользователь запросит встречу каждый день в 15:00, и вы используете эту функцию для вычисления всех будущих встреч, добавляя день за днём, эта функция может изменить время встречи на 14:00 или 16:00, если есть изменения в текущем часовом поясе. Вычисление повторяющихся дат и времени в стандартной библиотеке Elixir в настоящее время не поддерживается, но доступно в сторонних библиотеках.

Примеры

iex> dt = DateTime.from_naive!(~N[2018-11-15 10:00:00], "Europe/Copenhagen", FakeTimeZoneDatabase)
iex> dt |> DateTime.add(3600, :second, FakeTimeZoneDatabase)
#DateTime<2018-11-15 11:00:00+01:00 CET Europe/Copenhagen>

iex> DateTime.add(~U[2018-11-15 10:00:00Z], 3600, :second)
~U[2018-11-15 11:00:00Z]

При добавлении 3 секунд непосредственно перед «переходом на летнее время» мы переходим от 1:59:59 до 3:00:02:

iex> dt = DateTime.from_naive!(~N[2019-03-31 01:59:59.123], "Europe/Copenhagen", FakeTimeZoneDatabase)
iex> dt |> DateTime.add(3, :second, FakeTimeZoneDatabase)
#DateTime<2019-03-31 03:00:02.123+02:00 CEST Europe/Copenhagen>

При добавлении 1 дня во время «перехода на летнее время» час также меняется:

iex> dt = DateTime.from_naive!(~N[2019-03-31 01:00:00], "Europe/Copenhagen", FakeTimeZoneDatabase)
iex> dt |> DateTime.add(1, :day, FakeTimeZoneDatabase)
#DateTime<2019-04-01 02:00:00+02:00 CEST Europe/Copenhagen>

Эта операция объединяет точность простого времени с заданной единицей измерения:

iex> result = DateTime.add(~U[2014-10-02 00:29:10Z], 21, :millisecond)
~U[2014-10-02 00:29:10.021Z]
iex> result.microsecond
{21000, 3}

Чтобы сдвинуть дату и время на Duration и в соответствии с его основным календарём, используйте DateTime.shift/3.

after?(datetime1, datetime2)Source

@spec after?(Calendar.datetime(), Calendar.datetime()) :: boolean()

Возвращает true если первое значение даты и времени строго позже второго.

Примеры

iex> DateTime.after?(~U[2022-02-02 11:00:00Z], ~U[2021-01-01 11:00:00Z])
true
iex> DateTime.after?(~U[2021-01-01 11:00:00Z], ~U[2021-01-01 11:00:00Z])
false
iex> DateTime.after?(~U[2021-01-01 11:00:00Z], ~U[2022-02-02 11:00:00Z])
false

before?(datetime1, datetime2)Source

@spec before?(Calendar.datetime(), Calendar.datetime()) :: boolean()

Возвращает true если первое значение даты и времени строго раньше второго.

Примеры

iex> DateTime.before?(~U[2021-01-01 11:00:00Z], ~U[2022-02-02 11:00:00Z])
true
iex> DateTime.before?(~U[2021-01-01 11:00:00Z], ~U[2021-01-01 11:00:00Z])
false
iex> DateTime.before?(~U[2022-02-02 11:00:00Z], ~U[2021-01-01 11:00:00Z])
false

compare(datetime1, datetime2)Source

@spec compare(Calendar.datetime(), Calendar.datetime()) :: :lt | :eq | :gt

Сравнивает две структуры даты и времени.

Возвращает :gt если первое значение даты и времени позже второго и :lt в обратном случае. Если две даты и время равны, возвращается :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)Source

@spec 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)Source

@spec convert!(Calendar.datetime(), Calendar.calendar()) :: t()

Преобразует заданную 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)Source

@spec diff(
  Calendar.datetime(),
  Calendar.datetime(),
  :day | :hour | :minute | System.time_unit()
) :: integer()

Вычитает datetime2 из datetime1.

Результат может быть возвращён в любой :day, :hour, :minute, или любой unit единице измерения из System.time_unit/0. Единица измерения определяется согласно Calendar.ISO и по умолчанию равна :second.

Дробные результаты не поддерживаются и усекаются.

Примеры

iex> DateTime.diff(~U[2024-01-15 10:00:10Z], ~U[2024-01-15 10:00:00Z])
10

Эта функция также учитывает смещения часовых поясов:

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
iex> DateTime.diff(dt1, dt2, :hour)
5
iex> DateTime.diff(dt2, dt1, :hour)
-5

from_gregorian_seconds(seconds, arg \\ {0, 0}, calendar \\ Calendar.ISO)Source

@spec from_gregorian_seconds(integer(), Calendar.microsecond(), Calendar.calendar()) ::
  t()

Преобразует количество григорианских секунд в структуру DateTime.

Возвращаемая DateTime будет иметь часовой пояс UTC, если вам нужен другой часовой пояс, пожалуйста, воспользуйтесь DateTime.shift_zone/3.

Примеры

iex> DateTime.from_gregorian_seconds(1)
~U[0000-01-01 00:00:01Z]
iex> DateTime.from_gregorian_seconds(63_755_511_991, {5000, 3})
~U[2020-05-01 00:26:31.005Z]
iex> DateTime.from_gregorian_seconds(-1)
~U[-0001-12-31 23:59:59Z]

from_iso8601(string, format_or_calendar \\ Calendar.ISO)Source

@spec from_iso8601(String.t(), Calendar.calendar() | :extended | :basic) ::
  {:ok, t(), Calendar.utc_offset()} | {:error, atom()}

Парсит расширенный формат «Дата и время суток», описанный в ISO 8601:2019.

Поскольку ISO 8601 не включает правильный часовой пояс, заданная строка будет преобразована в UTC, а её смещение во времени в секундах будет возвращено в качестве части этой функции. Поэтому информация о смещении должна присутствовать в строке.

Как указано в стандарте, разделитель «T» может быть опущен при необходимости, так как в этой функции нет неоднозначности.

Обратите внимание, что добавочные секунды не поддерживаются встроенным Calendar.ISO.

Примеры

iex> {:ok, datetime, 0} = DateTime.from_iso8601("2015-01-23T23:50:07Z")
iex> datetime
~U[2015-01-23 23:50:07Z]

iex> {:ok, datetime, 9000} = DateTime.from_iso8601("2015-01-23T23:50:07.123+02:30")
iex> datetime
~U[2015-01-23 21:20:07.123Z]

iex> {:ok, datetime, 9000} = DateTime.from_iso8601("2015-01-23T23:50:07,123+02:30")
iex> datetime
~U[2015-01-23 21:20:07.123Z]

iex> {:ok, datetime, 0} = DateTime.from_iso8601("-2015-01-23T23:50:07Z")
iex> datetime
~U[-2015-01-23 23:50:07Z]

iex> {:ok, datetime, 9000} = DateTime.from_iso8601("-2015-01-23T23:50:07,123+02:30")
iex> datetime
~U[-2015-01-23 21:20:07.123Z]

iex> {:ok, datetime, 9000} = DateTime.from_iso8601("20150123T235007.123+0230", :basic)
iex> datetime
~U[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-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}

from_iso8601(string, calendar, format)Source

@spec from_iso8601(String.t(), Calendar.calendar(), :extended | :basic) ::
  {:ok, t(), Calendar.utc_offset()} | {:error, atom()}

Преобразует из ISO8601, задавая как календарь, так и режим.

См. from_iso8601/2 для получения дополнительной информации.

Примеры

iex> {:ok, datetime, 9000} = DateTime.from_iso8601("2015-01-23T23:50:07,123+02:30", Calendar.ISO, :extended)
iex> datetime
~U[2015-01-23 21:20:07.123Z]

iex> {:ok, datetime, 9000} = DateTime.from_iso8601("20150123T235007.123+0230", Calendar.ISO, :basic)
iex> datetime
~U[2015-01-23 21:20:07.123Z]

from_naive(naive_datetime, time_zone, time_zone_database \\ Calendar.get_time_zone_database())Source

@spec from_naive(
  Calendar.naive_datetime(),
  Calendar.time_zone(),
  Calendar.time_zone_database()
) ::
  {:ok, t()}
  | {:ambiguous, first_datetime :: t(), second_datetime :: t()}
  | {:gap, t(), t()}
  | {:error,
     :incompatible_calendars
     | :time_zone_not_found
     | :utc_only_time_zone_database}

Преобразует заданный NaiveDateTime в DateTime.

Ожидается часовой пояс для установки NaiveDateTime. Если часовой пояс — "Etc/UTC", преобразование всегда выполняется успешно. В противном случае, NaiveDateTime проверяется по базе данных часовых поясов, указанной как time_zone_database. См. раздел «База данных часовых поясов» в документации модуля.

Примеры

iex> DateTime.from_naive(~N[2016-05-24 13:26:08.003], "Etc/UTC")
{:ok, ~U[2016-05-24 13:26:08.003Z]}

Если datetime неоднозначен — например, при переходе с летнего на зимнее время — возвращаются две возможные допустимые даты и времени в кортеже. Первая дата и время — это также та, которая идёт первой в хронологическом порядке, а вторая — последняя.

iex> {:ambiguous, first_dt, second_dt} = DateTime.from_naive(~N[2018-10-28 02:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase)
iex> first_dt
#DateTime<2018-10-28 02:30:00+02:00 CEST Europe/Copenhagen>
iex> second_dt
#DateTime<2018-10-28 02:30:00+01:00 CET Europe/Copenhagen>

Если существует разрыв во времени отображения — например, весной, когда часы переводятся вперёд — возвращаются самая поздняя допустимая дата и время перед разрывом и самая ранняя допустимая дата и время после разрыва.

iex> {:gap, just_before, just_after} = DateTime.from_naive(~N[2019-03-31 02:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase)
iex> just_before
#DateTime<2019-03-31 01:59:59.999999+01:00 CET Europe/Copenhagen>
iex> just_after
#DateTime<2019-03-31 03:00:00+02:00 CEST Europe/Copenhagen>

Большинство времени существует одна и только одна допустимая дата и время для определённой даты и времени в определённом часовом поясе.

iex> {:ok, datetime} = DateTime.from_naive(~N[2018-07-28 12:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase)
iex> datetime
#DateTime<2018-07-28 12:30:00+02:00 CEST Europe/Copenhagen>

Эта функция принимает любую карту или структуру, которая содержит по крайней мере те же поля, что и структура NaiveDateTime. Наиболее распространённым примером является DateTime. В этом случае информация о часовом поясе этого DateTime полностью игнорируется. Это тот же принцип, что и передача DateTime в Date.to_iso8601/2. Date.to_iso8601/2 извлекает только поля, относящиеся к дате (календарь, год, месяц и день) заданной структуры и игнорирует все остальные.

Таким образом, если у вас есть DateTime в одном часовом поясе, вы можете получить то же время отображения в другом часовом поясе. Например, если у вас есть 2018-08-24 10:00:00 в Копенгагене и вам нужен DateTime для 2018-08-24 10:00:00 в UTC, вы можете сделать:

iex> cph_datetime = DateTime.from_naive!(~N[2018-08-24 10:00:00], "Europe/Copenhagen", FakeTimeZoneDatabase)
iex> {:ok, utc_datetime} = DateTime.from_naive(cph_datetime, "Etc/UTC", FakeTimeZoneDatabase)
iex> utc_datetime
~U[2018-08-24 10:00:00Z]

Если вместо этого вам нужен DateTime для той же точки во времени в другом часовом поясе, см. функцию DateTime.shift_zone/3, которая преобразует 2018-08-24 10:00:00 в Копенгагене в 2018-08-24 08:00:00 в UTC.

from_naive!(naive_datetime, time_zone, time_zone_database \\ Calendar.get_time_zone_database())Source

@spec from_naive!(
  NaiveDateTime.t(),
  Calendar.time_zone(),
  Calendar.time_zone_database()
) :: t()

Преобразует заданный NaiveDateTime в DateTime.

Ожидается часовой пояс для установки NaiveDateTime. Если часовой пояс — "Etc/UTC", преобразование всегда выполняется успешно. В противном случае, NaiveDateTime проверяется по базе данных часовых поясов, указанной как time_zone_database. См. раздел «База данных часовых поясов» в документации модуля.

Примеры

iex> DateTime.from_naive!(~N[2016-05-24 13:26:08.003], "Etc/UTC")
~U[2016-05-24 13:26:08.003Z]

iex> DateTime.from_naive!(~N[2018-05-24 13:26:08.003], "Europe/Copenhagen", FakeTimeZoneDatabase)
#DateTime<2018-05-24 13:26:08.003+02:00 CEST Europe/Copenhagen>

from_unix(integer, unit \\ :second, calendar \\ Calendar.ISO)Source

@spec from_unix(integer(), :native | System.time_unit(), Calendar.calendar()) ::
  {:ok, t()} | {:error, atom()}

Преобразует заданное время Unix в DateTime.

Целое число может быть задано в разных единицах измерения согласно System.convert_time_unit/3, и оно будет преобразовано во внутренние микросекунды. Поддерживается до 253402300799 секунд.

Время Unix всегда в UTC, поэтому DateTime будет возвращено в UTC.

Примеры

iex> {:ok, datetime} = DateTime.from_unix(1_464_096_368)
iex> datetime
~U[2016-05-24 13:26:08Z]

iex> {:ok, datetime} = DateTime.from_unix(1_432_560_368_868_569, :microsecond)
iex> datetime
~U[2015-05-25 13:26:08.868569Z]

iex> {:ok, datetime} = DateTime.from_unix(253_402_300_799)
iex> datetime
~U[9999-12-31 23:59:59Z]

iex> {:error, :invalid_unix_time} = DateTime.from_unix(253_402_300_800)

Единица измерения также может быть целым числом, как в System.time_unit/0:

iex> {:ok, datetime} = DateTime.from_unix(143_256_036_886_856, 1024)
iex> datetime
~U[6403-03-17 07:05:22.320312Z]

Поддерживаются отрицательные времена Unix до -377705116800 секунд:

iex> {:ok, datetime} = DateTime.from_unix(-377_705_116_800)
iex> datetime
~U[-9999-01-01 00:00:00Z]

iex> {:error, :invalid_unix_time} = DateTime.from_unix(-377_705_116_801)

from_unix!(integer, unit \\ :second, calendar \\ Calendar.ISO)Source

@spec 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)
~U[1970-01-01 00:00:00Z]

iex> DateTime.from_unix!(1_464_096_368)
~U[2016-05-24 13:26:08Z]

iex> DateTime.from_unix!(1_432_560_368_868_569, :microsecond)
~U[2015-05-25 13:26:08.868569Z]

iex> DateTime.from_unix!(143_256_036_886_856, 1024)
~U[6403-03-17 07:05:22.320312Z]

new(date, time, time_zone \\ "Etc/UTC", time_zone_database \\ Calendar.get_time_zone_database())Source

@spec new(Date.t(), Time.t(), Calendar.time_zone(), Calendar.time_zone_database()) ::
  {:ok, t()}
  | {:ambiguous, first_datetime :: t(), second_datetime :: t()}
  | {:gap, t(), t()}
  | {:error,
     :incompatible_calendars
     | :time_zone_not_found
     | :utc_only_time_zone_database}

Создаёт datetime из структур date и time.

Ожидается часовой пояс для установки DateTime. Если часовой пояс не указан, он по умолчанию устанавливается в "Etc/UTC", что всегда выполняется успешно. В противном случае, DateTime проверяется по базе данных часовых поясов, указанной как time_zone_database. См. раздел «База данных часовых поясов» в документации модуля.

Примеры

iex> DateTime.new(~D[2016-05-24], ~T[13:26:08.003], "Etc/UTC")
{:ok, ~U[2016-05-24 13:26:08.003Z]}

Если datetime неоднозначен — например, при переходе с летнего на зимнее время — возвращаются две возможные допустимые даты и времени в кортеже. Первая дата и время — это также та, которая идёт первой в хронологическом порядке, а вторая — последняя.

iex> {:ambiguous, first_dt, second_dt} = DateTime.new(~D[2018-10-28], ~T[02:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase)
iex> first_dt
#DateTime<2018-10-28 02:30:00+02:00 CEST Europe/Copenhagen>
iex> second_dt
#DateTime<2018-10-28 02:30:00+01:00 CET Europe/Copenhagen>

Если существует разрыв во времени отображения — например, весной, когда часы переводятся вперёд — возвращаются самая поздняя допустимая дата и время перед разрывом и самая ранняя допустимая дата и время после разрыва.

iex> {:gap, just_before, just_after} = DateTime.new(~D[2019-03-31], ~T[02:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase)
iex> just_before
#DateTime<2019-03-31 01:59:59.999999+01:00 CET Europe/Copenhagen>
iex> just_after
#DateTime<2019-03-31 03:00:00+02:00 CEST Europe/Copenhagen>

Большинство времени существует одна и только одна допустимая дата и время для определённой даты и времени в определённом часовом поясе.

iex> {:ok, datetime} = DateTime.new(~D[2018-07-28], ~T[12:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase)
iex> datetime
#DateTime<2018-07-28 12:30:00+02:00 CEST Europe/Copenhagen>

new!(date, time, time_zone \\ "Etc/UTC", time_zone_database \\ Calendar.get_time_zone_database())Source

@spec new!(Date.t(), Time.t(), Calendar.time_zone(), Calendar.time_zone_database()) ::
  t()

Создаёт datetime из структур date и time, выбрасывая ошибку при ошибках.

Ожидается часовой пояс для установки DateTime. Если часовой пояс не указан, он по умолчанию устанавливается в "Etc/UTC", что всегда выполняется успешно. В противном случае, DateTime проверяется по базе данных часовых поясов, указанной как time_zone_database. См. раздел «База данных часовых поясов» в документации модуля.

Примеры

iex> DateTime.new!(~D[2016-05-24], ~T[13:26:08.003], "Etc/UTC")
~U[2016-05-24 13:26:08.003Z]

Если datetime неоднозначен — например, при переходе с летнего на зимнее время — будет выброшена ошибка.

iex> DateTime.new!(~D[2018-10-28], ~T[02:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase)
** (ArgumentError) cannot build datetime with ~D[2018-10-28] and ~T[02:30:00] because such instant is ambiguous in time zone Europe/Copenhagen as there is an overlap between #DateTime<2018-10-28 02:30:00+02:00 CEST Europe/Copenhagen> and #DateTime<2018-10-28 02:30:00+01:00 CET Europe/Copenhagen>

Если существует разрыв во времени отображения — например, весной, когда часы переводятся вперёд — будет выброшена ошибка.

iex> DateTime.new!(~D[2019-03-31], ~T[02:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase)
** (ArgumentError) cannot build datetime with ~D[2019-03-31] and ~T[02:30:00] because such instant does not exist in time zone Europe/Copenhagen as there is a gap between #DateTime<2019-03-31 01:59:59.999999+01:00 CET Europe/Copenhagen> and #DateTime<2019-03-31 03:00:00+02:00 CEST Europe/Copenhagen>

Большинство времени существует одна и только одна допустимая дата и время для определённой даты и времени в определённом часовом поясе.

iex> datetime = DateTime.new!(~D[2018-07-28], ~T[12:30:00], "Europe/Copenhagen", FakeTimeZoneDatabase)
iex> datetime
#DateTime<2018-07-28 12:30:00+02:00 CEST Europe/Copenhagen>

now(time_zone, time_zone_database \\ Calendar.get_time_zone_database())Source

@spec now(Calendar.time_zone(), Calendar.time_zone_database()) ::
  {:ok, t()} | {:error, :time_zone_not_found | :utc_only_time_zone_database}

Возвращает текущую дату и время в указанном часовом поясе.

По умолчанию используется значение часового пояса, возвращаемое Calendar.get_time_zone_database/0, которое по умолчанию соответствует Calendar.UTCOnlyTimeZoneDatabase, обрабатывающему только datetime "Etc/UTC". Другие базы данных часовых поясов могут быть переданы в качестве аргумента или установлены глобально. См. раздел «База данных часовых поясов» в документации модуля.

Примеры

iex> {:ok, datetime} = DateTime.now("Etc/UTC")
iex> datetime.time_zone
"Etc/UTC"

iex> DateTime.now("Europe/Copenhagen")
{:error, :utc_only_time_zone_database}

iex> DateTime.now("bad timezone", FakeTimeZoneDatabase)
{:error, :time_zone_not_found}

now!(time_zone, time_zone_database \\ Calendar.get_time_zone_database())Source

@spec now!(Calendar.time_zone(), Calendar.time_zone_database()) :: t()

Возвращает текущую дату и время в указанном часовом поясе или выбрасывает ошибку при ошибках

См. now/2 для получения дополнительной информации.

Примеры

iex> datetime = DateTime.now!("Etc/UTC")
iex> datetime.time_zone
"Etc/UTC"

iex> DateTime.now!("Europe/Copenhagen")
** (ArgumentError) cannot get current datetime in "Europe/Copenhagen" time zone, reason: :utc_only_time_zone_database

iex> DateTime.now!("bad timezone", FakeTimeZoneDatabase)
** (ArgumentError) cannot get current datetime in "bad timezone" time zone, reason: :time_zone_not_found
END_OF_DOCUMENT_MARKER

shift(datetime, duration, time_zone_database \\ Calendar.get_time_zone_database())Source

@spec shift(Calendar.datetime(), Duration.duration(), Calendar.time_zone_database()) ::
  t()

Сдвигает заданный datetime на duration в соответствии с его календарем.

Допустимые единицы измерения: :year, :month, :week, :day, :hour, :minute, :second, :microsecond.

Эта операция эквивалентна сдвигу времени отображения (иначе говоря, значения, которое увидит пользователь в данном часовом поясе на своих часах), затем применению смещения часового пояса для преобразования в UTC и, наконец, вычислению нового часового пояса в случае сдвигов. Это гарантирует, что shift/3 всегда возвращает допустимый datetime.

С другой стороны, часовые пояса, которые соблюдают «летнее время» или другие изменения, в течение летнего/зимнего времени будут добавлять/удалять часы из результирующего datetime:

dt = DateTime.new!(~D[2019-03-31], ~T[01:00:00], "Europe/Copenhagen")
DateTime.shift(dt, hour: 1)
#=> #DateTime<2019-03-31 03:00:00+02:00 CEST Europe/Copenhagen>

dt = DateTime.new!(~D[2018-11-04], ~T[00:00:00], "America/Los_Angeles")
DateTime.shift(dt, hour: 2)
#=> #DateTime<2018-11-04 01:00:00-08:00 PST America/Los_Angeles>

В случае, если вы не хотите, чтобы эти изменения происходили автоматически, или если вы хотите отобразить конфликты часовых поясов пользователю, вы можете сдвинуть datetime как naive datetime, а затем использовать from_naive/2:

dt |> NaiveDateTime.shift(duration) |> DateTime.from_naive(dt.time_zone)

При использовании стандартного календаря ISO, продолжительности сворачиваются и применяются в порядке месяцев, затем секунд и микросекунд:

  • при сдвиге на 1 год и 2 месяца дата фактически сдвигается на 14 месяцев
  • недели, дни и меньшие единицы сворачиваются в секунды и микросекунды

При сдвиге на месяц дни округляются вниз до ближайшей допустимой даты.

Примеры

iex> DateTime.shift(~U[2016-01-01 00:00:00Z], month: 2)
~U[2016-03-01 00:00:00Z]
iex> DateTime.shift(~U[2016-01-01 00:00:00Z], year: 1, week: 4)
~U[2017-01-29 00:00:00Z]
iex> DateTime.shift(~U[2016-01-01 00:00:00Z], minute: -25)
~U[2015-12-31 23:35:00Z]
iex> DateTime.shift(~U[2016-01-01 00:00:00Z], minute: 5, microsecond: {500, 4})
~U[2016-01-01 00:05:00.0005Z]

# leap years
iex> DateTime.shift(~U[2024-02-29 00:00:00Z], year: 1)
~U[2025-02-28 00:00:00Z]
iex> DateTime.shift(~U[2024-02-29 00:00:00Z], year: 4)
~U[2028-02-29 00:00:00Z]

# rounding down
iex> DateTime.shift(~U[2015-01-31 00:00:00Z], month: 1)
~U[2015-02-28 00:00:00Z]

shift_zone(datetime, time_zone, time_zone_database \\ Calendar.get_time_zone_database())Source

@spec shift_zone(t(), Calendar.time_zone(), Calendar.time_zone_database()) ::
  {:ok, t()} | {:error, :time_zone_not_found | :utc_only_time_zone_database}

Изменяет часовой пояс DateTime.

Возвращает DateTime для той же точки времени, но в предоставленном часовом поясе. Предполагается, что DateTime является допустимым и существует в данном часовом поясе и календаре.

По умолчанию используется базовая база данных часовых поясов, возвращаемая Calendar.get_time_zone_database/0, которая по умолчанию равна Calendar.UTCOnlyTimeZoneDatabase, обрабатывающей только datetime "Etc/UTC". Другие базы данных часовых поясов могут быть переданы в качестве аргумента или установлены глобально. См. раздел "База данных часовых поясов" в документации модуля.

Примеры

iex> {:ok, pacific_datetime} = DateTime.shift_zone(~U[2018-07-16 10:00:00Z], "America/Los_Angeles", FakeTimeZoneDatabase)
iex> pacific_datetime
#DateTime<2018-07-16 03:00:00-07:00 PDT America/Los_Angeles>

iex> DateTime.shift_zone(~U[2018-07-16 10:00:00Z], "bad timezone", FakeTimeZoneDatabase)
{:error, :time_zone_not_found}

shift_zone!(datetime, time_zone, time_zone_database \\ Calendar.get_time_zone_database())Source

@spec shift_zone!(t(), Calendar.time_zone(), Calendar.time_zone_database()) :: t()

Изменяет часовой пояс DateTime или вызывает исключение при ошибках.

См. shift_zone/3 для получения дополнительной информации.

Примеры

iex> DateTime.shift_zone!(~U[2018-07-16 10:00:00Z], "America/Los_Angeles", FakeTimeZoneDatabase)
#DateTime<2018-07-16 03:00:00-07:00 PDT America/Los_Angeles>

iex> DateTime.shift_zone!(~U[2018-07-16 10:00:00Z], "bad timezone", FakeTimeZoneDatabase)
** (ArgumentError) cannot shift ~U[2018-07-16 10:00:00Z] to "bad timezone" time zone, reason: :time_zone_not_found

to_date(datetime)Source

@spec to_date(Calendar.datetime()) :: Date.t()

Преобразует DateTime в Date.

Поскольку 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_gregorian_seconds(datetime)Source

@spec to_gregorian_seconds(Calendar.datetime()) :: {integer(), non_neg_integer()}

Преобразует структуру DateTime в количество грегорианских секунд и микросекунд.

Примеры

iex> dt = %DateTime{year: 0000, month: 1, day: 1, zone_abbr: "UTC",
...>                hour: 0, minute: 0, second: 1, microsecond: {0, 0},
...>                utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
iex> DateTime.to_gregorian_seconds(dt)
{1, 0}

iex> dt = %DateTime{year: 2020, month: 5, day: 1, zone_abbr: "UTC",
...>                hour: 0, minute: 26, second: 31, microsecond: {5000, 0},
...>                utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
iex> DateTime.to_gregorian_seconds(dt)
{63_755_511_991, 5000}

iex> dt = %DateTime{year: 2020, month: 5, day: 1, zone_abbr: "CET",
...>                hour: 1, minute: 26, second: 31, microsecond: {5000, 0},
...>                utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> DateTime.to_gregorian_seconds(dt)
{63_755_511_991, 5000}

to_iso8601(datetime, format \\ :extended, offset \\ nil)Source

@spec to_iso8601(Calendar.datetime(), :basic | :extended, nil | integer()) ::
  String.t()

Преобразует заданный datetime в формат ISO 8601:2019.

По умолчанию DateTime.to_iso8601/2 возвращает datetime в формате "extended" для лучшей читабельности. Также поддерживается формат "basic" через параметр :basic.

Поддерживает преобразование только datetime в календаре ISO, попытка преобразования datetime из других календарей вызовет исключение. Также можно указать смещение для форматированной строки.

ПРЕДУПРЕЖДЕНИЕ: формат datetime 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"

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, 3600)
"2000-03-01T04:00:07+01: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, :extended, 0)
"2000-03-01T03:00:07+00:00"

iex> dt = %DateTime{year: 2000, month: 3, day: 01, zone_abbr: "UTC",
...>                hour: 03, minute: 0, second: 7, microsecond: {0, 0},
...>                utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
iex> DateTime.to_iso8601(dt, :extended, 0)
"2000-03-01T03:00:07Z"

iex> {:ok, dt, offset} = DateTime.from_iso8601("2000-03-01T03:00:07Z")
iex> "2000-03-01T03:00:07Z" = DateTime.to_iso8601(dt, :extended, offset)

to_naive(datetime)Source

@spec to_naive(Calendar.datetime()) :: 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)Source

@spec 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"

iex> dt = %DateTime{year: -100, month: 12, day: 19, zone_abbr: "CET",
...>                hour: 3, minute: 20, second: 31, microsecond: {0, 0},
...>                utc_offset: 3600, std_offset: 0, time_zone: "Europe/Stockholm"}
iex> DateTime.to_string(dt)
"-0100-12-19 03:20:31+01:00 CET Europe/Stockholm"

to_time(datetime)Source

@spec to_time(Calendar.datetime()) :: Time.t()

Преобразует DateTime в Time.

Поскольку 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)Source

@spec to_unix(Calendar.datetime(), :native | System.time_unit()) :: integer()

Преобразует заданный datetime в время Unix.

Ожидается, что datetime использует календарь ISO с годом не менее 0.

Будет возвращена целая часть с заданной единицей, согласно System.convert_time_unit/3.

Примеры

iex> 1_464_096_368 |> 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)Source

@spec truncate(Calendar.datetime(), :microsecond | :millisecond | :second) :: t()

Возвращает заданный datetime с усечённым полем микросекунд до заданной точности (:microsecond, :millisecond или :second).

Заданный datetime возвращается без изменений, если он уже имеет меньшую точность, чем указанная.

Примеры

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_or_time_unit \\ Calendar.ISO)Source

@spec utc_now(Calendar.calendar() | :native | :microsecond | :millisecond | :second) ::
  t()

Возвращает текущий datetime в UTC.

Если вам нужно текущее время в секундах Unix, используйте System.os_time/1 вместо этого.

Вы также можете передать единицу времени, чтобы автоматически усечь полученный datetime. Это доступно начиная с версии v1.15.0.

Единица измерения по умолчанию, если не указана, — :native, что приводит к разрешению по умолчанию в микросекундах.

Примеры

iex> datetime = DateTime.utc_now()
iex> datetime.time_zone
"Etc/UTC"

iex> datetime = DateTime.utc_now(:second)
iex> datetime.microsecond
{0, 0}

utc_now(time_unit, calendar)Source

@spec utc_now(:native | :microsecond | :millisecond | :second, Calendar.calendar()) ::
  t()

Возвращает текущий datetime в UTC, поддерживающий конкретный календарь и точность.

Если вам нужно текущее время в секундах Unix, используйте System.os_time/1 вместо этого.

Примеры

iex> datetime = DateTime.utc_now(:microsecond, Calendar.ISO)
iex> datetime.time_zone
"Etc/UTC"

iex> datetime = DateTime.utc_now(:second, Calendar.ISO)
iex> datetime.microsecond
{0, 0}

Скачать версию ePub

Создано с помощью ExDoc (v0.34.1) для язык программирования Elixir

© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.17.2/DateTime.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API