The FEEL type time (DMN 1.6, section 10.3.2.3.4): a time of day.
Neither Elixir's Time nor Erlang's calendar types can represent a FEEL time:
seconds need to be a decimal, and the zone has to say whether the time is
floating (no zone), has a fixed offset from UTC, or names an IANA time zone.
A floating time is not interchangeable with a zoned one, so the distinction is
part of the value.
Fields
:hour- 0 to 23.:minute- 0 to 59.:second- aFeel.Value.Number.t/0from 0 up to, but not including, 60.:zone- seezone/0.
Summary
Functions
Builds a time, checking the ranges of its parts.
Parses a time string, as time("...") and @"..." read it: hh:mm:ss, with an
optional fraction of a second and an optional zone (DMN 1.6, section 10.3.4.1; the
forms are those of notes 06, AE-1).
Parses a time string as parse/1 does, and says whether it was the end of the day: the carry is 1
for 24:00:00, which is 00:00:00 of the next day, and 0 for any other time.
The zone that a text names: Z (or z) for UTC, an offset such as +01:00 or -05:30, or the id of a zone of the
database. :error for anything else, and for no zone: :floating is not something a text can name.
Returns the type descriptor of time.
Returns true for a t/0 whose parts are all in range.
Types
@type t() :: %Feel.Value.Time{ hour: 0..23, minute: 0..59, second: Feel.Value.Number.t(), zone: zone() }
@type zone() :: :floating | {:offset, -50400..50400} | {:iana, String.t()}
The time zone of a time.
:floating- no zone: a local time of day at some unspecified place.{:offset, seconds}- a fixed offset from UTC, between -14 and +14 hours. An offset of 0 is a UTC form.{:iana, id}- an IANA time zone, such as"Europe/Paris".
Functions
Builds a time, checking the ranges of its parts.
Returns :error when a part is out of range or the zone is not valid. An IANA
zone has to be one of the time zone database (Feel.Value.Zone, D-54).
iex> {:ok, time} = Feel.Value.Time.new(12, 30, 15, {:offset, 0})
iex> {time.hour, time.minute, Decimal.to_string(time.second), time.zone}
{12, 30, "15", {:offset, 0}}
iex> Feel.Value.Time.new(24, 0, 0)
:error
iex> Feel.Value.Time.new(12, 0, 0, {:iana, "Europe/Atlantis"})
:error
Parses a time string, as time("...") and @"..." read it: hh:mm:ss, with an
optional fraction of a second and an optional zone (DMN 1.6, section 10.3.4.1; the
forms are those of notes 06, AE-1).
The zone is Z (or z) for UTC, an offset such as +01:00 or -05:30, or an IANA
zone id after an @, as in 10:30:00@Europe/Paris. Without a zone the time is
floating. White space around the string is ignored. Returns :error for anything else,
including an offset beyond fourteen hours, a zone id that the database does not have, and a
time without seconds.
24:00:00 is the end of the day, which XML Schema reads as midnight, and so does the TCK: it is
00:00:00, with the zone it has. Nothing else of hour 24 is a time. parse_with_carry/1 says
that the day has ended, which a date and time needs.
iex> {:ok, time} = Feel.Value.Time.parse("23:59:00")
iex> {time.hour, time.minute, Decimal.to_string(time.second), time.zone}
{23, 59, "0", :floating}
iex> {:ok, time} = Feel.Value.Time.parse("11:00:30.5Z")
iex> {Decimal.to_string(time.second), time.zone}
{"30.5", {:offset, 0}}
iex> {:ok, time} = Feel.Value.Time.parse("10:00:00-05:30")
iex> time.zone
{:offset, -19_800}
iex> {:ok, time} = Feel.Value.Time.parse("10:30:00@Europe/Paris")
iex> time.zone
{:iana, "Europe/Paris"}
iex> {:ok, time} = Feel.Value.Time.parse("24:00:00Z")
iex> {time.hour, time.minute, time.zone}
{0, 0, {:offset, 0}}
iex> Feel.Value.Time.parse("24:00:01")
:error
iex> Feel.Value.Time.parse("10:00:00@Europe/Atlantis")
:error
iex> Feel.Value.Time.parse("10:00")
:error
Parses a time string as parse/1 does, and says whether it was the end of the day: the carry is 1
for 24:00:00, which is 00:00:00 of the next day, and 0 for any other time.
iex> {:ok, time, carry} = Feel.Value.Time.parse_with_carry("24:00:00")
iex> {time.hour, carry}
{0, 1}
iex> {:ok, _time, carry} = Feel.Value.Time.parse_with_carry("23:59:59")
iex> carry
0
The zone that a text names: Z (or z) for UTC, an offset such as +01:00 or -05:30, or the id of a zone of the
database. :error for anything else, and for no zone: :floating is not something a text can name.
iex> Feel.Value.Time.parse_zone("Z")
{:ok, {:offset, 0}}
iex> Feel.Value.Time.parse_zone("-05:30")
{:ok, {:offset, -19_800}}
iex> Feel.Value.Time.parse_zone("Europe/Paris")
{:ok, {:iana, "Europe/Paris"}}
iex> Feel.Value.Time.parse_zone("Europe/Atlantis")
:error
@spec type() :: Feel.Type.t()
Returns the type descriptor of time.
Returns true for a t/0 whose parts are all in range.
iex> {:ok, time} = Feel.Value.Time.new(1, 2, 3)
iex> Feel.Value.Time.value?(time)
true
iex> Feel.Value.Time.value?(%Feel.Value.Time{hour: 25, minute: 0, second: Decimal.new(0)})
false