Kalends.DateTime

DateTime provides a struct which represents a certain time and date in a certain time zone.

The functions in this module can be used to create and transform DateTime structs.

Summary

from_erl!(date_time, time_zone, microsec \\ nil)

Like from_erl/2 without "!", but returns the result directly without a tag. Will raise if date is ambiguous or invalid! Only use this if you are sure the date is valid. Otherwise use "from_erl" without the "!"

from_erl(date_time, timezone, microsec \\ nil)

Takes an Erlang-style date-time tuple and additionally a timezone name. Returns a tuple with a tag and a DateTime struct

from_naive(ndt, timezone)

Takes an NaiveDateTime and a time zone identifier and returns a DateTime

gregorian_seconds(date_time)

Takes a DateTime and returns an integer of gregorian seconds starting with year 0. This is done via the Erlang calendar module

gregorian_seconds_and_microsec(date_time)
now(timezone)

Takes a timezone name a returns a DateTime with the current time in that timezone. Timezone names must be in the TZ data format

now_utc()

Like DateTime.now("Etc/UTC")

shift_zone!(date_time, timezone)

Like shift_zone without "!", but does not check that the time zone is valid and just returns a DateTime struct instead of a tuple with a tag

shift_zone(date_time, timezone)

Takes a DateTime and the name of a new timezone. Returns a DateTime with the equivalent time in the new timezone

to_date(dt)

Takes a DateTime struct and returns a Date struct representing the date part of the provided DateTime

to_date_and_time(dt)

Returns a tuple with a Date struct and a Time struct

to_erl(datetime)

Takes a DateTime struct and returns an erlang style datetime tuple

to_naive(dt)

Takes a DateTime and returns a NaiveDateTime

to_time(dt)

Takes a DateTime struct and returns a Time struct representing the time part of the provided DateTime

Functions

from_erl(date_time, timezone, microsec \\ nil)

Takes an Erlang-style date-time tuple and additionally a timezone name. Returns a tuple with a tag and a DateTime struct.

The tag can be :ok, :ambiguous or :error. :ok is for an unambigous time. :ambiguous is for a time that could have different UTC offsets and/or standard offsets. Usually when switching from summer to winter time.

An erlang style date-time tuple has the following format: {{year, month, day}, {hour, minute, second}}

Examples

Normal, non-ambigous time

iex> from_erl({{2014, 9, 26}, {17, 10, 20}}, "America/Montevideo")
{:ok, %Kalends.DateTime{day: 26, hour: 17, min: 10, month: 9, sec: 20,
                        year: 2014, timezone: "America/Montevideo",
                        abbr: "UYT",
                        utc_off: -10800, std_off: 0, microsec: nil} }

Switching from summer to wintertime in the fall means an ambigous time.

iex> from_erl({{2014, 3, 9}, {1, 1, 1}}, "America/Montevideo")
{:ambiguous, %Kalends.AmbiguousDateTime{possible_date_times:
  [%Kalends.DateTime{day: 9, hour: 1, min: 1, month: 3, sec: 1,
                     year: 2014, timezone: "America/Montevideo",
                     abbr: "UYST", utc_off: -10800, std_off: 3600},
   %Kalends.DateTime{day: 9, hour: 1, min: 1, month: 3, sec: 1,
                     year: 2014, timezone: "America/Montevideo",
                     abbr: "UYT", utc_off: -10800, std_off: 0},
  ]}
}

iex> from_erl({{2014, 9, 26}, {17, 10, 20}}, "Non-existing timezone")
{:error, :timezone_not_found}

The time between 2:00 and 3:00 in the following example does not exist because of the one hour gap caused by switching to DST.

iex> from_erl({{2014, 3, 30}, {2, 20, 02}}, "Europe/Copenhagen")
{:error, :invalid_datetime_for_timezone}

Time with fractional seconds. This represents the time 17:10:20.987654321

iex> from_erl({{2014, 9, 26}, {17, 10, 20}}, "America/Montevideo", 987654)
{:ok, %Kalends.DateTime{day: 26, hour: 17, min: 10, month: 9, sec: 20,
                        year: 2014, timezone: "America/Montevideo",
                        abbr: "UYT",
                        utc_off: -10800, std_off: 0, microsec: 987654} }
from_erl!(date_time, time_zone, microsec \\ nil)

Like from_erl/2 without "!", but returns the result directly without a tag. Will raise if date is ambiguous or invalid! Only use this if you are sure the date is valid. Otherwise use "from_erl" without the "!".

Example:

