Current section

Files

Jump to
gtempo src tempo@time.erl
Raw

src/tempo@time.erl

-module(tempo@time).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([new/3, new_milli/4, new_micro/4, new_nano/4, test_literal/3, test_literal_milli/4, test_literal_micro/4, test_literal_nano/4, set_hour/2, set_minute/2, set_second/2, set_milli/2, set_micro/2, set_nano/2, to_second_precision/1, to_milli_precision/1, to_micro_precision/1, to_nano_precision/1, to_string/1, from_string/1, literal/1, to_tuple/1, from_tuple/1, to_tuple_nanosecond/1, from_tuple_nanosecond/1, compare/2, is_earlier/2, is_earlier_or_equal/2, is_equal/2, is_later/2, is_later_or_equal/2, is_between/3, is_outside/3, to_nanoseconds/1, to_duration/1, difference/2, difference_abs/2, from_nanoseconds/1, now_utc/0, now_local/0, from_unix_utc/1, from_unix_milli_utc/1, from_unix_micro_utc/1, from_unix_nano_utc/1, from_duration/1, add/2, subtract/2, left_in_day/1, until/2, since/2]).
-export_type([boundary/0]).
-type boundary() :: {boundary, tempo:time(), boolean()}.
-spec validate(tempo:time()) -> {ok, tempo:time()} | {error, tempo:error()}.
validate(Time) ->
case (((((((erlang:element(2, Time) >= 0) andalso (erlang:element(2, Time)
=< 23))
andalso (erlang:element(3, Time) >= 0))
andalso (erlang:element(3, Time) =< 59))
andalso (erlang:element(4, Time) >= 0))
andalso (erlang:element(4, Time) =< 59))
orelse ((((erlang:element(2, Time) =:= 24) andalso (erlang:element(3, Time)
=:= 0))
andalso (erlang:element(4, Time) =:= 0))
andalso (erlang:element(5, Time) =:= 0)))
orelse (((erlang:element(3, Time) =:= 59) andalso (erlang:element(4, Time)
=:= 60))
andalso (erlang:element(5, Time) =:= 0)) of
true ->
case Time of
{time, _, _, _, _} ->
{ok, Time};
{time_milli, _, _, _, Millis} when Millis =< 999000000 ->
{ok, Time};
{time_micro, _, _, _, Micros} when Micros =< 999999000 ->
{ok, Time};
{time_nano, _, _, _, Nanos} when Nanos =< 999999999 ->
{ok, Time};
_ ->
{error, time_out_of_bounds}
end;
false ->
{error, time_out_of_bounds}
end.
-spec new(integer(), integer(), integer()) -> {ok, tempo:time()} |
{error, tempo:error()}.
new(Hour, Minute, Second) ->
_pipe = {time, Hour, Minute, Second, 0},
validate(_pipe).
-spec new_milli(integer(), integer(), integer(), integer()) -> {ok,
tempo:time()} |
{error, tempo:error()}.
new_milli(Hour, Minute, Second, Millisecond) ->
_pipe = {time_milli, Hour, Minute, Second, Millisecond * 1000000},
validate(_pipe).
-spec new_micro(integer(), integer(), integer(), integer()) -> {ok,
tempo:time()} |
{error, tempo:error()}.
new_micro(Hour, Minute, Second, Microsecond) ->
_pipe = {time_micro, Hour, Minute, Second, Microsecond * 1000},
validate(_pipe).
-spec new_nano(integer(), integer(), integer(), integer()) -> {ok, tempo:time()} |
{error, tempo:error()}.
new_nano(Hour, Minute, Second, Nanosecond) ->
_pipe = {time_nano, Hour, Minute, Second, Nanosecond},
validate(_pipe).
-spec test_literal(integer(), integer(), integer()) -> tempo:time().
test_literal(Hour, Minute, Second) ->
_assert_subject = begin
_pipe = {time, Hour, Minute, Second, 0},
validate(_pipe)
end,
{ok, Time} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"tempo/time"/utf8>>,
function => <<"test_literal"/utf8>>,
line => 195})
end,
Time.
-spec test_literal_milli(integer(), integer(), integer(), integer()) -> tempo:time().
test_literal_milli(Hour, Minute, Second, Millisecond) ->
_assert_subject = begin
_pipe = {time_milli, Hour, Minute, Second, Millisecond * 1000000},
validate(_pipe)
end,
{ok, Time} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"tempo/time"/utf8>>,
function => <<"test_literal_milli"/utf8>>,
line => 201})
end,
Time.
-spec test_literal_micro(integer(), integer(), integer(), integer()) -> tempo:time().
test_literal_micro(Hour, Minute, Second, Microsecond) ->
_assert_subject = begin
_pipe = {time_micro, Hour, Minute, Second, Microsecond * 1000},
validate(_pipe)
end,
{ok, Time} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"tempo/time"/utf8>>,
function => <<"test_literal_micro"/utf8>>,
line => 209})
end,
Time.
-spec test_literal_nano(integer(), integer(), integer(), integer()) -> tempo:time().
test_literal_nano(Hour, Minute, Second, Nanosecond) ->
_assert_subject = begin
_pipe = {time_nano, Hour, Minute, Second, Nanosecond},
validate(_pipe)
end,
{ok, Time} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"tempo/time"/utf8>>,
function => <<"test_literal_nano"/utf8>>,
line => 216})
end,
Time.
-spec set_hour(tempo:time(), integer()) -> {ok, tempo:time()} |
{error, tempo:error()}.
set_hour(Time, Hour) ->
case Time of
{time, _, M, S, _} ->
new(Hour, M, S);
{time_milli, _, M@1, S@1, N} ->
new_milli(Hour, M@1, S@1, N);
{time_micro, _, M@2, S@2, N@1} ->
new_micro(Hour, M@2, S@2, N@1);
{time_nano, _, M@3, S@3, N@2} ->
new_nano(Hour, M@3, S@3, N@2)
end.
-spec set_minute(tempo:time(), integer()) -> {ok, tempo:time()} |
{error, tempo:error()}.
set_minute(Time, Minute) ->
case Time of
{time, H, _, S, _} ->
new(H, Minute, S);
{time_milli, H@1, _, S@1, N} ->
new_milli(H@1, Minute, S@1, N);
{time_micro, H@2, _, S@2, N@1} ->
new_micro(H@2, Minute, S@2, N@1);
{time_nano, H@3, _, S@3, N@2} ->
new_nano(H@3, Minute, S@3, N@2)
end.
-spec set_second(tempo:time(), integer()) -> {ok, tempo:time()} |
{error, tempo:error()}.
set_second(Time, Second) ->
case Time of
{time, H, M, _, _} ->
new(H, M, Second);
{time_milli, H@1, M@1, _, N} ->
new_milli(H@1, M@1, Second, N);
{time_micro, H@2, M@2, _, N@1} ->
new_micro(H@2, M@2, Second, N@1);
{time_nano, H@3, M@3, _, N@2} ->
new_nano(H@3, M@3, Second, N@2)
end.
-spec set_milli(tempo:time(), integer()) -> {ok, tempo:time()} |
{error, tempo:error()}.
set_milli(Time, Millisecond) ->
new_milli(
erlang:element(2, Time),
erlang:element(3, Time),
erlang:element(4, Time),
Millisecond
).
-spec set_micro(tempo:time(), integer()) -> {ok, tempo:time()} |
{error, tempo:error()}.
set_micro(Time, Microsecond) ->
new_micro(
erlang:element(2, Time),
erlang:element(3, Time),
erlang:element(4, Time),
Microsecond
).
-spec set_nano(tempo:time(), integer()) -> {ok, tempo:time()} |
{error, tempo:error()}.
set_nano(Time, Nanosecond) ->
new_nano(
erlang:element(2, Time),
erlang:element(3, Time),
erlang:element(4, Time),
Nanosecond
).
-spec to_second_precision(tempo:time()) -> tempo:time().
to_second_precision(Time) ->
{time,
erlang:element(2, Time),
erlang:element(3, Time),
erlang:element(4, Time),
0}.
-spec to_milli_precision(tempo:time()) -> tempo:time().
to_milli_precision(Time) ->
{time_milli,
erlang:element(2, Time),
erlang:element(3, Time),
erlang:element(4, Time),
(erlang:element(5, Time) div 1000000) * 1000000}.
-spec to_micro_precision(tempo:time()) -> tempo:time().
to_micro_precision(Time) ->
{time_micro,
erlang:element(2, Time),
erlang:element(3, Time),
erlang:element(4, Time),
(erlang:element(5, Time) div 1000) * 1000}.
-spec to_nano_precision(tempo:time()) -> tempo:time().
to_nano_precision(Time) ->
{time_nano,
erlang:element(2, Time),
erlang:element(3, Time),
erlang:element(4, Time),
erlang:element(5, Time)}.
-spec to_string(tempo:time()) -> binary().
to_string(Time) ->
_pipe@6 = gleam@string_builder:from_strings(
[begin
_pipe = erlang:element(2, Time),
_pipe@1 = gleam@int:to_string(_pipe),
gleam@string:pad_left(_pipe@1, 2, <<"0"/utf8>>)
end,
<<":"/utf8>>,
begin
_pipe@2 = erlang:element(3, Time),
_pipe@3 = gleam@int:to_string(_pipe@2),
gleam@string:pad_left(_pipe@3, 2, <<"0"/utf8>>)
end,
<<":"/utf8>>,
begin
_pipe@4 = erlang:element(4, Time),
_pipe@5 = gleam@int:to_string(_pipe@4),
gleam@string:pad_left(_pipe@5, 2, <<"0"/utf8>>)
end]
),
_pipe@16 = (fun(Sb) -> case Time of
{time, _, _, _, _} ->
Sb;
{time_milli, _, _, _, Nanos} ->
_pipe@7 = gleam@string_builder:append(Sb, <<"."/utf8>>),
gleam@string_builder:append(
_pipe@7,
begin
_pipe@8 = (Nanos div 1000000),
_pipe@9 = gleam@int:to_string(_pipe@8),
gleam@string:pad_left(_pipe@9, 3, <<"0"/utf8>>)
end
);
{time_micro, _, _, _, Nanos@1} ->
_pipe@10 = gleam@string_builder:append(Sb, <<"."/utf8>>),
gleam@string_builder:append(
_pipe@10,
begin
_pipe@11 = (Nanos@1 div 1000),
_pipe@12 = gleam@int:to_string(_pipe@11),
gleam@string:pad_left(_pipe@12, 6, <<"0"/utf8>>)
end
);
{time_nano, _, _, _, Nanos@2} ->
_pipe@13 = gleam@string_builder:append(Sb, <<"."/utf8>>),
gleam@string_builder:append(
_pipe@13,
begin
_pipe@14 = Nanos@2,
_pipe@15 = gleam@int:to_string(_pipe@14),
gleam@string:pad_left(_pipe@15, 9, <<"0"/utf8>>)
end
)
end end)(_pipe@6),
gleam@string_builder:to_string(_pipe@16).
-spec from_string(binary()) -> {ok, tempo:time()} | {error, tempo:error()}.
from_string(Time) ->
gleam@result:'try'(
begin
_pipe = case gleam@string:split(Time, <<":"/utf8>>) of
[Hour, Minute, Second] ->
{ok, {Hour, Minute, Second}};
[Hour@1, Minute@1] ->
{ok, {Hour@1, Minute@1, <<"0"/utf8>>}};
_ ->
{error, time_invalid_format}
end,
gleam@result:try_recover(
_pipe,
fun(_) ->
case {gleam@string:length(Time),
gleam_stdlib:contains_string(Time, <<"."/utf8>>)} of
{6, false} ->
{ok,
{gleam@string:slice(Time, 0, 2),
gleam@string:slice(Time, 2, 2),
gleam@string:slice(Time, 4, 2)}};
{4, false} ->
{ok,
{gleam@string:slice(Time, 0, 2),
gleam@string:slice(Time, 2, 2),
<<"0"/utf8>>}};
{L, true} when L >= 7 ->
{ok,
{gleam@string:slice(Time, 0, 2),
gleam@string:slice(Time, 2, 2),
gleam@string:slice(Time, 4, 12)}};
{_, _} ->
{error, time_invalid_format}
end
end
)
end,
fun(_use0) ->
{Hour@2, Minute@2, Second@1} = _use0,
_pipe@4 = case {gleam@int:parse(Hour@2),
gleam@int:parse(Minute@2),
gleam@string:split(Second@1, <<"."/utf8>>)} of
{{ok, Hour@3}, {ok, Minute@3}, [Second@2, Second_fraction]} ->
Second_fraction_length = gleam@string:length(
Second_fraction
),
case Second_fraction_length of
Len when Len =< 3 ->
case {gleam@int:parse(Second@2),
gleam@int:parse(
begin
_pipe@1 = Second_fraction,
gleam@string:pad_right(
_pipe@1,
3,
<<"0"/utf8>>
)
end
)} of
{{ok, Second@3}, {ok, Milli}} ->
{ok,
{time_milli,
Hour@3,
Minute@3,
Second@3,
Milli * 1000000}};
{_, _} ->
{error, time_invalid_format}
end;
Len@1 when Len@1 =< 6 ->
case {gleam@int:parse(Second@2),
gleam@int:parse(
begin
_pipe@2 = Second_fraction,
gleam@string:pad_right(
_pipe@2,
6,
<<"0"/utf8>>
)
end
)} of
{{ok, Second@4}, {ok, Micro}} ->
{ok,
{time_micro,
Hour@3,
Minute@3,
Second@4,
Micro * 1000}};
{_, _} ->
{error, time_invalid_format}
end;
Len@2 when Len@2 =< 9 ->
case {gleam@int:parse(Second@2),
gleam@int:parse(
begin
_pipe@3 = Second_fraction,
gleam@string:pad_right(
_pipe@3,
9,
<<"0"/utf8>>
)
end
)} of
{{ok, Second@5}, {ok, Nano}} ->
{ok,
{time_nano,
Hour@3,
Minute@3,
Second@5,
Nano}};
{_, _} ->
{error, time_invalid_format}
end;
_ ->
{error, time_invalid_format}
end;
{{ok, Hour@4}, {ok, Minute@4}, _} ->
case gleam@int:parse(Second@1) of
{ok, Second@6} ->
{ok, {time, Hour@4, Minute@4, Second@6, 0}};
_ ->
{error, time_invalid_format}
end;
{_, _, _} ->
{error, time_invalid_format}
end,
gleam@result:'try'(_pipe@4, fun validate/1)
end
).
-spec literal(binary()) -> tempo:time().
literal(Time) ->
case from_string(Time) of
{ok, Time@1} ->
Time@1;
{error, time_invalid_format} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid time literal format"/utf8>>,
module => <<"tempo/time"/utf8>>,
function => <<"literal"/utf8>>,
line => 136});
{error, time_out_of_bounds} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid time literal value"/utf8>>,
module => <<"tempo/time"/utf8>>,
function => <<"literal"/utf8>>,
line => 137});
{error, _} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid time literal"/utf8>>,
module => <<"tempo/time"/utf8>>,
function => <<"literal"/utf8>>,
line => 138})
end.
-spec to_tuple(tempo:time()) -> {integer(), integer(), integer()}.
to_tuple(Time) ->
{erlang:element(2, Time), erlang:element(3, Time), erlang:element(4, Time)}.
-spec from_tuple({integer(), integer(), integer()}) -> {ok, tempo:time()} |
{error, tempo:error()}.
from_tuple(Time) ->
new(
erlang:element(1, Time),
erlang:element(2, Time),
erlang:element(3, Time)
).
-spec to_tuple_nanosecond(tempo:time()) -> {integer(),
integer(),
integer(),
integer()}.
to_tuple_nanosecond(Time) ->
{erlang:element(2, Time),
erlang:element(3, Time),
erlang:element(4, Time),
erlang:element(5, Time)}.
-spec from_tuple_nanosecond({integer(), integer(), integer(), integer()}) -> {ok,
tempo:time()} |
{error, tempo:error()}.
from_tuple_nanosecond(Time) ->
new_nano(
erlang:element(1, Time),
erlang:element(2, Time),
erlang:element(3, Time),
erlang:element(4, Time)
).
-spec compare(tempo:time(), tempo:time()) -> gleam@order:order().
compare(A, B) ->
case erlang:element(2, A) =:= erlang:element(2, B) of
true ->
case erlang:element(3, A) =:= erlang:element(3, B) of
true ->
case erlang:element(4, A) =:= erlang:element(4, B) of
true ->
case erlang:element(5, A) =:= erlang:element(5, B) of
true ->
eq;
false ->
case erlang:element(5, A) < erlang:element(
5,
B
) of
true ->
lt;
false ->
gt
end
end;
false ->
case erlang:element(4, A) < erlang:element(4, B) of
true ->
lt;
false ->
gt
end
end;
false ->
case erlang:element(3, A) < erlang:element(3, B) of
true ->
lt;
false ->
gt
end
end;
false ->
case erlang:element(2, A) < erlang:element(2, B) of
true ->
lt;
false ->
gt
end
end.
-spec is_earlier(tempo:time(), tempo:time()) -> boolean().
is_earlier(A, B) ->
compare(A, B) =:= lt.
-spec is_earlier_or_equal(tempo:time(), tempo:time()) -> boolean().
is_earlier_or_equal(A, B) ->
(compare(A, B) =:= lt) orelse (compare(A, B) =:= eq).
-spec is_equal(tempo:time(), tempo:time()) -> boolean().
is_equal(A, B) ->
compare(A, B) =:= eq.
-spec is_later(tempo:time(), tempo:time()) -> boolean().
is_later(A, B) ->
compare(A, B) =:= gt.
-spec is_later_or_equal(tempo:time(), tempo:time()) -> boolean().
is_later_or_equal(A, B) ->
(compare(A, B) =:= gt) orelse (compare(A, B) =:= eq).
-spec is_between(tempo:time(), boundary(), boundary()) -> boolean().
is_between(Time, Start, End) ->
case erlang:element(3, Start) of
true ->
is_later_or_equal(Time, erlang:element(2, Start));
false ->
is_later(Time, erlang:element(2, Start))
end andalso case erlang:element(3, End) of
true ->
is_earlier_or_equal(Time, erlang:element(2, End));
false ->
is_earlier(Time, erlang:element(2, End))
end.
-spec is_outside(tempo:time(), boundary(), boundary()) -> boolean().
is_outside(Time, Start, End) ->
case erlang:element(3, Start) of
true ->
is_earlier_or_equal(Time, erlang:element(2, Start));
false ->
is_earlier(Time, erlang:element(2, Start))
end orelse case erlang:element(3, End) of
true ->
is_later_or_equal(Time, erlang:element(2, End));
false ->
is_later(Time, erlang:element(2, End))
end.
-spec to_nanoseconds(tempo:time()) -> integer().
to_nanoseconds(Time) ->
(((erlang:element(2, Time) * 3600000000000) + (erlang:element(3, Time) * 60000000000))
+ (erlang:element(4, Time) * 1000000000))
+ erlang:element(5, Time).
-spec to_duration(tempo:time()) -> tempo:duration().
to_duration(Time) ->
_pipe = to_nanoseconds(Time),
{duration, _pipe}.
-spec difference(tempo:time(), tempo:time()) -> tempo:duration().
difference(A, B) ->
_pipe = to_nanoseconds(A) - to_nanoseconds(B),
{duration, _pipe}.
-spec difference_abs(tempo:time(), tempo:time()) -> tempo:duration().
difference_abs(A, B) ->
case to_nanoseconds(A) - to_nanoseconds(B) of
Diff when Diff < 0 ->
_pipe = - Diff,
{duration, _pipe};
Diff@1 ->
_pipe@1 = Diff@1,
{duration, _pipe@1}
end.
-spec from_nanoseconds(integer()) -> tempo:time().
from_nanoseconds(Nanoseconds) ->
In_range_ns = case 86400000000000 of
0 -> 0;
Gleam@denominator -> Nanoseconds rem Gleam@denominator
end,
Adj_ns = case In_range_ns < 0 of
true ->
In_range_ns + 86400000000000;
false ->
In_range_ns
end,
Hours = Adj_ns div 3600000000000,
Minutes = (Adj_ns - (Hours * 3600000000000)) div 60000000000,
Seconds = ((Adj_ns - (Hours * 3600000000000)) - (Minutes * 60000000000)) div 1000000000,
Nanoseconds@1 = ((Adj_ns - (Hours * 3600000000000)) - (Minutes * 60000000000))
- (Seconds * 1000000000),
{time_nano, Hours, Minutes, Seconds, Nanoseconds@1}.
-spec now_utc() -> tempo:time().
now_utc() ->
Now_ts_nano = tempo_ffi:now(),
Date_ts_nano = (tempo@date:to_unix_utc(
tempo@date:from_unix_utc(Now_ts_nano div 1000000000)
))
* 1000000000,
from_nanoseconds(Now_ts_nano - Date_ts_nano).
-spec now_local() -> tempo:time().
now_local() ->
Now_ts_nano = tempo_ffi:now(),
Date_ts_nano = (tempo@date:to_unix_utc(
tempo@date:from_unix_utc(Now_ts_nano div 1000000000)
))
* 1000000000,
from_nanoseconds((Now_ts_nano - Date_ts_nano) + tempo@offset:local_nano()).
-spec from_unix_utc(integer()) -> tempo:time().
from_unix_utc(Unix_ts) ->
_pipe = (Unix_ts - (tempo@date:to_unix_utc(
tempo@date:from_unix_utc(Unix_ts)
)))
* 1000000000,
_pipe@1 = from_nanoseconds(_pipe),
to_second_precision(_pipe@1).
-spec from_unix_milli_utc(integer()) -> tempo:time().
from_unix_milli_utc(Unix_ts) ->
_pipe = (Unix_ts - (tempo@date:to_unix_milli_utc(
tempo@date:from_unix_milli_utc(Unix_ts)
)))
* 1000000,
_pipe@1 = from_nanoseconds(_pipe),
to_milli_precision(_pipe@1).
-spec from_unix_micro_utc(integer()) -> tempo:time().
from_unix_micro_utc(Unix_ts) ->
_pipe = (Unix_ts - (tempo@date:to_unix_micro_utc(
tempo@date:from_unix_micro_utc(Unix_ts)
)))
* 1000,
_pipe@1 = from_nanoseconds(_pipe),
to_micro_precision(_pipe@1).
-spec from_unix_nano_utc(integer()) -> tempo:time().
from_unix_nano_utc(Unix_ts) ->
_pipe = (Unix_ts - ((tempo@date:to_unix_micro_utc(
tempo@date:from_unix_micro_utc(Unix_ts div 1000)
))
* 1000)),
from_nanoseconds(_pipe).
-spec from_duration(tempo:duration()) -> tempo:time().
from_duration(Duration) ->
from_nanoseconds(erlang:element(2, Duration)).
-spec add(tempo:time(), tempo:duration()) -> tempo:time().
add(A, B) ->
New_time = begin
_pipe = to_nanoseconds(A) + erlang:element(2, B),
from_nanoseconds(_pipe)
end,
case A of
{time, _, _, _, _} ->
to_second_precision(New_time);
{time_milli, _, _, _, _} ->
to_milli_precision(New_time);
{time_micro, _, _, _, _} ->
to_micro_precision(New_time);
{time_nano, _, _, _, _} ->
to_nano_precision(New_time)
end.
-spec subtract(tempo:time(), tempo:duration()) -> tempo:time().
subtract(A, B) ->
New_time = begin
_pipe = to_nanoseconds(A) - erlang:element(2, B),
from_nanoseconds(_pipe)
end,
case A of
{time, _, _, _, _} ->
to_second_precision(New_time);
{time_milli, _, _, _, _} ->
to_milli_precision(New_time);
{time_micro, _, _, _, _} ->
to_micro_precision(New_time);
{time_nano, _, _, _, _} ->
to_nano_precision(New_time)
end.
-spec left_in_day(tempo:time()) -> tempo:time().
left_in_day(Time) ->
New_time = begin
_pipe@1 = 86400000000000 - begin
_pipe = Time,
to_nanoseconds(_pipe)
end,
from_nanoseconds(_pipe@1)
end,
case Time of
{time, _, _, _, _} ->
to_second_precision(New_time);
{time_milli, _, _, _, _} ->
to_milli_precision(New_time);
{time_micro, _, _, _, _} ->
to_micro_precision(New_time);
{time_nano, _, _, _, _} ->
to_nano_precision(New_time)
end.
-spec until(tempo:time(), tempo:time()) -> tempo:duration().
until(Time, Until) ->
Dur = begin
_pipe = Time,
_pipe@1 = difference(_pipe, Until),
tempo@duration:inverse(_pipe@1)
end,
case begin
_pipe@2 = Dur,
tempo@duration:is_negative(_pipe@2)
end of
true ->
tempo@duration:nanoseconds(0);
false ->
Dur
end.
-spec since(tempo:time(), tempo:time()) -> tempo:duration().
since(Time, Since) ->
Dur = begin
_pipe = Time,
difference(_pipe, Since)
end,
case begin
_pipe@1 = Dur,
tempo@duration:is_negative(_pipe@1)
end of
true ->
tempo@duration:nanoseconds(0);
false ->
Dur
end.