Kalends.DateTime

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

DateTime can also represent a “naive time”. That is a point in time without a specified time zone.

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

Summary

from_erl!(date_time)

Like from_erl/1 without “!”, but returns the result directly without a tag. Will raise if date is invalid. Only use this if you are sure the date is valid

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)

Takes an Erlang-style date-time tuple. If the datetime is valid it returns a tuple with a tag and a naive DateTime. Naive in this context means that it does not have any timezone data

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)

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)

Takes an Erlang-style date-time tuple. If the datetime is valid it returns a tuple with a tag and a naive DateTime. Naive in this context means that it does not have any timezone data.

Examples

iex from_erl({{2014, 9, 26}, {17, 10, 20}})

{:ok, %Kalends.DateTime{date: 26, hour: 17, min: 10, month: 9, sec: 20, year: 2014, timezone: nil, abbr: nil} }

iex from_erl({{2014, 99, 99}, {17, 10, 20}})

{:error, :invalid_datetime}
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)

Like from_erl/1 without “!”, but returns the result directly without a tag. Will raise if date is invalid. Only use this if you are sure the date is valid.

Examples

iex> from_erl!({{2014, 9, 26}, {17, 10, 20}})
%Kalends.DateTime{date: 26, hour: 17, min: 10, month: 9, sec: 20, year: 2014, timezone: nil, abbr: nil}

iex from_erl!({{2014, 99, 99}, {17, 10, 20}})
# this will throw a MatchError
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}}),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.

Make sure that timezone is valid.

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