DateTime

A datetime implementation with a time zone.

This datetime can be seen as an ephemeral snapshot of a datetime at a given time zone. For such purposes, it also includes both UTC and Standard offsets, as well as the zone abbreviation field used exclusively for formatting purposes.

Developers should avoid creating the DateTime struct directly and instead rely on the functions provided by this module as well as the ones in 3rd party calendar libraries.

Where are my functions?

You will notice this module only contains conversion functions as well as functions that work on UTC. This is because a proper DateTime implementation requires a TimeZone database which currently is not provided as part of Elixir.

Such may be addressed in upcoming versions, meanwhile, use 3rd party packages to provide DateTime building and similar functionality with time zone backing.

Summary

Types

t()

Functions

compare(datetime1, datetime2)

Compares two DateTime structs

from_iso8601(arg1)

Parses the extended “Date and time of day” format described by ISO 8601:2004

from_naive(naive_datetime, time_zone)

Converts the given NaiveDateTime to DateTime

from_naive!(naive_datetime, time_zone)

Converts the given NaiveDateTime to DateTime

from_unix(integer, unit \\ :second)

Converts the given Unix time to DateTime

from_unix!(integer, unit \\ :second)

Converts the given Unix time to DateTime

to_date(date_time)

Converts a DateTime into a Date

to_iso8601(map)

Converts the given datetime to ISO 8601:2004 format

to_naive(date_time)

Converts a DateTime into a NaiveDateTime

to_string(map)

Converts the given datetime to a string according to its calendar

to_time(date_time)

Converts a DateTime into Time

to_unix(datetime, unit \\ :second)

Converts the given DateTime to Unix time

utc_now()

Returns the current datetime in UTC

Types

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

Functions

compare(datetime1, datetime2)

compare(DateTime.t(), DateTime.t()) :: :lt | :eq | :gt

Compares two DateTime structs.

Returns :gt if first datetime is later than the second and :lt for vice versa. If the two datetimes are equal :eq is returned.

Note that both utc and stc offsets will be taken into account when comparison is done.

Examples

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

from_iso8601(arg1)

from_iso8601(String.t()) ::
  {:ok, t(), Calendar.utc_offset()} |
  {:error, atom()}

Parses the extended “Date and time of day” format described by ISO 8601:2004.

Since ISO8601 does not include the proper time zone, the given string will be converted to UTC and its offset in seconds will be returned as part of this function. Therefore offset information must be present in the string.

As specified in the standard, the separator “T” may be omitted if desired as there is no ambiguity within this function.

Time representations with reduced accuracy are not supported.

Examples

iex> DateTime.from_iso8601("2015-01-23T23:50:07Z")
{:ok, %DateTime{calendar: Calendar.ISO, day: 23, hour: 23, microsecond: {0, 0}, minute: 50, month: 1, second: 7, std_offset: 0,
                time_zone: "Etc/UTC", utc_offset: 0, year: 2015, zone_abbr: "UTC"}, 0}
iex> DateTime.from_iso8601("2015-01-23T23:50:07.123+02:30")
{:ok, %DateTime{calendar: Calendar.ISO, day: 23, hour: 21, microsecond: {123000, 3}, minute: 20, month: 1, second: 7, std_offset: 0,
                time_zone: "Etc/UTC", utc_offset: 0, year: 2015, zone_abbr: "UTC"}, 9000}

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, DateTime.t()}

Converts the given NaiveDateTime to DateTime.

It expects a time zone to put the NaiveDateTime in. Currently it only supports “Etc/UTC” as time zone.

Examples

iex> DateTime.from_naive(~N[2016-05-24 13:26:08.003], "Etc/UTC")
{:ok, %DateTime{calendar: Calendar.ISO, day: 24, hour: 13, microsecond: {3000, 3}, minute: 26,
                month: 5, second: 8, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0,
                year: 2016, zone_abbr: "UTC"}}

from_naive!(naive_datetime, time_zone)

from_naive!(non_neg_integer(), :native | System.time_unit()) :: DateTime.t()

Converts the given NaiveDateTime to DateTime.

It expects a time zone to put the NaiveDateTime in. Currently it only supports “Etc/UTC” as time zone.

Examples

iex> DateTime.from_naive!(~N[2016-05-24 13:26:08.003], "Etc/UTC")
%DateTime{calendar: Calendar.ISO, day: 24, hour: 13, microsecond: {3000, 3}, minute: 26,
          month: 5, second: 8, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0,
          year: 2016, zone_abbr: "UTC"}

from_unix(integer, unit \\ :second)

