Tox.DateTime (tox v0.2.3)
A set of functions to work with DateTime
.
All examples are using
TimeZoneInfo.TimeZoneDatabase
. But everything also works with any other time zone DB as long as the time
zones are available in the DB.
Link to this section Summary
Functions
Returns true if datetime1
occurs after datetime2
.
Returns true if datetime1
occurs after datetime2
or both datetimes are
equal.
Returns true if datetime1
occurs before datetime2
.
Returns true if datetime1
occurs before datetime2
or both datetimes are equal.
Returns a datetime representing the start of the day.
Returns datetime representing the start of the month.
Returns a datetime representing the start of the week.
Returns datetime representing the start of the year.
Returns a boolean indicating whether datetime
occurs between from
and to
.
The optional boundaries
specifies whether from
and to
are included or
not. The possible value for boundaries
are
Returns datetime representing the end of the day.
Returns a datetime} representing the end of the month.
Returns a datetime representing the end of the week.
Returns a datetime representing the end of the year.
Returns true if both datetimes are equal.
Shifts the datetime
by the given duration
.
Returns an {year, week}
representing the ISO week number for the specified
date.
Link to this section Functions
Returns true if datetime1
occurs after datetime2
.
Examples
iex> Tox.DateTime.after?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.999999Z], "Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000001Z], "Etc/UTC")
...> )
true
iex> Tox.DateTime.after?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43Z], "Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43Z], "Etc/UTC")
...> )
false
iex> Tox.DateTime.after?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000001Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.999999Z],"Etc/UTC")
...> )
false
# with time zone Europe/London (UTC+1) and Europe/Berlin (UTC+2)
iex> Tox.DateTime.after?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000999], "Europe/Berlin"),
...> DateTime.from_naive!(~N[2020-06-14 14:01:43.000001], "Europe/London")
...> )
true
Returns true if datetime1
occurs after datetime2
or both datetimes are
equal.
Examples
iex> Tox.DateTime.after_or_equal?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.999999Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000001Z],"Etc/UTC")
...> )
true
iex> Tox.DateTime.after_or_equal?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43Z],"Etc/UTC" )
...> )
true
iex> Tox.DateTime.after_or_equal?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000001Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.999999Z],"Etc/UTC")
...> )
false
# with time zone Europe/London (UTC+1) and Europe/Berlin (UTC+2)
iex> Tox.DateTime.after_or_equal?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000999], "Europe/Berlin"),
...> DateTime.from_naive!(~N[2020-06-14 14:01:43.000001], "Europe/London")
...> )
true
Returns true if datetime1
occurs before datetime2
.
Examples
iex> Tox.DateTime.before?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000001Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.999999Z],"Etc/UTC")
...> )
true
iex> Tox.DateTime.before?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43Z],"Etc/UTC")
...> )
false
iex> Tox.DateTime.before?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.999999Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000001Z],"Etc/UTC")
...> )
false
# with time zone Europe/London (UTC+1) and Europe/Berlin (UTC+2)
iex> Tox.DateTime.before?(
...> DateTime.from_naive!(~N[2020-06-14 14:01:43.000001], "Europe/London"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000999], "Europe/Berlin")
...> )
true
Returns true if datetime1
occurs before datetime2
or both datetimes are equal.
Examples
iex> Tox.DateTime.before_or_equal?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000001Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.999999Z],"Etc/UTC")
...> )
true
iex> Tox.DateTime.before_or_equal?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43Z],"Etc/UTC")
...> )
true
iex> Tox.DateTime.before_or_equal?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.999999Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000001Z],"Etc/UTC")
...> )
false
# with time zone Europe/London (UTC+1) and Europe/Berlin (UTC+2)
iex> Tox.DateTime.before_or_equal?(
...> DateTime.from_naive!(~N[2020-06-14 14:01:43.000000], "Europe/London"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.999999], "Europe/Berlin")
...> )
true
beginning_of_day(map, time_zone_database \\ Calendar.get_time_zone_database())
Specs
beginning_of_day(Calendar.datetime(), Calendar.time_zone_database()) :: DateTime.t()
Returns a datetime representing the start of the day.
Examples
iex> ~N[2020-03-29 12:00:00]
...> |> DateTime.from_naive!("Europe/Berlin")
...> |> Tox.DateTime.beginning_of_day()
#DateTime<2020-03-29 00:00:00+01:00 CET Europe/Berlin>
On a day starting with a gap
iex> ~N[2011-04-03 12:00:00]
iex> |> DateTime.from_naive!("Africa/El_Aaiun")
iex> |> Tox.DateTime.beginning_of_day()
#DateTime<2011-04-03 01:00:00+01:00 +01 Africa/El_Aaiun>
On a day starting with an ambiguous period
iex> datetime = DateTime.from_naive!(~N[2020-10-25 12:00:00], "America/Scoresbysund")
#DateTime<2020-10-25 12:00:00-01:00 -01 America/Scoresbysund>
iex> Tox.DateTime.beginning_of_day(datetime)
#DateTime<2020-10-25 00:00:00+00:00 +00 America/Scoresbysund>
beginning_of_month(datetime, time_zone_database \\ Calendar.get_time_zone_database())
Specs
beginning_of_month(Calendar.datetime(), Calendar.time_zone_database()) :: DateTime.t()
Returns datetime representing the start of the month.
Examples
iex> ~N[2020-11-11 11:11:11]
iex> |> DateTime.from_naive!("Europe/Berlin")
iex> |> Tox.DateTime.beginning_of_month()
#DateTime<2020-11-01 00:00:00+01:00 CET Europe/Berlin>
iex> ~N[1969-01-11 12:00:00]
iex> |> DateTime.from_naive!("Antarctica/Casey")
iex> |> Tox.DateTime.beginning_of_month()
#DateTime<1969-01-01 08:00:00+08:00 +08 Antarctica/Casey>
beginning_of_week(datetime, time_zone_database \\ Calendar.get_time_zone_database())
Specs
beginning_of_week(Calendar.datetime(), Calendar.time_zone_database()) :: DateTime.t()
Returns a datetime representing the start of the week.
Examples
iex> ~N[2020-07-22 11:11:11]
iex> |> DateTime.from_naive!("Europe/Berlin")
iex> |> Tox.DateTime.beginning_of_week()
#DateTime<2020-07-20 00:00:00+02:00 CEST Europe/Berlin>
beginning_of_year(datetime, time_zone_database \\ Calendar.get_time_zone_database())
Specs
beginning_of_year(Calendar.datetime(), Calendar.time_zone_database()) :: DateTime.t()
Returns datetime representing the start of the year.
Examples
iex> ~N[2020-11-11 11:11:11]
iex> |> DateTime.from_naive!("Europe/Berlin")
iex> |> Tox.DateTime.beginning_of_year()
#DateTime<2020-01-01 00:00:00+01:00 CET Europe/Berlin>
iex> ~N[1969-11-11 12:00:00]
iex> |> DateTime.from_naive!("Antarctica/Casey")
iex> |> Tox.DateTime.beginning_of_year()
#DateTime<1969-01-01 08:00:00+08:00 +08 Antarctica/Casey>
between?(datetime, from, to, boundaries \\ :right_open)
Specs
between?( Calendar.datetime(), Calendar.datetime(), Calendar.datetime(), Tox.boundaries() ) :: boolean()
Returns a boolean indicating whether datetime
occurs between from
and to
.
The optional boundaries
specifies whether from
and to
are included or
not. The possible value for boundaries
are:
:open
:from
andto
are excluded:closed
:from
andto
are included:left_open
:from
is excluded andto
is included:right_open
:from
is included andto
is excluded
Examples
iex> from = DateTime.from_naive!(~N[2020-04-05 12:30:00], "Asia/Omsk")
iex> to = DateTime.from_naive!(~N[2020-04-15 12:30:00], "Asia/Omsk")
iex> datetime = DateTime.from_naive!(~N[2020-04-01 12:30:00], "Asia/Omsk")
iex> Tox.DateTime.between?(datetime, from, to)
false
iex> datetime = DateTime.from_naive!(~N[2020-04-11 12:30:00], "Asia/Omsk")
iex> Tox.DateTime.between?(datetime, from, to)
true
iex> datetime = DateTime.from_naive!(~N[2020-04-21 12:30:00], "Asia/Omsk")
iex> Tox.DateTime.between?(datetime, from, to)
false
iex> Tox.DateTime.between?(from, from, to)
true
iex> Tox.DateTime.between?(to, from, to)
false
iex> Tox.DateTime.between?(from, from, to, :open)
false
iex> Tox.DateTime.between?(to, from, to, :open)
false
iex> Tox.DateTime.between?(from, from, to, :closed)
true
iex> Tox.DateTime.between?(to, from, to, :closed)
true
iex> Tox.DateTime.between?(from, from, to, :left_open)
false
iex> Tox.DateTime.between?(to, from, to, :left_open)
true
iex> Tox.DateTime.between?(datetime, to, from)
** (ArgumentError) from is equal or greater as to
end_of_day(datetime, time_zone_database \\ Calendar.get_time_zone_database())
Specs
end_of_day(Calendar.datetime(), Calendar.time_zone_database()) :: DateTime.t()
Returns datetime representing the end of the day.
Examples
iex> ~N[2020-03-29 01:00:00]
...> |> DateTime.from_naive!("Europe/Berlin")
...> |> Tox.DateTime.end_of_day()
#DateTime<2020-03-29 23:59:59.999999+02:00 CEST Europe/Berlin>
On a day ending with a gap.
iex> ~N[1916-06-14 12:00:00]
...> |> DateTime.from_naive!("Africa/Algiers")
...> |> Tox.DateTime.end_of_day()
#DateTime<1916-06-14 22:59:59.999999+00:00 WET Africa/Algiers>
end_of_month(datetime, time_zone_database \\ Calendar.get_time_zone_database())
Specs
end_of_month(Calendar.datetime(), Calendar.time_zone_database()) :: DateTime.t()
Returns a datetime} representing the end of the month.
Examples
iex> ~N[2020-11-11 11:11:11]
...> |> DateTime.from_naive!("Europe/Amsterdam")
...> |> Tox.DateTime.end_of_month()
#DateTime<2020-11-30 23:59:59.999999+01:00 CET Europe/Amsterdam>
end_of_week(datetime, time_zone_database \\ Calendar.get_time_zone_database())
Specs
end_of_week(Calendar.datetime(), Calendar.time_zone_database()) :: DateTime.t()
Returns a datetime representing the end of the week.
Examples
iex> ~N[2020-07-22 11:11:11]
...> |> DateTime.from_naive!("Europe/Berlin")
...> |> Tox.DateTime.end_of_week()
#DateTime<2020-07-26 23:59:59.999999+02:00 CEST Europe/Berlin>
end_of_year(datetime, time_zone_database \\ Calendar.get_time_zone_database())
Specs
end_of_year(Calendar.datetime(), Calendar.time_zone_database()) :: DateTime.t()
Returns a datetime representing the end of the year.
Examples
iex> ~N[2020-03-29 01:00:00]
iex> |> DateTime.from_naive!("Europe/Berlin")
iex> |> Tox.DateTime.end_of_year()
#DateTime<2020-12-31 23:59:59.999999+01:00 CET Europe/Berlin>
With the Ethiopic calendar.
iex> datetime =
...> ~N[2020-10-26 02:30:00]
...> |> DateTime.from_naive!("Africa/Nairobi")
...> |> DateTime.convert!(Cldr.Calendar.Ethiopic)
...>
...> to_string(datetime)
"2013-02-16 02:30:00+03:00 EAT Africa/Nairobi"
iex> datetime |> Tox.DateTime.end_of_year() |> to_string()
"2013-13-05 23:59:59.999999+03:00 EAT Africa/Nairobi"
Returns true if both datetimes are equal.
Examples
iex> Tox.DateTime.equal?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.999999Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000001Z],"Etc/UTC")
...> )
false
iex> Tox.DateTime.equal?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43Z],"Etc/UTC")
...> )
true
iex> Tox.DateTime.equal?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000001Z],"Etc/UTC"),
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.999999Z],"Etc/UTC")
...> )
false
# with time zone Europe/London (UTC+1) and Europe/Berlin (UTC+2)
iex> Tox.DateTime.equal?(
...> DateTime.from_naive!(~N[2020-06-14 15:01:43.000999], "Europe/Berlin"),
...> DateTime.from_naive!(~N[2020-06-14 14:01:43.000999], "Europe/London")
...> )
true
shift(datetime, durations, time_zone_database \\ Calendar.get_time_zone_database())
Specs
shift(Calendar.datetime(), [Tox.duration()], Calendar.time_zone_database()) :: DateTime.t()
Shifts the datetime
by the given duration
.
The durations
is a keyword list of one or more durations of the type
Tox.duration
e.g. [year: 1, day: 5, minute: 500]
. All values will be
shifted from the largest to the smallest unit.
Examples
iex> datetime = DateTime.from_naive!(~N[1980-11-01 00:00:00], "Europe/Oslo")
iex> Tox.DateTime.shift(datetime, year: 2)
#DateTime<1982-11-01 00:00:00+01:00 CET Europe/Oslo>
iex> Tox.DateTime.shift(datetime, year: -2, month: 1, hour: 48)
#DateTime<1978-12-03 00:00:00+01:00 CET Europe/Oslo>
iex> Tox.DateTime.shift(datetime, hour: 10, minute: 10, second: 10)
#DateTime<1980-11-01 10:10:10+01:00 CET Europe/Oslo>
Adding a month at the end of the month can update the day too.
iex> datetime = DateTime.from_naive!(~N[2000-01-31 00:00:00], "Europe/Oslo")
iex> Tox.DateTime.shift(datetime, month: 1)
#DateTime<2000-02-29 00:00:00+01:00 CET Europe/Oslo>
For that reason it is important to know that all values will be shifted from the largest to the smallest unit.
iex> datetime = DateTime.from_naive!(~N[2000-01-30 00:00:00], "Europe/Oslo")
iex> Tox.DateTime.shift(datetime, month: 1, day: 1)
#DateTime<2000-03-01 00:00:00+01:00 CET Europe/Oslo>
iex> datetime |> Tox.DateTime.shift(month: 1) |> Tox.DateTime.shift(day: 1)
#DateTime<2000-03-01 00:00:00+01:00 CET Europe/Oslo>
iex> datetime |> Tox.DateTime.shift(day: 1) |> Tox.DateTime.shift(month: 1)
#DateTime<2000-02-29 00:00:00+01:00 CET Europe/Oslo>
Treatment of time gaps. Usually, a transition to a daily-saving-time causing a time gap. For
example, in the time-zone Europe/Berlin, the clocks are advanced by one hour on the last Sunday
in March at 02:00. Therefore there is a gap between 02:00 and 03:00. The shift/3
function will
adjust this by adding or subtracting the difference from the calculated date.
# adding a day
iex> datetime = DateTime.from_naive!(~N[2020-03-28 02:30:00], "Europe/Berlin")
iex> result = Tox.DateTime.shift(datetime, day: 1)
#DateTime<2020-03-29 03:30:00+02:00 CEST Europe/Berlin>
iex> DateTime.diff(result, datetime) == 24 * 60 * 60
true
iex> Tox.DateTime.shift(result, day: -1)
#DateTime<2020-03-28 03:30:00+01:00 CET Europe/Berlin>
# subtracting a day
iex> datetime = DateTime.from_naive!(~N[2020-03-30 02:30:00], "Europe/Berlin")
iex> result = Tox.DateTime.shift(datetime, day: -1)
#DateTime<2020-03-29 01:30:00+01:00 CET Europe/Berlin>
iex> DateTime.diff(datetime, result) == 24 * 60 * 60
true
iex> Tox.DateTime.shift(result, day: 1)
#DateTime<2020-03-30 01:30:00+02:00 CEST Europe/Berlin>
Treatment of ambiguous times. Usually, a transition from daily-saving-time causing an ambiguous
period. For example, in the time-zone Europe/Berlin, the clocks are set back one hour on the
last Sunday in October. Therefore the period from 02:00 to 03:00 exists twice on this day. The
shift/3
function will adjust this by checking if the original datetime later or earlier.
# adding a day
iex> datetime = DateTime.from_naive!(~N[2020-10-24 02:30:00], "Europe/Berlin")
iex> result = Tox.DateTime.shift(datetime, day: 1)
#DateTime<2020-10-25 02:30:00+02:00 CEST Europe/Berlin>
iex> DateTime.diff(result, datetime) == 24 * 60 * 60
true
# subtracting a day
iex> datetime = DateTime.from_naive!(~N[2020-10-26 02:30:00], "Europe/Berlin")
iex> result = Tox.DateTime.shift(datetime, day: -1)
#DateTime<2020-10-25 02:30:00+01:00 CET Europe/Berlin>
iex> DateTime.diff(datetime, result) == 24 * 60 * 60
true
Using shift/3
with a different calendar.
iex> datetime =
...> ~N[2020-10-26 02:30:00]
...> |> DateTime.from_naive!("Africa/Nairobi")
...> |> DateTime.convert!(Cldr.Calendar.Ethiopic)
...>
...> to_string(datetime)
"2013-02-16 02:30:00+03:00 EAT Africa/Nairobi"
iex> datetime |> Tox.DateTime.shift(month: 13) |> to_string()
"2014-02-16 02:30:00+03:00 EAT Africa/Nairobi"
week(datetime)
Specs
week(Calendar.datetime()) :: {Calendar.year(), non_neg_integer()}
Returns an {year, week}
representing the ISO week number for the specified
date.
This function is just defined for datetimes with Calendar.ISO
.
Example
iex> ~N[2017-01-01 01:00:00]
...> |> DateTime.from_naive!("Europe/Berlin")
...> |> Tox.DateTime.week()
{2016, 52}
iex> ~N[2020-01-01 01:00:00]
...> |> DateTime.from_naive!("Europe/Berlin")
...> |> Tox.DateTime.week()
{2020, 1}
iex> ~N[2019-12-31 01:00:00]
...> |> DateTime.from_naive!("Europe/Berlin")
...> |> Tox.DateTime.week()
{2020, 1}
iex> ~N[2020-06-04 11:12:13]
...> |> DateTime.from_naive!("Etc/UTC")
...> |> DateTime.convert(Cldr.Calendar.Coptic)
...> |> Tox.DateTime.week()
** (FunctionClauseError) no function clause matching in Tox.DateTime.week/1