Time View Source
A Time struct and functions.
The Time struct contains the fields hour, minute, second and microseconds.
New times can be built with the new/4
function or using the
~T
(see Kernel.sigil_T/2
) sigil:
iex> ~T[23:00:07.001]
~T[23:00:07.001]
Both new/4
and sigil return a struct where the time fields can
be accessed directly:
iex> time = ~T[23:00:07.001]
iex> time.hour
23
iex> time.microsecond
{1000, 3}
The functions on this module work with the Time
struct as well
as any struct that contains the same fields as the Time
struct,
such as NaiveDateTime
and DateTime
. Such functions expect
Calendar.time/0
in their typespecs (instead of t/0
).
Developers should avoid creating the Time structs directly and instead rely on the functions provided by this module as well as the ones in third-party calendar libraries.
Comparing times
Comparisons in Elixir using ==/2
, >/2
, </2
and similar are structural
and based on the Time
struct fields. For proper comparison between
times, use the compare/2
function.
Link to this section Summary
Functions
Adds the number
of unit
s to the given time
Compares two time structs
Converts given time
to a different calendar
Similar to Time.convert/2
, but raises an ArgumentError
if the conversion between the two calendars is not possible
Returns the difference between two times, considering only the hour, minute, second and microsecond
Converts an Erlang time tuple to a Time
struct
Converts an Erlang time tuple to a Time
struct
Parses the extended "Local time" format described by ISO 8601:2004
Parses the extended "Local time" format described by ISO 8601:2004
Converts given time
to an Erlang time tuple
Converts the given time to ISO 8601:2004
Converts the given time
to a string
Returns the given time with the microsecond field truncated to the given
precision (:microsecond
, millisecond
or :second
)
Returns the current time in UTC
Link to this section Types
t()
View Source
t() :: %Time{
calendar: Calendar.calendar(),
hour: Calendar.hour(),
microsecond: Calendar.microsecond(),
minute: Calendar.minute(),
second: Calendar.second()
}
t() :: %Time{ calendar: Calendar.calendar(), hour: Calendar.hour(), microsecond: Calendar.microsecond(), minute: Calendar.minute(), second: Calendar.second() }
Link to this section Functions
add(time, number, unit \\ :second)
View Source
(since 1.6.0)
add(Calendar.time(), integer(), System.time_unit()) :: t()
add(Calendar.time(), integer(), System.time_unit()) :: t()
Adds the number
of unit
s to the given time
.
This function accepts the number
measured according to Calendar.ISO
.
The time is returned in the same calendar as it was given in.
Note the result value represents the time of day, meaning that it is cyclic, for instance, it will never go over 24 hours for the ISO calendar.
Examples
iex> Time.add(~T[10:00:00], 27000)
~T[17:30:00.000000]
iex> Time.add(~T[11:00:00.005], 2400)
~T[11:40:00.005000]
iex> Time.add(~T[00:00:00], 86_399_999, :millisecond)
~T[23:59:59.999000]
iex> Time.add(~T[17:10:05], 86400)
~T[17:10:05.000000]
iex> Time.add(~T[23:00:00], -60)
~T[22:59:00.000000]
compare(time1, time2)
View Source
(since 1.4.0)
compare(Calendar.time(), Calendar.time()) :: :lt | :eq | :gt
compare(Calendar.time(), Calendar.time()) :: :lt | :eq | :gt
Compares two time structs.
Returns :gt
if first time is later than the second
and :lt
for vice versa. If the two times are equal
:eq
is returned.
Examples
iex> Time.compare(~T[16:04:16], ~T[16:04:28])
:lt
iex> Time.compare(~T[16:04:16], ~T[16:04:16])
:eq
iex> Time.compare(~T[16:04:16.01], ~T[16:04:16.001])
:gt
This function can also be used to compare across more complex calendar types by considering only the time fields:
iex> Time.compare(~N[1900-01-01 16:04:16], ~N[2015-01-01 16:04:16])
:eq
iex> Time.compare(~N[2015-01-01 16:04:16], ~N[2015-01-01 16:04:28])
:lt
iex> Time.compare(~N[2015-01-01 16:04:16.01], ~N[2000-01-01 16:04:16.001])
:gt
convert(time, calendar)
View Source
(since 1.5.0)
convert(Calendar.time(), Calendar.calendar()) ::
{:ok, t()} | {:error, atom()}
convert(Calendar.time(), Calendar.calendar()) :: {:ok, t()} | {:error, atom()}
Converts given time
to a different calendar.
Returns {:ok, time}
if the conversion was successful,
or {:error, reason}
if it was not, for some reason.
Examples
Imagine someone implements Calendar.Holocene
, a calendar based on the
Gregorian calendar that adds exactly 10,000 years to the current Gregorian
year:
iex> Time.convert(~T[13:30:15], Calendar.Holocene)
{:ok, %Time{calendar: Calendar.Holocene, hour: 13, minute: 30, second: 15, microsecond: {0, 0}}}
convert!(time, calendar)
View Source
(since 1.5.0)
convert!(Calendar.time(), Calendar.calendar()) :: t()
convert!(Calendar.time(), Calendar.calendar()) :: t()
Similar to Time.convert/2
, but raises an ArgumentError
if the conversion between the two calendars is not possible.
Examples
Imagine someone implements Calendar.Holocene
, a calendar based on the
Gregorian calendar that adds exactly 10,000 years to the current Gregorian
year:
iex> Time.convert!(~T[13:30:15], Calendar.Holocene)
%Time{calendar: Calendar.Holocene, hour: 13, minute: 30, second: 15, microsecond: {0, 0}}
diff(time1, time2, unit \\ :second)
View Source
(since 1.5.0)
diff(Calendar.time(), Calendar.time(), System.time_unit()) :: integer()
diff(Calendar.time(), Calendar.time(), System.time_unit()) :: integer()
Returns the difference between two times, considering only the hour, minute, second and microsecond.
As with the compare/2
function both Time
structs and other structures
containing time can be used. If for instance a NaiveDateTime
or DateTime
is passed, only the hour, month, second, and microsecond is considered. Any
additional information about a date or time zone is ignored when calculating
the difference.
The answer can be returned in any unit
available from
System.time_unit/0
. If the first unit is smaller than
the second, a negative number is returned.
This function returns the difference in seconds where seconds
are measured according to Calendar.ISO
.
Examples
iex> Time.diff(~T[00:29:12], ~T[00:29:10])
2
# When passing a [`NaiveDateTime`](NaiveDateTime.html) the date part is ignored.
iex> Time.diff(~N[2017-01-01 00:29:12], ~T[00:29:10])
2
# Two [`NaiveDateTime`](NaiveDateTime.html) structs could have big differences in the date
# but only the time part is considered.
iex> Time.diff(~N[2017-01-01 00:29:12], ~N[1900-02-03 00:29:10])
2
iex> Time.diff(~T[00:29:12], ~T[00:29:10], :microsecond)
2_000_000
iex> Time.diff(~T[00:29:10], ~T[00:29:12], :microsecond)
-2_000_000
from_erl(tuple, microsecond \\ {0, 0}, calendar \\ Calendar.ISO)
View Source
from_erl(:calendar.time(), Calendar.microsecond(), Calendar.calendar()) ::
{:ok, t()} | {:error, atom()}
from_erl(:calendar.time(), Calendar.microsecond(), Calendar.calendar()) :: {:ok, t()} | {:error, atom()}
Converts an Erlang time tuple to a Time
struct.
Examples
iex> Time.from_erl({23, 30, 15}, {5000, 3})
{:ok, ~T[23:30:15.005]}
iex> Time.from_erl({24, 30, 15})
{:error, :invalid_time}
from_erl!(tuple, microsecond \\ {0, 0}, calendar \\ Calendar.ISO)
View Source
from_erl!(:calendar.time(), Calendar.microsecond(), Calendar.calendar()) ::
t()
from_erl!(:calendar.time(), Calendar.microsecond(), Calendar.calendar()) :: t()
Converts an Erlang time tuple to a Time
struct.
Examples
iex> Time.from_erl!({23, 30, 15})
~T[23:30:15]
iex> Time.from_erl!({23, 30, 15}, {5000, 3})
~T[23:30:15.005]
iex> Time.from_erl!({24, 30, 15})
** (ArgumentError) cannot convert {24, 30, 15} to time, reason: :invalid_time
from_iso8601(string, calendar \\ Calendar.ISO)
View Source
from_iso8601(String.t(), Calendar.calendar()) ::
{:ok, t()} | {:error, atom()}
from_iso8601(String.t(), Calendar.calendar()) :: {:ok, t()} | {:error, atom()}
Parses the extended "Local time" format described by ISO 8601:2004.
Time zone offset may be included in the string but they will be simply discarded as such information is not included in times.
As specified in the standard, the separator "T" may be omitted if desired as there is no ambiguity within this function.
Time representations with reduced accuracy are not supported.
Note that while ISO 8601 allows times to specify 24:00:00 as the zero hour of the next day, this notation is not supported by Elixir. Leap seconds are not supported as well by the built-in Calendar.ISO.
Examples
iex> Time.from_iso8601("23:50:07")
{:ok, ~T[23:50:07]}
iex> Time.from_iso8601("23:50:07Z")
{:ok, ~T[23:50:07]}
iex> Time.from_iso8601("T23:50:07Z")
{:ok, ~T[23:50:07]}
iex> Time.from_iso8601("23:50:07,0123456")
{:ok, ~T[23:50:07.012345]}
iex> Time.from_iso8601("23:50:07.0123456")
{:ok, ~T[23:50:07.012345]}
iex> Time.from_iso8601("23:50:07.123Z")
{:ok, ~T[23:50:07.123]}
iex> Time.from_iso8601("2015:01:23 23-50-07")
{:error, :invalid_format}
iex> Time.from_iso8601("23:50:07A")
{:error, :invalid_format}
iex> Time.from_iso8601("23:50:07.")
{:error, :invalid_format}
iex> Time.from_iso8601("23:50:61")
{:error, :invalid_time}
from_iso8601!(string, calendar \\ Calendar.ISO)
View Source
from_iso8601!(String.t(), Calendar.calendar()) :: t()
from_iso8601!(String.t(), Calendar.calendar()) :: t()
Parses the extended "Local time" format described by ISO 8601:2004.
Raises if the format is invalid.
Examples
iex> Time.from_iso8601!("23:50:07,123Z")
~T[23:50:07.123]
iex> Time.from_iso8601!("23:50:07.123Z")
~T[23:50:07.123]
iex> Time.from_iso8601!("2015:01:23 23-50-07")
** (ArgumentError) cannot parse "2015:01:23 23-50-07" as time, reason: :invalid_format
new(hour, minute, second, microsecond \\ {0, 0}, calendar \\ Calendar.ISO)
View Source
new(
Calendar.hour(),
Calendar.minute(),
Calendar.second(),
Calendar.microsecond() | integer(),
Calendar.calendar()
) :: {:ok, t()} | {:error, atom()}
new( Calendar.hour(), Calendar.minute(), Calendar.second(), Calendar.microsecond() | integer(), Calendar.calendar() ) :: {:ok, t()} | {:error, atom()}
Builds a new time.
Expects all values to be integers. Returns {:ok, time}
if each
entry fits its appropriate range, returns {:error, reason}
otherwise.
Microseconds can also be given with a precision, which must be an integer between 0 and 6.
The built-in calendar does not support leap seconds.
Examples
iex> Time.new(0, 0, 0, 0)
{:ok, ~T[00:00:00.000000]}
iex> Time.new(23, 59, 59, 999_999)
{:ok, ~T[23:59:59.999999]}
iex> Time.new(24, 59, 59, 999_999)
{:error, :invalid_time}
iex> Time.new(23, 60, 59, 999_999)
{:error, :invalid_time}
iex> Time.new(23, 59, 60, 999_999)
{:error, :invalid_time}
iex> Time.new(23, 59, 59, 1_000_000)
{:error, :invalid_time}
# Invalid precision
Time.new(23, 59, 59, {999_999, 10})
{:error, :invalid_time}
to_erl(time)
View Source
to_erl(Calendar.time()) :: :calendar.time()
to_erl(Calendar.time()) :: :calendar.time()
Converts given time
to an Erlang time tuple.
WARNING: Loss of precision may occur, as Erlang time tuples only contain hours/minutes/seconds.
Examples
iex> Time.to_erl(~T[23:30:15.999])
{23, 30, 15}
iex> Time.to_erl(~N[2010-04-17 23:30:15.999])
{23, 30, 15}
to_iso8601(time, format \\ :extended)
View Source
to_iso8601(Calendar.time(), :extended | :basic) :: String.t()
to_iso8601(Calendar.time(), :extended | :basic) :: String.t()
Converts the given time to ISO 8601:2004.
By default, Time.to_iso8601/2
returns times formatted in the "extended"
format, for human readability. It also supports the "basic" format through
passing the :basic
option.
Examples
iex> Time.to_iso8601(~T[23:00:13])
"23:00:13"
iex> Time.to_iso8601(~T[23:00:13.001])
"23:00:13.001"
iex> Time.to_iso8601(~T[23:00:13.001], :basic)
"230013.001"
iex> Time.to_iso8601(~N[2010-04-17 23:00:13])
"23:00:13"
to_string(time)
View Source
to_string(Calendar.time()) :: String.t()
to_string(Calendar.time()) :: String.t()
Converts the given time
to a string.
Examples
iex> Time.to_string(~T[23:00:00])
"23:00:00"
iex> Time.to_string(~T[23:00:00.001])
"23:00:00.001"
iex> Time.to_string(~T[23:00:00.123456])
"23:00:00.123456"
iex> Time.to_string(~N[2015-01-01 23:00:00.001])
"23:00:00.001"
iex> Time.to_string(~N[2015-01-01 23:00:00.123456])
"23:00:00.123456"
truncate(time, precision) View Source (since 1.6.0)
Returns the given time with the microsecond field truncated to the given
precision (:microsecond
, millisecond
or :second
).
The given time is returned unchanged if it already has lower precision than the given precision.
Examples
iex> Time.truncate(~T[01:01:01.123456], :microsecond)
~T[01:01:01.123456]
iex> Time.truncate(~T[01:01:01.123456], :millisecond)
~T[01:01:01.123]
iex> Time.truncate(~T[01:01:01.123456], :second)
~T[01:01:01]
utc_now(calendar \\ Calendar.ISO)
View Source
(since 1.4.0)
utc_now(Calendar.calendar()) :: t()
utc_now(Calendar.calendar()) :: t()
Returns the current time in UTC.
Examples
iex> time = Time.utc_now()
iex> time.hour >= 0
true