from_unix(integer(), :native | System.time_unit()) ::
  {:ok, DateTime.t()} |
  {:error, atom()}

Converts the given Unix time to DateTime.

The integer can be given in different unit according to System.convert_time_unit/3 and it will be converted to microseconds internally.

Unix times are always in UTC and therefore the DateTime will be returned in UTC.

Examples

iex> DateTime.from_unix(1464096368)
{:ok, %DateTime{calendar: Calendar.ISO, day: 24, hour: 13, microsecond: {0, 0}, minute: 26,
                month: 5, second: 8, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0,
                year: 2016, zone_abbr: "UTC"}}

iex> DateTime.from_unix(1432560368868569, :microsecond)
{:ok, %DateTime{calendar: Calendar.ISO, day: 25, hour: 13, microsecond: {868569, 6}, minute: 26,
                month: 5, second: 8, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0,
                year: 2015, zone_abbr: "UTC"}}

The unit can also be an integer as in System.time_unit/0:

iex> DateTime.from_unix(1432560368868569, 1024)
{:ok, %DateTime{calendar: Calendar.ISO, day: 23, hour: 22, microsecond: {211914, 3}, minute: 53,
                month: 1, second: 43, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0,
                year: 46302, zone_abbr: "UTC"}}

Negative Unix times are supported, up to -62167219200 seconds, which is equivalent to “0000-01-01T00:00:00Z” or 0 gregorian seconds.

iex> DateTime.from_unix(-12345678910)
{:ok, %DateTime{calendar: Calendar.ISO, day: 13, hour: 4, microsecond: {0, 0}, minute: 44,
                month: 10, second: 50, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0,
                year: 1578, zone_abbr: "UTC"}}

When a Unix time before that moment is passed to from_unix/2, :error will be returned.

from_unix!(integer, unit \\ :second)

from_unix!(non_neg_integer(), :native | System.time_unit()) :: DateTime.t()

Converts the given Unix time to DateTime.

The integer can be given in different unit according to System.convert_time_unit/3 and it will be converted to microseconds internally.

Unix times are always in UTC and therefore the DateTime will be returned in UTC.

Examples

iex> DateTime.from_unix!(1464096368)
%DateTime{calendar: Calendar.ISO, day: 24, hour: 13, microsecond: {0, 0}, minute: 26,
          month: 5, second: 8, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0,
          year: 2016, zone_abbr: "UTC"}

iex> DateTime.from_unix!(1432560368868569, :microsecond)
%DateTime{calendar: Calendar.ISO, day: 25, hour: 13, microsecond: {868569, 6}, minute: 26,
          month: 5, second: 8, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0,
          year: 2015, zone_abbr: "UTC"}

Negative Unix times are supported, up to -62167219200 seconds, which is equivalent to “0000-01-01T00:00:00Z” or 0 gregorian seconds.

iex> DateTime.from_unix(-12345678910)
{:ok, %DateTime{calendar: Calendar.ISO, day: 13, hour: 4, microsecond: {0, 0}, minute: 44,
                month: 10, second: 50, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0,
                year: 1578, zone_abbr: "UTC"}}

When a Unix time before that moment is passed to from_unix!/2, an ArgumentError will be raised.

to_date(date_time)

Converts a DateTime into a Date.

Because Date does not hold time nor time zone information, data will be lost during the conversion.

Examples

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(map)

to_iso8601(DateTime.t()) :: String.t()

Converts the given datetime to ISO 8601:2004 format.

Only supports converting datetimes which are in the ISO calendar, attempting to convert datetimes from other calendars will raise.

WARNING: the ISO 8601 datetime format does not contain the time zone nor its abbreviation, which means information is lost when converting to such format.

Examples

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)
"2000-02-29T23:00:07-04:00"

to_naive(date_time)

Converts a DateTime into a NaiveDateTime.

Because NaiveDateTime does not hold time zone information, any time zone related data will be lost during the conversion.

Examples

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(map)

to_string(DateTime.t()) :: String.t()

Converts the given datetime to a string according to its calendar.

Examples

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(date_time)

Converts a DateTime into Time.

Because Time does not hold date nor time zone information, data will be lost during the conversion.

Examples

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(DateTime.t(), System.time_unit()) :: non_neg_integer()

Converts the given DateTime to Unix time.

The DateTime is expected to be using the ISO calendar with a year greater than or equal to 0.

It will return the integer with the given unit, according to System.convert_time_unit/3.

Examples

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

utc_now()

utc_now() :: DateTime.t()

Returns the current datetime in UTC.

Examples

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.4.5/DateTime.html