iex> from_erl!({{2014, 9, 26}, {17, 10, 20}}, "America/Montevideo")
%Kalends.DateTime{day: 26, hour: 17, min: 10, month: 9, sec: 20, year: 2014, timezone: "America/Montevideo", abbr: "UYT", utc_off: -10800, std_off: 0}
from_naive(ndt, timezone)

Takes an NaiveDateTime and a time zone identifier and returns a DateTime

iex> Kalends.NaiveDateTime.from_erl!({{2014,10,15},{2,37,22}}) |> from_naive "UTC"
{:ok, %Kalends.DateTime{abbr: "UTC", day: 15, microsec: nil, hour: 2, min: 37, month: 10, sec: 22, std_off: 0, timezone: "UTC", utc_off: 0, year: 2014}}
gregorian_seconds(date_time)

Takes a DateTime and returns an integer of gregorian seconds starting with year 0. This is done via the Erlang calendar module.

Examples

iex> from_erl!({{2014,9,26},{17,10,20}}, "UTC") |> gregorian_seconds
63578970620
gregorian_seconds_and_microsec(date_time)
now(timezone)

Takes a timezone name a returns a DateTime with the current time in that timezone. Timezone names must be in the TZ data format.

Examples

iex > DateTime.now "UTC"
%Kalends.DateTime{abbr: "UTC", day: 15, hour: 2,
 min: 39, month: 10, sec: 53, std_off: 0, timezone: "UTC", utc_off: 0,
 year: 2014}

iex > DateTime.now "Europe/Copenhagen"
%Kalends.DateTime{abbr: "CEST", day: 15, hour: 4,
 min: 41, month: 10, sec: 1, std_off: 3600, timezone: "Europe/Copenhagen",
 utc_off: 3600, year: 2014}
now_utc()

Like DateTime.now("Etc/UTC")

shift_zone(date_time, timezone)

Takes a DateTime and the name of a new timezone. Returns a DateTime with the equivalent time in the new timezone.

Example

iex> from_erl!({{2014,10,2},{0,29,10}}, "America/New_York",123456) |> shift_zone("Europe/Copenhagen")
{:ok, %Kalends.DateTime{abbr: "CEST", day: 2, hour: 6, min: 29, month: 10, sec: 10, timezone: "Europe/Copenhagen", utc_off: 3600, std_off: 3600, year: 2014, microsec: 123456}}

iex> {:ok, nyc} = from_erl {{2014,10,2},{0,29,10}},"America/New_York"; shift_zone(nyc, "Invalid timezone")
{:invalid_time_zone, nil}
shift_zone!(date_time, timezone)

Like shift_zone without "!", but does not check that the time zone is valid and just returns a DateTime struct instead of a tuple with a tag.

Example

iex> from_erl!({{2014,10,2},{0,29,10}},"America/New_York") |> shift_zone! "Europe/Copenhagen"
%Kalends.DateTime{abbr: "CEST", day: 2, hour: 6, min: 29, month: 10, sec: 10,
                  timezone: "Europe/Copenhagen", utc_off: 3600, std_off: 3600, year: 2014}
to_date(dt)

Takes a DateTime struct and returns a Date struct representing the date part of the provided DateTime.

iex> from_erl!({{2014,10,15},{2,37,22}}, "UTC") |> Kalends.DateTime.to_date
%Kalends.Date{day: 15, month: 10, year: 2014}
to_date_and_time(dt)

Returns a tuple with a Date struct and a Time struct.

iex> from_erl!({{2014,10,15},{2,37,22}}, "UTC") |> Kalends.DateTime.to_date_and_time
{%Kalends.Date{day: 15, month: 10, year: 2014}, %Kalends.Time{microsec: nil, hour: 2, min: 37, sec: 22}}
to_erl(datetime)

Takes a DateTime struct and returns an erlang style datetime tuple.

Examples

iex> from_erl!({{2014,10,15},{2,37,22}}, "Etc/UTC") |> Kalends.DateTime.to_erl
{{2014, 10, 15}, {2, 37, 22}}
to_naive(dt)

Takes a DateTime and returns a NaiveDateTime

iex> Kalends.DateTime.from_erl!({{2014,10,15},{2,37,22}}, "UTC", 0.55) |> to_naive
%Kalends.NaiveDateTime{day: 15, microsec: 0.55, hour: 2, min: 37, month: 10, sec: 22, year: 2014}
to_time(dt)

Takes a DateTime struct and returns a Time struct representing the time part of the provided DateTime.

iex> from_erl!({{2014,10,15},{2,37,22}}, "UTC") |> Kalends.DateTime.to_time
%Kalends.Time{microsec: nil, hour: 2, min: 37, sec: 22}