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)

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)

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

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

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

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_erl(datetime)

Takes a DateTime struct and returns an erlang style datetime tuple

Functions

from_erl(date_time, timezone)

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, date}, {hour, minute, second}}

Examples

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

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{date: 9, hour: 1, min: 1, month: 3, sec: 1, year: 2014, timezone: "America/Montevideo", abbr: "UYST", utc_off: -10800, std_off: 3600}, %Kalends.DateTime{date: 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 does not exist because of the gap caused by switching to DST.

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

from_erl!(date_time, time_zone)

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{date: 26, hour: 17, min: 10, month: 9, sec: 20, year: 2014, timezone: "America/Montevideo", abbr: "UYT", utc_off: -10800, std_off: 0}
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.

iex> elem(from_erl({{2014,9,26},{17,10,20}}, "UTC"),1) |> gregorian_seconds 63578970620

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.

Usually the list will only have a size of 1. But if for instance there is a shift from DST to winter time taking place, the list will have 2 elements.

Examples

iex > Kalends.DateTime.now "UTC" %Kalends.DateTime{abbr: "UTC", date: 15, hour: 2, min: 39, month: 10, sec: 53, std_off: 0, timezone: "UTC", utc_off: 0, year: 2014} iex > Kalends.DateTime.now "Europe/Copenhagen" %Kalends.DateTime{abbr: "CEST", date: 15, hour: 4, min: 41, month: 10, sec: 1, std_off: 3600, timezone: "Europe/Copenhagen", utc_off: 3600, year: 2014}

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> {:ok, nyc} = from_erl {{2014,10,2},{0,29,10}},"America/New_York"; shift_zone(nyc, "Europe/Copenhagen") {:ok, %Kalends.DateTime{abbr: "CEST", date: 2, hour: 6, min: 29, month: 10, sec: 10, timezone: "Europe/Copenhagen", utc_off: 3600, std_off: 3600, year: 2014}}

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> {:ok, nyc} = from_erl {{2014,10,2},{0,29,10}},"America/New_York"; shift_zone!(nyc, "Europe/Copenhagen") %Kalends.DateTime{abbr: "CEST", date: 2, hour: 6, min: 29, month: 10, sec: 10, timezone: "Europe/Copenhagen", utc_off: 3600, std_off: 3600, year: 2014}

to_erl(datetime)

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

Examples

iex > Kalends.DateTime.now("UTC") |> Kalends.DateTime.to_erl {{2014, 10, 15}, {2, 37, 22}}