Timex.Date
Module for working with dates.
Functions that produce time intervals use UNIX epoch (or simly Epoch) as the default reference date. Epoch is defined as UTC midnight of January 1, 1970.
Time intervals in this module don't account for leap seconds.
Supported tasks:
- get current date in the desired time zone
- convert dates between time zones and time units
- introspect dates to find out weekday, week number, number of days in a given month, etc.
- parse dates from string
- compare dates
- date arithmetic
Summary↑
add(date, arg2) | Add time to a date using a timestamp, i.e. {megasecs, secs, microsecs} Same as shift(date, Time.to_timestamp(5, :mins), :timestamp) |
century() | Gets the current century |
century(datetime) | Given a date, get the century this date is in |
compare(date, date) | Compare two dates returning one of the following values: |
compare(this, other, granularity) | |
day(date) | Returns the ordinal day number of the date |
day_name(x) | Get the name of the day corresponding to the provided number |
day_shortname(x) | Get the short name of the day corresponding to the provided number |
day_to_num(x) | Get the day of the week corresponding to the given name |
days_in_month(datetime) | Return the number of days in the month which the date falls on |
days_in_month(year, month) | |
diff(this, other, atom3) | Calculate time interval between two dates. If the second date comes after the first one in time, return value will be positive; and negative otherwise. You must specify one of the following units: |
epoch() | The date of Epoch, used as default reference date by this module and also by the Time module |
epoch(atom1) | Time interval since year 0 of Epoch expressed in the specified units |
equal?(this, other) | Determine if two dates represent the same point in time |
from(date) | Construct a date from Erlang's date or datetime value |
from(date, tz) | |
from(value, type, reference \\ :epoch) | Construct a date from a time interval since Epoch or year 0 |
from_iso_day(day, date \\ nil) | Convert an iso ordinal day number to the day it represents in the current year. If no date is provided, a new one will be created, with the time will be set to 0:00:00, in UTC. Otherwise, the date provided will have it's month and day reset to the date represented by the ordinal day |
from_iso_triplet(arg1) | Given an ISO triplet |
is_leap?(year) | Return a boolean indicating whether the given year is a leap year. You may pase a date or a year number |
is_valid?(datetime) | Return a boolean indicating whether the given date is valid |
iso_triplet(datetime) | Return a 3-tuple {year, week number, weekday} for the given date |
iso_week(datetime) | Return a pair {year, week number} (as defined by ISO 8601) that date falls on |
local() | Get current local date |
local(date) | Convert a date to your local timezone |
month_name(x) | Get the name of the month corresponding to the provided number |
month_shortname(x) | Get the short name of the month corresponding to the provided number |
month_to_num(x) | Get the number of the month corresponding to the given name |
normalize(arg1) | Produce a valid date from a possibly invalid one |
now() | Get current date |
now(tz) | Get representation of the current date in seconds or days since Epoch |
set(date, options) | Return a new date with the specified fields replaced by new values |
shift(date, spec) | A single function for adjusting the date using various units: timestamp, seconds, minutes, hours, days, weeks, months, years |
subtract(date, arg2) | Subtract time from a date using a timestamp, i.e. {megasecs, secs, microsecs} Same as shift(date, Time.to_timestamp(5, :mins) |> Time.invert, :timestamp) |
timezone(name, datetime) | Get a TimezoneInfo object for the specified offset or name |
to_days(date, reference \\ :epoch) | Convert the date to an integer number of days since Epoch or year 0 |
to_secs(date, reference \\ :epoch, options \\ [utc: true]) | Convert a date to an integer number of seconds since Epoch or year 0. With |
to_timestamp(date, reference \\ :epoch) | Convert a date to a timestamp value consumable by the Time module |
universal() | Get current the current datetime in UTC |
universal(date) | Convert a date to UTC |
weekday(datetime) | Return weekday number (as defined by ISO 8601) of the specified date |
zero() | The first day of year zero (calendar module's default reference date) |
Types ↑
year :: non_neg_integer
month :: 1 .. 12
day :: 1 .. 31
daynum :: 1 .. 366
weekday :: 1 .. 7
weeknum :: 1 .. 53
num_of_days :: 28 .. 31
hour :: 0 .. 23
minute :: 0 .. 59
second :: 0 .. 59
timestamp :: {megaseconds, seconds, microseconds}
megaseconds :: non_neg_integer
seconds :: non_neg_integer
microseconds :: non_neg_integer
dtz :: {datetime, Timex.TimezoneInfo.t}
iso_triplet :: {year, weeknum, weekday}
Functions
Specs:
- add(Timex.DateTime.t, timestamp) :: Timex.DateTime.t
Add time to a date using a timestamp, i.e. {megasecs, secs, microsecs} Same as shift(date, Time.to_timestamp(5, :mins), :timestamp).
Specs:
- century :: non_neg_integer
Gets the current century
Examples
iex> Elixir.Timex.Date.century
21
Specs:
- century(Timex.DateTime.t) :: non_neg_integer
Given a date, get the century this date is in.
Examples
iex> Elixir.Timex.Date.now |> Elixir.Timex.Date.century
21
Specs:
- compare(Timex.DateTime.t, Timex.DateTime.t | :epoch | :zero | :distant_past | :distant_future) :: -1 | 0 | 1
Compare two dates returning one of the following values:
-1
-- the first date comes before the second one0
-- both arguments represent the same date when coalesced to the same timezone.1
-- the first date comes after the second one
You can optionality specify a granularity of any of
:years :months :weeks :days :hours :mins :secs :timestamp
and the dates will be compared with the cooresponding accuracy. The default granularity is :secs.
Examples
iex> date1 = Elixir.Timex.Date.from({2014, 3, 4})
iex> date2 = Elixir.Timex.Date.from({2015, 3, 4})
iex> Elixir.Timex.Date.compare(date1, date2, :years)
-1
iex> Elixir.Timex.Date.compare(date2, date1, :years)
1
iex> Elixir.Timex.Date.compare(date1, date1)
0
Specs:
- compare(Timex.DateTime.t, Timex.DateTime.t, :years | :months | :weeks | :days | :hours | :mins | :secs | :timestamp) :: -1 | 0 | 1
Specs:
- day(Timex.DateTime.t) :: daynum
Returns the ordinal day number of the date.
Examples
iex> Elixir.Timex.Date.from({{2015,6,26},{0,0,0}}) |> Elixir.Timex.Date.day
177
Specs:
- day_name(weekday) :: binary
Get the name of the day corresponding to the provided number
Examples
iex> Elixir.Timex.Date.day_name(1)
"Monday"
iex> Elixir.Timex.Date.day_name(0)
{:error, "Invalid day num: 0"}
Specs:
- day_shortname(weekday) :: binary
Get the short name of the day corresponding to the provided number
Examples
iex> Elixir.Timex.Date.day_shortname(1)
"Mon"
iex> Elixir.Timex.Date.day_shortname(0)
{:error, "Invalid day num: 0"}
Specs:
- day_to_num(binary | atom) :: integer
Get the day of the week corresponding to the given name.
Examples
iex> Elixir.Timex.Date.day_to_num("Monday")
1
iex> Elixir.Timex.Date.day_to_num("monday")
1
iex> Elixir.Timex.Date.day_to_num("Mon")
1
iex> Elixir.Timex.Date.day_to_num("mon")
1
iex> Elixir.Timex.Date.day_to_num(:mon)
1
Specs:
- days_in_month(Timex.DateTime.t | {year, month}) :: num_of_days
Return the number of days in the month which the date falls on.
Examples
iex> Elixir.Timex.Date.epoch |> Elixir.Timex.Date.days_in_month
31
Specs:
- diff(Timex.DateTime.t, Timex.DateTime.t, :secs | :mins | :hours | :days | :weeks | :months | :years) :: integer
- diff(Timex.DateTime.t, Timex.DateTime.t, :timestamp) :: timestamp
Calculate time interval between two dates. If the second date comes after the first one in time, return value will be positive; and negative otherwise. You must specify one of the following units:
:years :months :weeks :days :hours :mins :secs :timestamp
and the result will be an integer value of those units or a timestamp.
Specs:
- epoch :: Timex.DateTime.t
The date of Epoch, used as default reference date by this module and also by the Time module.
See also zero/0
.
Examples
iex> date = %Timex.DateTime{year: 1970, month: 1, day: 1, timezone: %Timex.TimezoneInfo{}}
iex> Elixir.Timex.Date.epoch === date
true
Specs:
- epoch(:secs | :days) :: integer
- epoch(:timestamp) :: timestamp
Time interval since year 0 of Epoch expressed in the specified units.
Examples
iex> Elixir.Timex.Date.epoch(:timestamp)
{0,0,0}
iex> Elixir.Timex.Date.epoch(:secs)
62167219200
Specs:
- equal?(Timex.DateTime.t, Timex.DateTime.t) :: boolean
Determine if two dates represent the same point in time
Examples
iex> date1 = Elixir.Timex.Date.from({2014, 3, 1})
iex> date2 = Elixir.Timex.Date.from({2014, 3, 1})
iex> Elixir.Timex.Date.equal?(date1, date2)
true
Specs:
- from(datetime | date) :: Timex.DateTime.t
Construct a date from Erlang's date or datetime value.
You may specify the date's time zone as the second argument. If the argument is omitted, UTC time zone is assumed.
When passing {year, month, day} as the first argument, the resulting date will indicate midnight of that day in the specified timezone (UTC by default).
NOTE: When using from
the input value is normalized to prevent invalid dates from being accidentally introduced. Use set
with validate: false
, or create the %DateTime{} by hand if you do not want normalization. ## Examples
> Date.from(:erlang.universaltime) #=> %DateTime{...}
> Date.from(:erlang.localtime) #=> %Datetime{...}
> Date.from(:erlang.localtime, :local) #=> %DateTime{...}
> Date.from({2014,3,16}, "America/Chicago") #=> %DateTime{...}
Specs:
- from(number, :us | :secs | :days) :: Timex.DateTime.t
- from(timestamp, :timestamp) :: Timex.DateTime.t
- from(datetime | date, :utc | :local | Timex.TimezoneInfo.t | binary) :: Timex.DateTime.t
Specs:
- from(number, :us | :secs | :days, :epoch | :zero) :: Timex.DateTime.t
- from(timestamp, :timestamp, :epoch | :zero) :: Timex.DateTime.t
Construct a date from a time interval since Epoch or year 0.
UTC time zone is assumed. This assumption can be modified by setting desired time zone using set/3 after the date is constructed.
Examples
> Date.from(13, :secs)
> Date.from(13, :days, :zero)
> Date.from(Time.now, :timestamp)
Specs:
- from_iso_day(non_neg_integer, Timex.DateTime.t | nil) :: Timex.DateTime.t
Convert an iso ordinal day number to the day it represents in the current year. If no date is provided, a new one will be created, with the time will be set to 0:00:00, in UTC. Otherwise, the date provided will have it's month and day reset to the date represented by the ordinal day.
Examples
# Creating a DateTime from the given day
iex> expected = Elixir.Timex.Date.from({{2015, 6, 29}, {0,0,0}})
iex> (Elixir.Timex.Date.from_iso_day(180) === expected)
true
# Shifting a DateTime to the given day
iex> date = Elixir.Timex.Date.from({{2015,6,26}, {12,0,0}})
iex> expected = Elixir.Timex.Date.from({{2015, 6, 29}, {12,0,0}})
iex> (Elixir.Timex.Date.from_iso_day(180, date) === expected)
true
Specs:
- from_iso_triplet(iso_triplet) :: Timex.DateTime.t
Given an ISO triplet {year, week number, weekday}
, convert it to a DateTime struct.
Examples
iex> expected = Elixir.Timex.Date.from({2014, 1, 28})
iex> Elixir.Timex.Date.from_iso_triplet({2014, 5, 2}) === expected
true
Specs:
- is_leap?(Timex.DateTime.t | year) :: boolean
Return a boolean indicating whether the given year is a leap year. You may pase a date or a year number.
Examples
iex> Elixir.Timex.Date.epoch |> Elixir.Timex.Date.is_leap?
false
iex> Elixir.Timex.Date.is_leap?(2012)
true
Specs:
- is_valid?(dtz | Timex.DateTime.t) :: boolean
Return a boolean indicating whether the given date is valid.
Examples
iex> Elixir.Timex.Date.from({{1,1,1}, {1,1,1}}) |> Elixir.Timex.Date.is_valid?
true
iex> %Timex.DateTime{} |> Elixir.Timex.Date.set([month: 13, validate: false]) |> Elixir.Timex.Date.is_valid?
false
iex> %Timex.DateTime{} |> Elixir.Timex.Date.set(hour: -1) |> Elixir.Timex.Date.is_valid?
false
Specs:
- iso_triplet(Timex.DateTime.t) :: {year, weeknum, weekday}
Return a 3-tuple {year, week number, weekday} for the given date.
Examples
iex> Elixir.Timex.Date.epoch |> Elixir.Timex.Date.iso_triplet
{1970, 1, 4}
Specs:
- iso_week(Timex.DateTime.t) :: {year, weeknum}
Return a pair {year, week number} (as defined by ISO 8601) that date falls on.
Examples
iex> Elixir.Timex.Date.epoch |> Elixir.Timex.Date.iso_week
{1970,1}
Specs:
- local :: Timex.DateTime.t
Get current local date.
See also universal/0
.
Examples
> Elixir.Timex.Date.local
%Timex.DateTime{year: 2013, month: 3, day: 16, hour: 11, minute: 1, second: 12, timezone: %TimezoneInfo{}}
Specs:
- local(date :: Timex.DateTime.t) :: Timex.DateTime.t
Convert a date to your local timezone.
See also universal/1
.
Examples
Date.now |> Date.local
Specs:
- month_name(month) :: binary
Get the name of the month corresponding to the provided number
Examples
iex> Elixir.Timex.Date.month_name(1)
"January"
iex> Elixir.Timex.Date.month_name(0)
{:error, "Invalid month num: 0"}
Specs:
- month_shortname(month) :: binary
Get the short name of the month corresponding to the provided number
Examples
iex> Elixir.Timex.Date.month_name(1)
"January"
iex> Elixir.Timex.Date.month_name(0)
{:error, "Invalid month num: 0"}
Specs:
- month_to_num(binary) :: integer
Get the number of the month corresponding to the given name.
Examples
iex> Elixir.Timex.Date.month_to_num("January")
1
iex> Elixir.Timex.Date.month_to_num("january")
1
iex> Elixir.Timex.Date.month_to_num("Jan")
1
iex> Elixir.Timex.Date.month_to_num("jan")
1
iex> Elixir.Timex.Date.month_to_num(:jan)
1
Specs:
- normalize(datetime | dtz | {date, time, Timex.TimezoneInfo.t}) :: Timex.DateTime.t
Produce a valid date from a possibly invalid one.
All date's components will be clamped to the minimum or maximum valid value.
Examples
iex> expected = Elixir.Timex.Date.from({{1, 12, 31}, {0, 59, 59}}, :local)
iex> date = {{1,12,31},{0,59,59}}
iex> localtz = Timex.Timezone.local(date)
iex> result = {{1,12,31},{0,59,59}, localtz} |> Elixir.Timex.Date.normalize |> Elixir.Timex.Date.local
iex> result === expected
true
Specs:
- now :: Timex.DateTime.t
Get current date.
Examples
> Elixir.Timex.Date.now
%Timex.DateTime{year: 2015, month: 6, day: 26, hour: 23, minute: 56, second: 12}
Specs:
- now(:secs | :days) :: integer
- now(binary) :: Timex.DateTime.t
Get representation of the current date in seconds or days since Epoch.
See convert/2 for converting arbitrary dates to various time units.
Examples
> Elixir.Timex.Date.now(:secs)
1363439013
> Elixir.Timex.Date.now(:days)
15780
Specs:
- set(Timex.DateTime.t, [{atom, term}]) :: Timex.DateTime.t
Return a new date with the specified fields replaced by new values.
Values are automatically validated and clamped to good values by default. If you wish to skip validation, perhaps for performance reasons, pass validate: false
.
Values are applied in order, so if you pass [datetime: dt, date: d]
, the date value from date
will override datetime
's date value.
Examples
iex> now = Elixir.Timex.Date.epoch
iex> Elixir.Timex.Date.set(now, date: {1,1,1})
%Timex.DateTime{year: 1, month: 1, day: 1, hour: 0, minute: 0, second: 0, timezone: %Timex.TimezoneInfo{}, calendar: :gregorian}
iex> Elixir.Timex.Date.set(now, hour: 8)
%Timex.DateTime{year: 1970, month: 1, day: 1, hour: 8, minute: 0, second: 0, timezone: %Timex.TimezoneInfo{}, calendar: :gregorian}
iex> Elixir.Timex.Date.set(now, [date: {2013,3,26}, hour: 30])
%Timex.DateTime{year: 2013, month: 3, day: 26, hour: 23, minute: 0, second: 0, timezone: %Timex.TimezoneInfo{}, calendar: :gregorian}
iex> Elixir.Timex.Date.set(now, [
...> datetime: {{2013,3,26}, {12,30,0}},
...> date: {2014,4,12}
...>])
%Timex.DateTime{year: 2014, month: 4, day: 12, hour: 12, minute: 30, second: 0, timezone: %Timex.TimezoneInfo{}, calendar: :gregorian}
iex> Elixir.Timex.Date.set(now, [minute: 74, validate: false])
%Timex.DateTime{year: 1970, month: 1, day: 1, hour: 0, minute: 74, second: 0, timezone: %Timex.TimezoneInfo{}, calendar: :gregorian}
Specs:
- shift(Timex.DateTime.t, [{atom, term}]) :: Timex.DateTime.t
A single function for adjusting the date using various units: timestamp, seconds, minutes, hours, days, weeks, months, years.
When shifting by timestamps, microseconds are ignored.
If the list contains :month
and at least one other unit, an ArgumentError is raised (due to ambiguity of such shifts). You can still shift by months separately.
If :year
is present, it is applied in the last turn.
The returned date is always valid. If after adding months or years the day exceeds maximum number of days in the resulting month, that month's last day is used.
To prevent day skew, fix up the date after shifting. For example, if you want to land on the last day of the next month, do the following:
shift(date, 1, :month) |> set(:month, 31)
Since set/3
is capping values that are out of range, you will get the correct last day for each month.
Examples
date = from({{2013,3,5}, {23,23,23}})
local(shift(date, secs: 24*3600*365))
#=> {{2014,3,5}, {23,23,23}}
local(shift(date, secs: -24*3600*(365*2 + 1))) # +1 day for leap year 2012
#=> {{2011,3,5}, {23,23,23}}
local(shift(date, [secs: 13, day: -1, week: 2]))
#=> {{2013,3,18}, {23,23,36}}
Specs:
- subtract(Timex.DateTime.t, timestamp) :: Timex.DateTime.t
Subtract time from a date using a timestamp, i.e. {megasecs, secs, microsecs} Same as shift(date, Time.to_timestamp(5, :mins) |> Time.invert, :timestamp).
Specs:
- timezone(:local | :utc | number | binary, Timex.DateTime.t | nil) :: Timex.TimezoneInfo.t
Get a TimezoneInfo object for the specified offset or name.
When offset or name is invalid, exception is raised.
Examples
iex> date = Elixir.Timex.Date.from({2015, 4, 12})
iex> tz = Elixir.Timex.Date.timezone(:utc, date)
iex> tz.full_name
"UTC"
iex> date = Elixir.Timex.Date.from({2015, 4, 12})
iex> tz = Elixir.Timex.Date.timezone("America/Chicago", date)
iex> {tz.full_name, tz.abbreviation}
{"America/Chicago", "CDT"}
iex> date = Elixir.Timex.Date.from({2015, 4, 12})
iex> tz = Elixir.Timex.Date.timezone(+2, date)
iex> {tz.full_name, tz.abbreviation}
{"Etc/GMT-2", "GMT-2"}
Specs:
- to_days(Timex.DateTime.t, :epoch | :zero) :: integer
Convert the date to an integer number of days since Epoch or year 0.
See also diff/2
if you want to specify an arbitray reference date.
Examples
iex> Elixir.Timex.Date.from({1970, 1, 15}) |> Elixir.Timex.Date.to_days
14
Specs:
- to_secs(Timex.DateTime.t, :epoch | :zero, [{:utc, false | true}]) :: integer
Convert a date to an integer number of seconds since Epoch or year 0. With to_secs/3
, you can also specify an option utc: false | true
, which controls whether the DateTime is converted to UTC prior to calculating the number of seconds from the reference date. By default, UTC conversion is enabled.
See also diff/2
if you want to specify an arbitrary reference date.
Examples
iex> Elixir.Timex.Date.from({{1999, 1, 2}, {12,13,14}}) |> Elixir.Timex.Date.to_secs
915279194
Specs:
- to_timestamp(Timex.DateTime.t, :epoch | :zero) :: timestamp
Convert a date to a timestamp value consumable by the Time module.
See also diff/2
if you want to specify an arbitrary reference date.
Examples
iex> Elixir.Timex.Date.epoch |> Elixir.Timex.Date.to_timestamp
{0,0,0}
Specs:
- universal :: Timex.DateTime.t
Get current the current datetime in UTC.
See also local/0
. Delegates to now/0
, since they are identical in behavior
Examples
> Elixir.Timex.Date.universal
%Timex.DateTime{timezone: %Timex.TimezoneInfo{full_name: "UTC"}}
Specs:
- universal(Timex.DateTime.t) :: Timex.DateTime.t
Convert a date to UTC
See also local/1
.
Examples
> localdate = Date.local
%Timex.DateTime{hour: 5, timezone: %Timex.TimezoneInfo{full_name: "America/Chicago"}}
> localdate |> Date.universal
%Timex.DateTime{hour: 10, timezone: %Timex.TimezoneInfo{full_name: "UTC"}}
Specs:
- weekday(Timex.DateTime.t) :: weekday
Return weekday number (as defined by ISO 8601) of the specified date.
Examples
iex> Elixir.Timex.Date.epoch |> Elixir.Timex.Date.weekday
4 # (i.e. Thursday)
Specs:
- zero :: Timex.DateTime.t
The first day of year zero (calendar module's default reference date).
See also epoch/0
.
Examples
iex> date = %Timex.DateTime{year: 0, month: 1, day: 1, timezone: %Timex.TimezoneInfo{}}
iex> Elixir.Timex.Date.zero === date
true