Current section

Files

Jump to
gtempo src tempo@datetime.erl
Raw

src/tempo@datetime.erl

-module(tempo@datetime).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-define(FILEPATH, "src/tempo/datetime.gleam").
-export([new/3, from_string/1, literal/1, to_string/1, parse/2, parse_any/1, describe_parse_error/1, from_unix_seconds/1, from_unix_milli/1, from_unix_micro/1, from_timestamp/1, from_string_fast/1, to_unix_micro/1, to_timestamp/1, from_dynamic_string/1, from_dynamic_unix_utc/1, from_dynamic_unix_milli_utc/1, from_dynamic_unix_micro_utc/1, get_date/1, get_calendar_date/1, get_time/1, get_calendar_time_of_day/1, get_offset/1, drop_offset/1, drop_time/1, apply_offset/1, to_unix_seconds/1, to_unix_milli/1, to_utc/1, format/2, to_offset/2, to_local_imprecise/1, to_local_time_imprecise/1, to_local_date_imprecise/1, to_timezone/2, get_timezone_name/1, compare/2, is_earlier/2, is_earlier_or_equal/2, is_equal/2, is_later/2, is_later_or_equal/2, difference/2, as_period/2, add/2, subtract/2, time_left_in_day/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Functions to use with the `DateTime` type in Tempo.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" import tempo/datetime\n"
" import snag\n"
"\n"
" pub fn main() {\n"
" datetime.literal(\"2024-12-25T06:00:00+05:00\")\n"
" |> datetime.format(\"ddd @ h:mm A, Z\")\n"
" // -> \"Fri @ 6:00 AM, +05:00\"\n"
"\n"
" datetime.parse(\"06:21:2024 23:17:07.123Z\", \"MM:DD:YYYY HH:mm:ss.SSSZ\")\n"
" |> snag.map_error(datetime.describe_parse_error)\n"
" |> result.map(datetime.to_string)\n"
" // -> Ok(\"2024-06-21T23:17:07.123Z\")\n"
" }\n"
" ```\n"
"\n"
" ```gleam\n"
" import gleam/list\n"
" import tempo/datetime\n"
" import tempo/period\n"
"\n"
" pub fn get_every_friday_between(datetime1, datetime2) {\n"
" period.new(datetime1, datetime2)\n"
" |> period.comprising_dates\n"
" |> list.filter(fn(date) {\n"
" date |> date.to_day_of_week == date.Fri\n"
" })\n"
" // -> [\"2024-06-21\", \"2024-06-28\", \"2024-07-05\"]\n"
" }\n"
" ```\n"
).
-file("src/tempo/datetime.gleam", 67).
?DOC(
" Create a new datetime from a date, time, and offset.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.new(\n"
" date.literal(\"2024-06-13\"),\n"
" time.literal(\"23:04:00.009\"),\n"
" offset.literal(\"+10:00\"),\n"
" )\n"
" // -> datetime.literal(\"2024-06-13T23:04:00.009+10:00\")\n"
" ```\n"
).
-spec new(tempo:date(), tempo:time(), tempo:offset()) -> tempo:date_time().
new(Date, Time, Offset) ->
tempo:datetime(Date, Time, Offset).
-file("src/tempo/datetime.gleam", 157).
-spec split_time_and_offset(binary()) -> {ok, {binary(), binary()}} |
{error, nil}.
split_time_and_offset(Time_with_offset) ->
case gleam@string:slice(Time_with_offset, -1, 1) of
<<"Z"/utf8>> ->
_pipe = {gleam@string:drop_end(Time_with_offset, 1), <<"Z"/utf8>>},
{ok, _pipe};
<<"z"/utf8>> ->
_pipe@1 = {gleam@string:drop_end(Time_with_offset, 1), <<"Z"/utf8>>},
{ok, _pipe@1};
_ ->
case gleam@string:split_once(Time_with_offset, <<"-"/utf8>>) of
{ok, {Time, Offset}} ->
_pipe@2 = {Time, <<"-"/utf8, Offset/binary>>},
{ok, _pipe@2};
_ ->
case gleam@string:split_once(Time_with_offset, <<"+"/utf8>>) of
{ok, {Time@1, Offset@1}} ->
_pipe@3 = {Time@1, <<"+"/utf8, Offset@1/binary>>},
{ok, _pipe@3};
_ ->
{error, nil}
end
end
end.
-file("src/tempo/datetime.gleam", 114).
?DOC(
" Parses a datetime string in the format `YYYY-MM-DDThh:mm:ss.sTZD`,\n"
" `YYYYMMDDThhmmss.sTZD`, `YYYY-MM-DD hh:mm:ss.sTZD`,\n"
" `YYYYMMDD hhmmss.sTZD`, `YYYY-MM-DD`, `YYYY-M-D`, `YYYY/MM/DD`,\n"
" `YYYY/M/D`, `YYYY.MM.DD`, `YYYY.M.D`, `YYYY_MM_DD`, `YYYY_M_D`,\n"
" `YYYY MM DD`, `YYYY M D`, or `YYYYMMDD`.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.from_string(\"20240613T230400.009+00:00\")\n"
" // -> datetime.literal(\"2024-06-13T23:04:00.009Z\")\n"
" ```\n"
).
-spec from_string(binary()) -> {ok, tempo:date_time()} |
{error, tempo@error:date_time_parse_error()}.
from_string(Datetime) ->
Split_dt = begin
_pipe = gleam@string:split_once(Datetime, <<"T"/utf8>>),
_pipe@1 = gleam@result:try_recover(
_pipe,
fun(_) -> gleam@string:split_once(Datetime, <<"t"/utf8>>) end
),
_pipe@2 = gleam@result:try_recover(
_pipe@1,
fun(_) -> gleam@string:split_once(Datetime, <<"_"/utf8>>) end
),
gleam@result:try_recover(
_pipe@2,
fun(_) -> gleam@string:split_once(Datetime, <<" "/utf8>>) end
)
end,
case Split_dt of
{ok, {Date, Time}} ->
gleam@result:'try'(
begin
_pipe@3 = tempo@date:from_string(Date),
gleam@result:map_error(
_pipe@3,
fun(_capture) ->
{date_time_date_parse_error, Datetime, _capture}
end
)
end,
fun(Date@1) ->
gleam@result:'try'(
begin
_pipe@4 = split_time_and_offset(Time),
gleam@result:replace_error(
_pipe@4,
{date_time_invalid_format, Datetime}
)
end,
fun(_use0) ->
{Time@1, Offset} = _use0,
gleam@result:'try'(
begin
_pipe@5 = tempo@time:from_string(Time@1),
gleam@result:map_error(
_pipe@5,
fun(_capture@1) ->
{date_time_time_parse_error,
Datetime,
_capture@1}
end
)
end,
fun(Time@2) ->
gleam@result:map(
begin
_pipe@6 = tempo@offset:from_string(
Offset
),
gleam@result:map_error(
_pipe@6,
fun(_capture@2) ->
{date_time_offset_parse_error,
Datetime,
_capture@2}
end
)
end,
fun(Offset@1) ->
new(Date@1, Time@2, Offset@1)
end
)
end
)
end
)
end
);
_ ->
{error, {date_time_invalid_format, Datetime}}
end.
-file("src/tempo/datetime.gleam", 89).
?DOC(
" Create a new datetime value from a string literal, but will panic if\n"
" the string is invalid. Accepted formats are `YYYY-MM-DDThh:mm:ss.sTZD` or\n"
" `YYYYMMDDThhmmss.sTZD`\n"
"\n"
" Useful for declaring datetime literals that you know are valid within your\n"
" program.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-13T23:04:00.009+10:00\")\n"
" |> datetime.to_string\n"
" // -> \"2024-06-13T23:04:00.009+10:00\"\n"
" ```\n"
).
-spec literal(binary()) -> tempo:date_time().
literal(Datetime) ->
case from_string(Datetime) of
{ok, Datetime@1} ->
Datetime@1;
{error, {date_time_invalid_format, _}} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid datetime literal format"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"tempo/datetime"/utf8>>,
function => <<"literal"/utf8>>,
line => 93});
{error, {date_time_date_parse_error, _, _}} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid date in datetime literal value"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"tempo/datetime"/utf8>>,
function => <<"literal"/utf8>>,
line => 95});
{error, {date_time_time_parse_error, _, _}} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid time in datetime literal value"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"tempo/datetime"/utf8>>,
function => <<"literal"/utf8>>,
line => 97});
{error, _} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid datetime literal"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"tempo/datetime"/utf8>>,
function => <<"literal"/utf8>>,
line => 98})
end.
-file("src/tempo/datetime.gleam", 184).
?DOC(
" Returns a string representation of a datetime value in the ISO 8601\n"
" format with millisecond precision. If a different precision is needed,\n"
" use the `format` function. If serializing to send outside of Gleam and then\n"
" parse back into a datetime value, use the `serialize` function.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.to_string(my_datetime)\n"
" // -> \"2024-06-21T05:22:22.009534Z\"\n"
" ```\n"
).
-spec to_string(tempo:date_time()) -> binary().
to_string(Datetime) ->
tempo:datetime_to_string(Datetime).
-file("src/tempo/datetime.gleam", 221).
?DOC(
" Parses a datetime string in the provided format. Always prefer using\n"
" this over `parse_any`. All parsed formats must have all parts of a\n"
" datetime (date, time, offset). Use the other modules for parsing lesser\n"
" date time values.\n"
"\n"
" Values can be escaped by putting brackets around them, like \"[Hello!] YYYY\".\n"
"\n"
" Available directives: YY (two-digit year), YYYY (four-digit year), M (month),\n"
" MM (two-digit month), MMM (short month name), MMMM (full month name),\n"
" D (day of the month), DD (two-digit day of the month),\n"
" H (hour), HH (two-digit hour), h (12-hour clock hour), hh\n"
" (two-digit 12-hour clock hour), m (minute), mm (two-digit minute),\n"
" s (second), ss (two-digit second), SSS (millisecond), SSSS (microsecond),\n"
" Z (offset from UTC), ZZ (offset from UTC with no \":\"),\n"
" z (short offset from UTC \"-04\", \"Z\"), zz (full offset from UTC as \"-04:00\"\n"
" or \"Z\" if UTC), A (AM/PM), a (am/pm).\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" datetime.parse(\"2024/06/08, 13:42:11, -04:00\", \"YYYY/MM/DD, HH:mm:ss, Z\")\n"
" // -> Ok(datetime.literal(\"2024-06-08T13:42:11-04\"))\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.parse(\"January 13, 2024. 3:42:11Z\", \"MMMM DD, YYYY. H:mm:ssz\")\n"
" // -> Ok(datetime.literal(\"2024-01-13T03:42:11Z\"))\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.parse(\"Hi! 2024 11 13 12 2 am Z\", \"[Hi!] YYYY M D h m a z\")\n"
" // -> Ok(datetime.literal(\"2024-11-13T00:02:00Z\"))\n"
" ```\n"
).
-spec parse(binary(), tempo:date_time_format()) -> {ok, tempo:date_time()} |
{error, tempo@error:date_time_parse_error()}.
parse(Str, Format) ->
Format_str = tempo:get_datetime_format_str(Format),
gleam@result:'try'(
begin
_pipe = tempo:consume_format(Str, Format_str),
gleam@result:map_error(
_pipe,
fun(Field@0) -> {date_time_invalid_format, Field@0} end
)
end,
fun(_use0) ->
{Parts, _} = _use0,
gleam@result:'try'(
begin
_pipe@1 = tempo:find_date(Parts),
gleam@result:map_error(
_pipe@1,
fun(_capture) ->
{date_time_date_parse_error, Str, _capture}
end
)
end,
fun(Date) ->
gleam@result:'try'(
begin
_pipe@2 = tempo:find_time(Parts),
gleam@result:map_error(
_pipe@2,
fun(_capture@1) ->
{date_time_time_parse_error,
Str,
_capture@1}
end
)
end,
fun(Time) ->
gleam@result:'try'(
begin
_pipe@3 = tempo:find_offset(Parts),
gleam@result:map_error(
_pipe@3,
fun(_capture@2) ->
{date_time_offset_parse_error,
Str,
_capture@2}
end
)
end,
fun(Offset) -> {ok, new(Date, Time, Offset)} end
)
end
)
end
)
end
).
-file("src/tempo/datetime.gleam", 265).
?DOC(
" Tries to parse a given date string without a known format. It will not\n"
" parse two digit years and will assume the month always comes before the\n"
" day in a date.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" parse_any.parse_any(\"2024.06.21 01:32 PM -0400\")\n"
" // -> Ok(datetime.literal(\"2024-06-21T13:32:00-04:00\"))\n"
" ```\n"
"\n"
" ```gleam\n"
" parse_any.parse_any(\"2024.06.21 01:32 PM\")\n"
" // -> Error(tempo.ParseMissingOffset)\n"
" ```\n"
).
-spec parse_any(binary()) -> {ok, tempo:date_time()} |
{error, tempo@error:date_time_parse_error()}.
parse_any(Str) ->
case tempo:parse_any(Str) of
{{some, Date}, {some, Time}, {some, Offset}} ->
{ok, new(Date, Time, Offset)};
{_, _, none} ->
{error,
{date_time_invalid_format,
<<"Unable to find offset in "/utf8, Str/binary>>}};
{_, none, _} ->
{error,
{date_time_invalid_format,
<<"Unable to find time in "/utf8, Str/binary>>}};
{none, _, _} ->
{error,
{date_time_invalid_format,
<<"Unable to find date in "/utf8, Str/binary>>}}
end.
-file("src/tempo/datetime.gleam", 289).
?DOC(
" Converts a datetime parse error to a human readable error message.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" datetime.parse(\"13:42:11.314-04:00\", \"YYYY-MM-DDTHH:mm:ss.SSSZ\")\n"
" |> snag.map_error(with: datetime.describe_parse_error)\n"
" // -> snag.error(\"Invalid date format in datetime: 13:42:11.314-04:00\")\n"
).
-spec describe_parse_error(tempo@error:date_time_parse_error()) -> binary().
describe_parse_error(Error) ->
tempo@error:describe_datetime_parse_error(Error).
-file("src/tempo/datetime.gleam", 356).
?DOC(
" Returns the UTC datetime of a unix timestamp.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.from_unix_seconds(1_718_829_191)\n"
" // -> datetime.literal(\"2024-06-17T12:59:51Z\")\n"
" ```\n"
).
-spec from_unix_seconds(integer()) -> tempo:date_time().
from_unix_seconds(Unix_ts) ->
new(
tempo@date:from_unix_seconds(Unix_ts),
tempo@time:from_unix_seconds(Unix_ts),
{offset, 0}
).
-file("src/tempo/datetime.gleam", 391).
?DOC(
" Returns the UTC datetime of a unix timestamp in milliseconds.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.from_unix_milli(1_718_629_314_334)\n"
" // -> datetime.literal(\"2024-06-17T13:01:54.334Z\")\n"
" ```\n"
).
-spec from_unix_milli(integer()) -> tempo:date_time().
from_unix_milli(Unix_ts) ->
new(
tempo@date:from_unix_milli(Unix_ts),
tempo@time:from_unix_milli(Unix_ts),
{offset, 0}
).
-file("src/tempo/datetime.gleam", 421).
?DOC(
" Returns the UTC datetime of a unix timestamp in microseconds.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.from_unix_micro(1_718_629_314_334_734)\n"
" // -> datetime.literal(\"2024-06-17T13:01:54.334734Z\")\n"
" ```\n"
).
-spec from_unix_micro(integer()) -> tempo:date_time().
from_unix_micro(Unix_ts) ->
new(
tempo@date:from_unix_micro(Unix_ts),
tempo@time:from_unix_micro(Unix_ts),
{offset, 0}
).
-file("src/tempo/datetime.gleam", 332).
?DOC(" Converts a core gleam time timestamp type to a datetime.\n").
-spec from_timestamp(gleam@time@timestamp:timestamp()) -> tempo:date_time().
from_timestamp(Timestamp) ->
{Seconds, Nanoseconds} = gleam@time@timestamp:to_unix_seconds_and_nanoseconds(
Timestamp
),
from_unix_micro((Seconds * 1000000) + (Nanoseconds div 1000)).
-file("src/tempo/datetime.gleam", 151).
-spec from_string_fast(binary()) -> {ok, tempo:date_time()} |
{error, tempo@error:date_time_parse_error()}.
from_string_fast(Datetime) ->
_pipe = gleam@time@timestamp:parse_rfc3339(Datetime),
_pipe@1 = gleam@result:map(_pipe, fun from_timestamp/1),
gleam@result:replace_error(_pipe@1, {date_time_invalid_format, Datetime}).
-file("src/tempo/datetime.gleam", 434).
?DOC(
" Returns the UTC unix timestamp in microseconds of a datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-17T13:01:54.334734Z\")\n"
" |> datetime.to_unix_micro\n"
" // -> 1_718_629_314_334_734\n"
" ```\n"
).
-spec to_unix_micro(tempo:date_time()) -> integer().
to_unix_micro(Datetime) ->
tempo:datetime_to_unix_micro(Datetime).
-file("src/tempo/datetime.gleam", 340).
?DOC(" Converts a datetime to a core gleam time timestamp type.\n").
-spec to_timestamp(tempo:date_time()) -> gleam@time@timestamp:timestamp().
to_timestamp(Datetime) ->
Unix_us = to_unix_micro(Datetime),
Seconds = Unix_us div 1000000,
Nanoseconds = (Unix_us rem 1000000) * 1000,
gleam@time@timestamp:from_unix_seconds_and_nanoseconds(Seconds, Nanoseconds).
-file("src/tempo/datetime.gleam", 460).
?DOC(
" Checks if a dynamic value is a valid datetime string, and returns the\n"
" datetime if it is.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" dynamic.string(\"2024-06-13T13:42:11.195Z\")\n"
" |> datetime.from_dynamic_string\n"
" // -> Ok(datetime.literal(\"2024-06-13T13:42:11.195Z\"))\n"
" ```\n"
"\n"
" ```gleam\n"
" dynamic.string(\"24-06-13,13:42:11.195\")\n"
" |> datetime.from_dynamic_string\n"
" // -> Error([\n"
" // decode.DecodeError(\n"
" // expected: \"tempo.DateTime\",\n"
" // found: \"Invalid format: 24-06-13,13:42:11.195\",\n"
" // path: [],\n"
" // ),\n"
" // ])\n"
" ```\n"
).
-spec from_dynamic_string(gleam@dynamic:dynamic_()) -> {ok, tempo:date_time()} |
{error, list(gleam@dynamic@decode:decode_error())}.
from_dynamic_string(Dynamic_string) ->
gleam@result:'try'(
begin
_pipe = gleam@dynamic@decode:run(
Dynamic_string,
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
gleam@result:map_error(
_pipe,
fun(Errs) ->
gleam@list:map(
Errs,
fun(Err) ->
{decode_error,
erlang:element(2, Err),
erlang:element(3, Err),
erlang:element(4, Err)}
end
)
end
)
end,
fun(Datetime) -> case from_string(Datetime) of
{ok, Datetime@1} ->
{ok, Datetime@1};
{error, Tempo_error} ->
{error,
[{decode_error,
<<"tempo.DateTime"/utf8>>,
case Tempo_error of
{date_time_invalid_format, Msg} ->
Msg;
{date_time_time_parse_error, Msg@1, _} ->
Msg@1;
{date_time_date_parse_error, Msg@2, _} ->
Msg@2;
{date_time_offset_parse_error, Msg@3, _} ->
Msg@3
end,
[]}]}
end end
).
-file("src/tempo/datetime.gleam", 514).
?DOC(
" Checks if a dynamic value is a valid unix timestamp in seconds, and\n"
" returns the datetime representation if it is.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" dynamic.int(1_718_629_314)\n"
" |> datetime.from_dynamic_unix_utc\n"
" // -> Ok(datetime.literal(\"2024-06-17T13:01:54Z\"))\n"
" ```\n"
"\n"
" ```gleam\n"
" dynamic.string(\"hello\")\n"
" |> datetime.from_dynamic_unix_utc\n"
" // -> Error([\n"
" // decode.DecodeError(\n"
" // expected: \"Int\",\n"
" // found: \"String\",\n"
" // path: [],\n"
" // ),\n"
" // ])\n"
" ```\n"
).
-spec from_dynamic_unix_utc(gleam@dynamic:dynamic_()) -> {ok, tempo:date_time()} |
{error, list(gleam@dynamic@decode:decode_error())}.
from_dynamic_unix_utc(Dynamic_ts) ->
gleam@result:map(
begin
_pipe = gleam@dynamic@decode:run(
Dynamic_ts,
{decoder, fun gleam@dynamic@decode:decode_int/1}
),
gleam@result:map_error(
_pipe,
fun(Errs) ->
gleam@list:map(
Errs,
fun(Err) ->
{decode_error,
erlang:element(2, Err),
erlang:element(3, Err),
erlang:element(4, Err)}
end
)
end
)
end,
fun(Unix_seconds) -> from_unix_seconds(Unix_seconds) end
).
-file("src/tempo/datetime.gleam", 553).
?DOC(
" Checks if a dynamic value is a valid unix timestamp in milliseconds, and\n"
" returns the datetime if it is.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" dynamic.int(1_718_629_314_334)\n"
" |> datetime.from_dynamic_unix_milli_utc\n"
" // -> Ok(datetime.literal(\"2024-06-17T13:01:54.334Z\"))\n"
" ```\n"
"\n"
" ```gleam\n"
" dynamic.string(\"hello\")\n"
" |> datetime.from_dynamic_unix_milli_utc\n"
" // -> Error([\n"
" // decode.DecodeError(\n"
" // expected: \"Int\",\n"
" // found: \"String\",\n"
" // path: [],\n"
" // ),\n"
" // ])\n"
" ```\n"
).
-spec from_dynamic_unix_milli_utc(gleam@dynamic:dynamic_()) -> {ok,
tempo:date_time()} |
{error, list(gleam@dynamic@decode:decode_error())}.
from_dynamic_unix_milli_utc(Dynamic_ts) ->
gleam@result:map(
begin
_pipe = gleam@dynamic@decode:run(
Dynamic_ts,
{decoder, fun gleam@dynamic@decode:decode_int/1}
),
gleam@result:map_error(
_pipe,
fun(Errs) ->
gleam@list:map(
Errs,
fun(Err) ->
{decode_error,
erlang:element(2, Err),
erlang:element(3, Err),
erlang:element(4, Err)}
end
)
end
)
end,
fun(Unix_milli) -> from_unix_milli(Unix_milli) end
).
-file("src/tempo/datetime.gleam", 592).
?DOC(
" Checks if a dynamic value is a valid unix timestamp in microseconds, and\n"
" returns the datetime if it is.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" dynamic.int(1_718_629_314_334_734)\n"
" |> datetime.from_dynamic_unix_micro_utc\n"
" // -> Ok(datetime.literal(\"2024-06-17T13:01:54.334734Z\"))\n"
" ```\n"
"\n"
" ```gleam\n"
" dynamic.string(\"hello\")\n"
" |> datetime.from_dynamic_unix_micro_utc\n"
" // -> Error([\n"
" // decode.DecodeError(\n"
" // expected: \"Int\",\n"
" // found: \"String\",\n"
" // path: [],\n"
" // ),\n"
" // ])\n"
" ```\n"
).
-spec from_dynamic_unix_micro_utc(gleam@dynamic:dynamic_()) -> {ok,
tempo:date_time()} |
{error, list(gleam@dynamic@decode:decode_error())}.
from_dynamic_unix_micro_utc(Dynamic_ts) ->
gleam@result:map(
begin
_pipe = gleam@dynamic@decode:run(
Dynamic_ts,
{decoder, fun gleam@dynamic@decode:decode_int/1}
),
gleam@result:map_error(
_pipe,
fun(Errs) ->
gleam@list:map(
Errs,
fun(Err) ->
{decode_error,
erlang:element(2, Err),
erlang:element(3, Err),
erlang:element(4, Err)}
end
)
end
)
end,
fun(Unix_micro) -> from_unix_micro(Unix_micro) end
).
-file("src/tempo/datetime.gleam", 618).
?DOC(
" Gets the date of a datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T13:42:11.195Z\")\n"
" |> datetime.get_date\n"
" // -> date.literal(\"2024-06-21\")\n"
" ```\n"
).
-spec get_date(tempo:date_time()) -> tempo:date().
get_date(Datetime) ->
erlang:element(2, Datetime).
-file("src/tempo/datetime.gleam", 631).
?DOC(
" Gets the core gleam time package calendar date of a datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T13:42:11.195Z\")\n"
" |> datetime.get_calendar_date\n"
" // -> calendar.Date(2024, calendar.June, 21)\n"
" ```\n"
).
-spec get_calendar_date(tempo:date_time()) -> gleam@time@calendar:date().
get_calendar_date(Datetime) ->
_pipe = erlang:element(2, Datetime),
tempo@date:to_calendar_date(_pipe).
-file("src/tempo/datetime.gleam", 644).
?DOC(
" Gets the time of a datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T13:42:11.195Z\")\n"
" |> datetime.get_time\n"
" // -> time.literal(\"13:42:11.195\")\n"
" ```\n"
).
-spec get_time(tempo:date_time()) -> tempo:time().
get_time(Datetime) ->
erlang:element(3, Datetime).
-file("src/tempo/datetime.gleam", 657).
?DOC(
" Gets the core gleam time package calendar time of day of a datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T13:42:11.195Z\")\n"
" |> datetime.get_calendar_time_of_day\n"
" // -> calendar.TimeOfDay(13, 42, 11, 195_000_000)\n"
" ```\n"
).
-spec get_calendar_time_of_day(tempo:date_time()) -> gleam@time@calendar:time_of_day().
get_calendar_time_of_day(Datetime) ->
_pipe = erlang:element(3, Datetime),
tempo@time:to_calendar_time_of_day(_pipe).
-file("src/tempo/datetime.gleam", 670).
?DOC(
" Gets the offset of a datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-12T13:42:11.195-04:00\")\n"
" |> datetime.get_offset\n"
" // -> offset.literal(\"+04:00\")\n"
" ```\n"
).
-spec get_offset(tempo:date_time()) -> tempo:offset().
get_offset(Datetime) ->
_pipe = Datetime,
tempo:datetime_get_offset(_pipe).
-file("src/tempo/datetime.gleam", 683).
?DOC(
" Drops the time of a datetime, leaving the date and time values unchanged.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-13T13:42:11.195Z\")\n"
" |> datetime.drop_offset\n"
" // -> naive_datetime.literal(\"2024-06-13T13:42:11\")\n"
" ```\n"
).
-spec drop_offset(tempo:date_time()) -> tempo:naive_date_time().
drop_offset(Datetime) ->
tempo:datetime_drop_offset(Datetime).
-file("src/tempo/datetime.gleam", 696).
?DOC(
" Drops the time of a datetime, leaving the date value unchanged.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-18T13:42:11.195Z\")\n"
" |> datetime.drop_time\n"
" // -> naive_datetime.literal(\"2024-06-18T00:00:00Z\")\n"
" ```\n"
).
-spec drop_time(tempo:date_time()) -> tempo:date_time().
drop_time(Datetime) ->
Naive = tempo@naive_datetime:drop_time(
begin
_pipe = Datetime,
tempo:datetime_get_naive(_pipe)
end
),
tempo:datetime(
erlang:element(2, Naive),
erlang:element(3, Naive),
begin
_pipe@1 = Datetime,
tempo:datetime_get_offset(_pipe@1)
end
).
-file("src/tempo/datetime.gleam", 716).
?DOC(
" Applies the offset of a datetime to the date and time values, resulting\n"
" in a new naive datetime value that represents the original datetime in\n"
" UTC time.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T05:36:11.195-04:00\")\n"
" |> datetime.apply_offset\n"
" // -> naive_datetime.literal(\"2024-06-21T09:36:11.195\")\n"
" ```\n"
).
-spec apply_offset(tempo:date_time()) -> tempo:naive_date_time().
apply_offset(Datetime) ->
tempo:datetime_apply_offset(Datetime).
-file("src/tempo/datetime.gleam", 373).
?DOC(
" Returns the UTC unix timestamp of a datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-17T12:59:51Z\")\n"
" |> datetime.to_unix_seconds\n"
" // -> 1_718_829_191\n"
" ```\n"
).
-spec to_unix_seconds(tempo:date_time()) -> integer().
to_unix_seconds(Datetime) ->
Utc_dt = begin
_pipe = Datetime,
apply_offset(_pipe)
end,
tempo@date:to_unix_seconds(
begin
_pipe@1 = Utc_dt,
tempo:naive_datetime_get_date(_pipe@1)
end
)
+ (tempo:time_to_microseconds(
begin
_pipe@2 = Utc_dt,
tempo:naive_datetime_get_time(_pipe@2)
end
)
div 1000000).
-file("src/tempo/datetime.gleam", 404).
?DOC(
" Returns the UTC unix timestamp in milliseconds of a datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-17T13:01:54.334Z\")\n"
" |> datetime.to_unix_milli\n"
" // -> 1_718_629_314_334\n"
" ```\n"
).
-spec to_unix_milli(tempo:date_time()) -> integer().
to_unix_milli(Datetime) ->
Utc_dt = begin
_pipe = Datetime,
apply_offset(_pipe)
end,
tempo@date:to_unix_milli(
begin
_pipe@1 = Utc_dt,
tempo:naive_datetime_get_date(_pipe@1)
end
)
+ (tempo:time_to_microseconds(
begin
_pipe@2 = Utc_dt,
tempo:naive_datetime_get_time(_pipe@2)
end
)
div 1000).
-file("src/tempo/datetime.gleam", 729).
?DOC(
" Converts a datetime to the equivalent UTC time.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T05:36:11.195-04:00\")\n"
" |> datetime.to_utc\n"
" // -> datetime.literal(\"2024-06-21T09:36:11.195Z\")\n"
" ```\n"
).
-spec to_utc(tempo:date_time()) -> tempo:date_time().
to_utc(Datetime) ->
tempo:datetime_to_utc(Datetime).
-file("src/tempo/datetime.gleam", 320).
?DOC(
" Formats a datetime value into a string using the provided format.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(tempo.Custom(\"2024-06-21T13:42:11.314-04:00\"))\n"
" |> datetime.format(\"ddd @ h:mm A (z)\")\n"
" // -> \"Fri @ 1:42 PM (-04)\"\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-03T09:02:01-04:00\")\n"
" |> datetime.format(tempo.Custom(\"YY YYYY M MM MMM MMMM D DD d dd ddd\"))\n"
" // -----------:---------------> \"24 2024 6 06 Jun June 3 03 1 Mo Mon\"\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-03T09:02:01.014920202-00:00\")\n"
" |> datetime.format(tempo.Custom(\"dddd SSS SSSS SSSSS Z ZZ z\"))\n"
" // -> \"Monday 014 014920 014920202 -00:00 -0000 Z\"\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-03T13:02:01-04:00\")\n"
" |> datetime.format(tempo.Custom(\"H HH h hh m mm s ss a A [An ant]\"))\n"
" // --------------------------> \"13 13 1 01 2 02 1 01 pm PM An ant\"\n"
" ```\n"
).
-spec format(tempo:date_time(), tempo:date_time_format()) -> binary().
format(Datetime, Format) ->
_pipe = case Format of
h_t_t_p ->
to_utc(Datetime);
_ ->
Datetime
end,
tempo:datetime_format(_pipe, Format).
-file("src/tempo/datetime.gleam", 742).
?DOC(
" Converts a datetime to the equivalent time in an offset.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T05:36:11.195-04:00\")\n"
" |> datetime.to_offset(offset.literal(\"+10:00\"))\n"
" // -> datetime.literal(\"2024-06-21T19:36:11.195+10:00\")\n"
" ```\n"
).
-spec to_offset(tempo:date_time(), tempo:offset()) -> tempo:date_time().
to_offset(Datetime, Offset) ->
tempo:datetime_to_offset(Datetime, Offset).
-file("src/tempo/datetime.gleam", 778).
?DOC(
" Converts a datetime to the equivalent local datetime. Prefer to either\n"
" design your application to not need this, or add an external timezone\n"
" provider to use with the `to_timezone` function.\n"
"\n"
" Conversion is based on the host's current offset. We can not be\n"
" sure the current host offset is applicable to the given datetime, and so\n"
" an imprecise conversion will be performed. The imprecise conversion can be\n"
" inaccurate to the degree the local offset changes throughout the year.\n"
" For example, in North America where Daylight Savings Time is observed with\n"
" a one-hour time shift, the imprecise conversion can be off by up to an hour,\n"
" depending on the time of year.\n"
"\n"
" If the date of the given datetime matches the date of the host, then the\n"
" conversion will actually be precise all but during the hour(s) when the\n"
" time zone offset is shifting.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T09:57:11.195Z\")\n"
" |> datetime.to_local_imprecise\n"
" // -> tempo.Precise(datetime.literal(\"2024-06-21T05:57:11.195-04:00\"))\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.literal(\"1998-08-23T09:57:11.195Z\")\n"
" |> datetime.to_local_imprecise\n"
" // -> tempo.Imprecise(datetime.literal(\"1998-08-23T05:57:11.195-04:00\"))\n"
" ```\n"
).
-spec to_local_imprecise(tempo:date_time()) -> tempo:date_time().
to_local_imprecise(Datetime) ->
_pipe = Datetime,
to_offset(_pipe, tempo@offset:local()).
-file("src/tempo/datetime.gleam", 815).
?DOC(false).
-spec to_local_time_imprecise(tempo:date_time()) -> tempo:time().
to_local_time_imprecise(Datetime) ->
erlang:element(3, to_local_imprecise(Datetime)).
-file("src/tempo/datetime.gleam", 852).
?DOC(false).
-spec to_local_date_imprecise(tempo:date_time()) -> tempo:date().
to_local_date_imprecise(Datetime) ->
erlang:element(2, to_local_imprecise(Datetime)).
-file("src/tempo/datetime.gleam", 878).
?DOC(
" Converts a datetime to the specified timezone. Relies on an external\n"
" package like `gtz` to provide timezone information.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import gtz\n"
" let assert Ok(tz) = gtz.timezone(\"America/New_York\")\n"
" datetime.literal(\"2024-06-21T06:30:02.334Z\")\n"
" |> datetime.to_timezone(tz)\n"
" |> datetime.to_string\n"
" // -> \"2024-01-03T02:30:02.334-04:00\"\n"
" ```\n"
"\n"
" ```gleam\n"
" import gtz\n"
" let assert Ok(local_tz) = gtz.local_name() |> gtz.timezone\n"
" datetime.from_unix_seconds(1_729_257_776)\n"
" |> datetime.to_timezone(local_tz)\n"
" |> datetime.to_string\n"
" // -> \"2024-10-18T14:22:56.000+01:00\"\n"
" ```\n"
).
-spec to_timezone(tempo:date_time(), tempo:time_zone_provider()) -> tempo:date_time().
to_timezone(Datetime, Tz) ->
tempo:datetime_to_tz(Datetime, Tz).
-file("src/tempo/datetime.gleam", 902).
?DOC(
" Gets the name of the timezone the datetime is in.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T06:30:02.334Z\")\n"
" |> datetime.get_timezone_name\n"
" // -> None\n"
" ```\n"
"\n"
" ```gleam\n"
" import gtz\n"
" let assert Ok(tz) = gtz.timezone(\"Europe/London\")\n"
" datetime.to_timezone(my_datetime, tz)\n"
" |> datetime.get_timezone_name\n"
" // -> Some(\"Europe/London\")\n"
" ```\n"
).
-spec get_timezone_name(tempo:date_time()) -> gleam@option:option(binary()).
get_timezone_name(Datetime) ->
tempo:datetime_get_tz(Datetime).
-file("src/tempo/datetime.gleam", 927).
?DOC(
" Compares two datetimes.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T23:47:00+09:05\")\n"
" |> datetime.compare(to: datetime.literal(\"2024-06-21T23:47:00+09:05\"))\n"
" // -> order.Eq\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2023-05-11T13:30:00-04:00\")\n"
" |> datetime.compare(to: datetime.literal(\"2023-05-11T13:15:00Z\"))\n"
" // -> order.Lt\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-12T23:47:00+09:05\")\n"
" |> datetime.compare(to: datetime.literal(\"2022-04-12T00:00:00\"))\n"
" // -> order.Gt\n"
" ```\n"
).
-spec compare(tempo:date_time(), tempo:date_time()) -> gleam@order:order().
compare(A, B) ->
tempo:datetime_compare(A, B).
-file("src/tempo/datetime.gleam", 950).
?DOC(
" Checks if the first datetime is earlier than the second datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T23:47:00+09:05\")\n"
" |> datetime.is_earlier(\n"
" than: datetime.literal(\"2024-06-21T23:47:00+09:05\"),\n"
" )\n"
" // -> False\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2023-05-11T13:30:00-04:00\")\n"
" |> datetime.is_earlier(\n"
" than: datetime.literal(\"2023-05-11T13:15:00Z\"),\n"
" )\n"
" // -> True\n"
" ```\n"
).
-spec is_earlier(tempo:date_time(), tempo:date_time()) -> boolean().
is_earlier(A, B) ->
tempo:datetime_is_earlier(A, B).
-file("src/tempo/datetime.gleam", 972).
?DOC(
" Checks if the first datetime is earlier or equal to the second datetime.\n"
"\n"
" ## Examples\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T23:47:00+09:05\")\n"
" |> datetime.is_earlier_or_equal(\n"
" to: datetime.literal(\"2024-06-21T23:47:00+09:05\"),\n"
" )\n"
" // -> True\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-07-15T23:40:00-04:00\")\n"
" |> datetime.is_earlier_or_equal(\n"
" to: datetime.literal(\"2023-05-11T13:15:00Z\"),\n"
" )\n"
" // -> False\n"
" ```\n"
).
-spec is_earlier_or_equal(tempo:date_time(), tempo:date_time()) -> boolean().
is_earlier_or_equal(A, B) ->
tempo:datetime_is_earlier_or_equal(A, B).
-file("src/tempo/datetime.gleam", 994).
?DOC(
" Checks if the first datetime is equal to the second datetime.\n"
"\n"
" ## Examples\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T09:44:00Z\")\n"
" |> datetime.is_equal(\n"
" to: datetime.literal(\"2024-06-21T05:44:00-04:00\"),\n"
" )\n"
" // -> True\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T09:44:00Z\")\n"
" |> datetime.is_equal(\n"
" to: datetime.literal(\"2024-06-21T09:44:00.045Z\"),\n"
" )\n"
" // -> False\n"
" ```\n"
).
-spec is_equal(tempo:date_time(), tempo:date_time()) -> boolean().
is_equal(A, B) ->
tempo:datetime_is_equal(A, B).
-file("src/tempo/datetime.gleam", 1017).
?DOC(
" Checks if the first datetime is later than the second datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T23:47:00+09:05\")\n"
" |> datetime.is_later(\n"
" than: datetime.literal(\"2024-06-21T23:47:00+09:05\"),\n"
" )\n"
" // -> False\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2023-05-11T13:00:00+04:00\")\n"
" |> datetime.is_later(\n"
" than: datetime.literal(\"2023-05-11T13:15:00.534Z\"),\n"
" )\n"
" // -> True\n"
" ```\n"
).
-spec is_later(tempo:date_time(), tempo:date_time()) -> boolean().
is_later(A, B) ->
tempo:datetime_is_later(A, B).
-file("src/tempo/datetime.gleam", 1039).
?DOC(
" Checks if the first datetime is later or equal to the second datetime.\n"
"\n"
" ## Examples\n"
" ```gleam\n"
" datetime.literal(\"2016-01-11T03:47:00+09:05\")\n"
" |> datetime.is_later_or_equal(\n"
" to: datetime.literal(\"2024-06-21T23:47:00+09:05\"),\n"
" )\n"
" // -> False\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-07-15T23:40:00-04:00\")\n"
" |> datetime.is_later_or_equal(\n"
" to: datetime.literal(\"2023-05-11T13:15:00Z\"),\n"
" )\n"
" // -> True\n"
" ```\n"
).
-spec is_later_or_equal(tempo:date_time(), tempo:date_time()) -> boolean().
is_later_or_equal(A, B) ->
tempo:datetime_is_later_or_equal(A, B).
-file("src/tempo/datetime.gleam", 1065).
?DOC(
" Returns the difference between two datetimes as a duration between their\n"
" equivalent UTC times.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-12T23:17:00Z\")\n"
" |> datetime.difference(\n"
" from: datetime.literal(\"2024-06-16T01:16:12Z\"),\n"
" )\n"
" |> duration.as_days\n"
" // -> 3\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-12T23:17:00Z\")\n"
" |> datetime.difference(\n"
" from: datetime.literal(\"2024-06-16T01:18:12Z\"),\n"
" )\n"
" |> duration.format\n"
" // -> \"3 days, 2 hours, and 1 minute\"\n"
" ```\n"
).
-spec difference(tempo:date_time(), tempo:date_time()) -> gleam@time@duration:duration().
difference(A, B) ->
tempo@naive_datetime:difference(
tempo:datetime_apply_offset(A),
tempo:datetime_apply_offset(B)
).
-file("src/tempo/datetime.gleam", 1099).
?DOC(
" Creates a period between two datetimes, where the start and end times are\n"
" the equivalent UTC times of the provided datetimes. The specified start\n"
" and end datetimes will be swapped if the start datetime is later than the\n"
" end datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.to_period(\n"
" start: datetime.literal(\"2024-06-12T23:17:00Z\")\n"
" end: datetime.literal(\"2024-06-16T01:16:12Z\"),\n"
" )\n"
" |> period.as_days\n"
" // -> 3\n"
" ```\n"
"\n"
" ```gleam\n"
" datetime.to_period(\n"
" start: datetime.literal(\"2024-06-12T23:17:00Z\")\n"
" end: datetime.literal(\"2024-06-16T01:18:12Z\"),\n"
" )\n"
" |> period.format\n"
" // -> \"3 days, 2 hours, and 1 minute\"\n"
" ```\n"
).
-spec as_period(tempo:date_time(), tempo:date_time()) -> tempo:period().
as_period(Start, End) ->
tempo:period_new(Start, End).
-file("src/tempo/datetime.gleam", 1115).
?DOC(
" Adds a duration to a datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-12T23:17:00Z\")\n"
" |> datetime.add(duration |> tempo.offset_get_minutes(3))\n"
" // -> datetime.literal(\"2024-06-12T23:20:00Z\")\n"
" ```\n"
).
-spec add(tempo:date_time(), gleam@time@duration:duration()) -> tempo:date_time().
add(Datetime, Duration_to_add) ->
tempo:datetime_add(Datetime, Duration_to_add).
-file("src/tempo/datetime.gleam", 1131).
?DOC(
" Subtracts a duration from a datetime.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" datetime.literal(\"2024-06-21T23:17:00Z\")\n"
" |> datetime.subtract(duration.days(3))\n"
" // -> datetime.literal(\"2024-06-18T23:17:00Z\")\n"
" ```\n"
).
-spec subtract(tempo:date_time(), gleam@time@duration:duration()) -> tempo:date_time().
subtract(Datetime, Duration_to_subtract) ->
tempo:datetime_subtract(Datetime, Duration_to_subtract).
-file("src/tempo/datetime.gleam", 1155).
?DOC(
" Gets the time left in the day.\n"
"\n"
" Does **not** account for leap seconds like the rest of the package.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" naive_datetime.literal(\"2015-06-30T23:59:03Z\")\n"
" |> naive_datetime.time_left_in_day\n"
" // -> time.literal(\"00:00:57\")\n"
" ```\n"
"\n"
" ```gleam\n"
" naive_datetime.literal(\"2024-06-18T08:05:20-04:00\")\n"
" |> naive_datetime.time_left_in_day\n"
" // -> time.literal(\"15:54:40\")\n"
" ```\n"
).
-spec time_left_in_day(tempo:date_time()) -> tempo:time().
time_left_in_day(Datetime) ->
_pipe = Datetime,
_pipe@1 = tempo:datetime_get_naive(_pipe),
_pipe@2 = tempo:naive_datetime_get_time(_pipe@1),
tempo@time:left_in_day(_pipe@2).