-module(tempo@datetime). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([new/3, now_utc/0, from_string/1, literal/1, to_string/1, parse/2, parse_any/1, from_unix_utc/1, from_unix_milli_utc/1, from_unix_micro_utc/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_time/1, get_offset/1, format/2, drop_offset/1, drop_time/1, to_second_precision/1, to_milli_precision/1, to_micro_precision/1, to_nano_precision/1, add/2, apply_offset/1, to_unix_utc/1, to_unix_milli_utc/1, to_unix_micro_utc/1, to_utc/1, compare/2, is_earlier/2, is_earlier_or_equal/2, is_equal/2, is_later/2, is_later_or_equal/2, as_period/2, difference/2, subtract/2, to_offset/2, to_local/1, now_local/0, now_text/0, to_local_time/1, to_local_date/1, time_left_in_day/1]). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 27). -spec new(tempo:date(), tempo:time(), tempo:offset()) -> tempo:date_time(). new(Date, Time, Offset) -> {date_time, tempo@naive_datetime:new(Date, Time), Offset}. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 88). -spec now_utc() -> tempo:date_time(). now_utc() -> Now_ts_nano = tempo_ffi:now(), new( tempo@date:from_unix_utc(Now_ts_nano div 1000000000), tempo@time:from_unix_nano_utc(Now_ts_nano), {offset, 0} ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 156). -spec split_time_and_offset(binary()) -> {ok, {binary(), binary()}} | {error, tempo:error()}. split_time_and_offset(Time_with_offset) -> case gleam@string:slice(Time_with_offset, -1, 1) of <<"Z"/utf8>> -> _pipe = {gleam@string:drop_right(Time_with_offset, 1), <<"Z"/utf8>>}, {ok, _pipe}; <<"z"/utf8>> -> _pipe@1 = {gleam@string:drop_right(Time_with_offset, 1), <<"Z"/utf8>>}, {ok, _pipe@1}; _ -> case gleam@string:split(Time_with_offset, <<"-"/utf8>>) of [Time, Offset] -> _pipe@2 = {Time, <<"-"/utf8, Offset/binary>>}, {ok, _pipe@2}; _ -> case gleam@string:split(Time_with_offset, <<"+"/utf8>>) of [Time@1, Offset@1] -> _pipe@3 = {Time@1, <<"+"/utf8, Offset@1/binary>>}, {ok, _pipe@3}; _ -> {error, date_time_invalid_format} end end end. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 128). -spec from_string(binary()) -> {ok, tempo:date_time()} | {error, tempo:error()}. from_string(Datetime) -> Split_dt = case gleam_stdlib:contains_string(Datetime, <<"T"/utf8>>) of true -> gleam@string:split(Datetime, <<"T"/utf8>>); false -> gleam@string:split(Datetime, <<" "/utf8>>) end, case Split_dt of [Date, Time] -> gleam@result:'try'( tempo@date:from_string(Date), fun(Date@1) -> gleam@result:'try'( split_time_and_offset(Time), fun(_use0) -> {Time@1, Offset} = _use0, gleam@result:'try'( tempo@time:from_string(Time@1), fun(Time@2) -> gleam@result:map( tempo@offset:from_string(Offset), fun(Offset@1) -> new(Date@1, Time@2, Offset@1) end ) end ) end ) end ); [Date@2] -> _pipe = tempo@date:from_string(Date@2), gleam@result:map( _pipe, fun(_capture) -> new(_capture, {time, 0, 0, 0, 0}, {offset, 0}) end ); _ -> {error, date_time_invalid_format} end. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 49). -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>>, module => <<"tempo/datetime"/utf8>>, function => <<"literal"/utf8>>, line => 53}); {error, date_out_of_bounds} -> erlang:error(#{gleam_error => panic, message => <<"Invalid date in datetime literal value"/utf8>>, module => <<"tempo/datetime"/utf8>>, function => <<"literal"/utf8>>, line => 55}); {error, time_out_of_bounds} -> erlang:error(#{gleam_error => panic, message => <<"Invalid time indatetime literal value"/utf8>>, module => <<"tempo/datetime"/utf8>>, function => <<"literal"/utf8>>, line => 57}); {error, _} -> erlang:error(#{gleam_error => panic, message => <<"Invalid datetime literal"/utf8>>, module => <<"tempo/datetime"/utf8>>, function => <<"literal"/utf8>>, line => 58}) end. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 184). -spec to_string(tempo:date_time()) -> binary(). to_string(Datetime) -> <<(begin _pipe = erlang:element(2, Datetime), tempo@naive_datetime:to_string(_pipe) end)/binary, (case erlang:element(2, erlang:element(3, Datetime)) of 0 -> <<"Z"/utf8>>; _ -> _pipe@1 = erlang:element(3, Datetime), tempo@offset:to_string(_pipe@1) end)/binary>>. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 224). -spec parse(binary(), binary()) -> {ok, tempo:date_time()} | {error, tempo:error()}. parse(Str, Fmt) -> gleam@result:'try'( tempo:consume_format(Str, Fmt), fun(_use0) -> {Parts, _} = _use0, gleam@result:'try'( tempo:find_date(Parts), fun(Date) -> gleam@result:'try'( tempo:find_time(Parts), fun(Time) -> gleam@result:'try'( tempo:find_offset(Parts), fun(Offset) -> {ok, new(Date, Time, Offset)} end ) end ) end ) end ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 251). -spec parse_any(binary()) -> {ok, tempo:date_time()} | {error, tempo:error()}. parse_any(Str) -> case tempo:parse_any(Str) of {ok, {{some, Date}, {some, Time}, {some, Offset}}} -> {ok, new(Date, Time, Offset)}; {ok, {_, _, none}} -> {error, parse_missing_offset}; {ok, {_, none, _}} -> {error, parse_missing_time}; {ok, {none, _, _}} -> {error, parse_missing_date}; {error, Err} -> {error, Err} end. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 362). -spec from_unix_utc(integer()) -> tempo:date_time(). from_unix_utc(Unix_ts) -> new( tempo@date:from_unix_utc(Unix_ts), tempo@time:from_unix_utc(Unix_ts), {offset, 0} ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 390). -spec from_unix_milli_utc(integer()) -> tempo:date_time(). from_unix_milli_utc(Unix_ts) -> new( tempo@date:from_unix_milli_utc(Unix_ts), tempo@time:from_unix_milli_utc(Unix_ts), {offset, 0} ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 422). -spec from_unix_micro_utc(integer()) -> tempo:date_time(). from_unix_micro_utc(Unix_ts) -> new( tempo@date:from_unix_micro_utc(Unix_ts), tempo@time:from_unix_micro_utc(Unix_ts), {offset, 0} ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 468). -spec from_dynamic_string(gleam@dynamic:dynamic_()) -> {ok, tempo:date_time()} | {error, list(gleam@dynamic:decode_error())}. from_dynamic_string(Dynamic_string) -> gleam@result:'try'( gleam@dynamic:string(Dynamic_string), fun(Dt) -> case from_string(Dt) of {ok, Datetime} -> {ok, Datetime}; {error, Tempo_error} -> {error, [{decode_error, <<"tempo.DateTime"/utf8>>, <<(case Tempo_error of date_time_invalid_format -> <<"Invalid format: "/utf8>>; naive_date_time_invalid_format -> <<"Invalid format: "/utf8>>; date_invalid_format -> <<"Invalid format: "/utf8>>; time_invalid_format -> <<"Invalid format: "/utf8>>; offset_invalid_format -> <<"Invalid format: "/utf8>>; date_out_of_bounds -> <<"Date out of bounds: "/utf8>>; month_out_of_bounds -> <<"Month out of bounds: "/utf8>>; time_out_of_bounds -> <<"Time out of bounds: "/utf8>>; offset_out_of_bounds -> <<"Offset out of bounds: "/utf8>>; _ -> <<""/utf8>> end)/binary, Dt/binary>>, []}]} end end ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 520). -spec from_dynamic_unix_utc(gleam@dynamic:dynamic_()) -> {ok, tempo:date_time()} | {error, list(gleam@dynamic:decode_error())}. from_dynamic_unix_utc(Dynamic_ts) -> gleam@result:map( gleam@dynamic:int(Dynamic_ts), fun(Dt) -> from_unix_utc(Dt) end ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 550). -spec from_dynamic_unix_milli_utc(gleam@dynamic:dynamic_()) -> {ok, tempo:date_time()} | {error, list(gleam@dynamic:decode_error())}. from_dynamic_unix_milli_utc(Dynamic_ts) -> gleam@result:map( gleam@dynamic:int(Dynamic_ts), fun(Dt) -> from_unix_milli_utc(Dt) end ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 580). -spec from_dynamic_unix_micro_utc(gleam@dynamic:dynamic_()) -> {ok, tempo:date_time()} | {error, list(gleam@dynamic:decode_error())}. from_dynamic_unix_micro_utc(Dynamic_ts) -> gleam@result:map( gleam@dynamic:int(Dynamic_ts), fun(Dt) -> from_unix_micro_utc(Dt) end ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 597). -spec get_date(tempo:date_time()) -> tempo:date(). get_date(Datetime) -> erlang:element(2, erlang:element(2, Datetime)). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 610). -spec get_time(tempo:date_time()) -> tempo:time(). get_time(Datetime) -> erlang:element(3, erlang:element(2, Datetime)). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 623). -spec get_offset(tempo:date_time()) -> tempo:offset(). get_offset(Datetime) -> erlang:element(3, Datetime). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 330). -spec replace_format(binary(), tempo:date_time()) -> binary(). replace_format(Content, Datetime) -> case Content of <<"z"/utf8>> -> case begin _pipe = Datetime, get_offset(_pipe) end of {offset, 0} -> <<"Z"/utf8>>; Offset -> Str_offset = begin _pipe@1 = Offset, tempo@offset:to_string(_pipe@1) end, case begin _pipe@2 = Str_offset, gleam@string:split(_pipe@2, <<":"/utf8>>) end of [Hours, <<"00"/utf8>>] -> Hours; _ -> Str_offset end end; <<"Z"/utf8>> -> _pipe@3 = Datetime, _pipe@4 = get_offset(_pipe@3), tempo@offset:to_string(_pipe@4); <<"ZZ"/utf8>> -> _pipe@5 = Datetime, _pipe@6 = get_offset(_pipe@5), _pipe@7 = tempo@offset:to_string(_pipe@6), gleam@string:replace(_pipe@7, <<":"/utf8>>, <<""/utf8>>); _ -> Content end. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 303). -spec format(tempo:date_time(), binary()) -> binary(). format(Datetime, Fmt) -> _assert_subject = gleam@regex:from_string( <<"\\[([^\\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|z|SSSSS|SSSS|SSS|."/utf8>> ), {ok, Re} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"tempo/datetime"/utf8>>, function => <<"format"/utf8>>, line => 304}) end, _pipe = gleam@regex:scan(Re, Fmt), _pipe@1 = lists:reverse(_pipe), _pipe@7 = gleam@list:fold(_pipe@1, [], fun(Acc, Match) -> case Match of {match, Content, []} -> [begin _pipe@2 = Content, _pipe@4 = tempo@date:replace_format( _pipe@2, begin _pipe@3 = Datetime, get_date(_pipe@3) end ), _pipe@6 = tempo@time:replace_format( _pipe@4, begin _pipe@5 = Datetime, get_time(_pipe@5) end ), replace_format(_pipe@6, Datetime) end | Acc]; {match, _, [{some, Sub}]} -> [Sub | Acc]; {match, Content@1, _} -> [Content@1 | Acc] end end), gleam@string:join(_pipe@7, <<""/utf8>>). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 636). -spec drop_offset(tempo:date_time()) -> tempo:naive_date_time(). drop_offset(Datetime) -> erlang:element(2, Datetime). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 649). -spec drop_time(tempo:date_time()) -> tempo:date_time(). drop_time(Datetime) -> {date_time, tempo@naive_datetime:drop_time(erlang:element(2, Datetime)), erlang:element(3, Datetime)}. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 837). -spec to_second_precision(tempo:date_time()) -> tempo:date_time(). to_second_precision(Datetime) -> new( erlang:element(2, erlang:element(2, Datetime)), begin _pipe = erlang:element(3, erlang:element(2, Datetime)), tempo@time:to_second_precision(_pipe) end, erlang:element(3, Datetime) ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 856). -spec to_milli_precision(tempo:date_time()) -> tempo:date_time(). to_milli_precision(Datetime) -> new( erlang:element(2, erlang:element(2, Datetime)), begin _pipe = erlang:element(3, erlang:element(2, Datetime)), tempo@time:to_milli_precision(_pipe) end, erlang:element(3, Datetime) ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 875). -spec to_micro_precision(tempo:date_time()) -> tempo:date_time(). to_micro_precision(Datetime) -> new( erlang:element(2, erlang:element(2, Datetime)), begin _pipe = erlang:element(3, erlang:element(2, Datetime)), tempo@time:to_micro_precision(_pipe) end, erlang:element(3, Datetime) ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 894). -spec to_nano_precision(tempo:date_time()) -> tempo:date_time(). to_nano_precision(Datetime) -> new( erlang:element(2, erlang:element(2, Datetime)), begin _pipe = erlang:element(3, erlang:element(2, Datetime)), tempo@time:to_nano_precision(_pipe) end, erlang:element(3, Datetime) ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 1108). -spec add(tempo:date_time(), tempo:duration()) -> tempo:date_time(). add(Datetime, Duration_to_add) -> _pipe = Datetime, _pipe@1 = drop_offset(_pipe), _pipe@2 = tempo@naive_datetime:add(_pipe@1, Duration_to_add), tempo@naive_datetime:set_offset(_pipe@2, erlang:element(3, Datetime)). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 667). -spec apply_offset(tempo:date_time()) -> tempo:naive_date_time(). apply_offset(Datetime) -> _pipe = Datetime, _pipe@1 = add(_pipe, tempo@offset:to_duration(erlang:element(3, Datetime))), drop_offset(_pipe@1). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 375). -spec to_unix_utc(tempo:date_time()) -> integer(). to_unix_utc(Datetime) -> Utc_dt = begin _pipe = Datetime, apply_offset(_pipe) end, tempo@date:to_unix_utc(erlang:element(2, Utc_dt)) + (tempo@time:to_nanoseconds( erlang:element(3, Utc_dt) ) div 1000000000). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 407). -spec to_unix_milli_utc(tempo:date_time()) -> integer(). to_unix_milli_utc(Datetime) -> Utc_dt = begin _pipe = Datetime, apply_offset(_pipe) end, tempo@date:to_unix_milli_utc(erlang:element(2, Utc_dt)) + (tempo@time:to_nanoseconds( erlang:element(3, Utc_dt) ) div 1000000). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 439). -spec to_unix_micro_utc(tempo:date_time()) -> integer(). to_unix_micro_utc(Datetime) -> Utc_dt = begin _pipe = Datetime, apply_offset(_pipe) end, tempo@date:to_unix_micro_utc(erlang:element(2, Utc_dt)) + (tempo@time:to_nanoseconds( erlang:element(3, Utc_dt) ) div 1000). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 682). -spec to_utc(tempo:date_time()) -> tempo:date_time(). to_utc(Datetime) -> _pipe = Datetime, _pipe@1 = add(_pipe, tempo@offset:to_duration(erlang:element(3, Datetime))), _pipe@2 = drop_offset(_pipe@1), tempo@naive_datetime:set_offset(_pipe@2, {offset, 0}). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 923). -spec compare(tempo:date_time(), tempo:date_time()) -> gleam@order:order(). compare(A, B) -> _pipe = apply_offset(A), tempo@naive_datetime:compare(_pipe, apply_offset(B)). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 946). -spec is_earlier(tempo:date_time(), tempo:date_time()) -> boolean(). is_earlier(A, B) -> compare(A, B) =:= lt. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 968). -spec is_earlier_or_equal(tempo:date_time(), tempo:date_time()) -> boolean(). is_earlier_or_equal(A, B) -> (compare(A, B) =:= lt) orelse (compare(A, B) =:= eq). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 990). -spec is_equal(tempo:date_time(), tempo:date_time()) -> boolean(). is_equal(A, B) -> compare(A, B) =:= eq. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 1013). -spec is_later(tempo:date_time(), tempo:date_time()) -> boolean(). is_later(A, B) -> compare(A, B) =:= gt. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 1035). -spec is_later_or_equal(tempo:date_time(), tempo:date_time()) -> boolean(). is_later_or_equal(A, B) -> (compare(A, B) =:= gt) orelse (compare(A, B) =:= eq). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 1087). -spec as_period(tempo:date_time(), tempo:date_time()) -> tempo:period(). as_period(Start, End) -> {Start@1, End@1} = case begin _pipe = Start, is_earlier_or_equal(_pipe, End) end of true -> {Start, End}; false -> {End, Start} end, {period, Start@1, End@1}. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 1061). -spec difference(tempo:date_time(), tempo:date_time()) -> tempo:period(). difference(A, B) -> as_period(A, B). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 1127). -spec subtract(tempo:date_time(), tempo:duration()) -> tempo:date_time(). subtract(Datetime, Duration_to_subtract) -> _pipe = Datetime, _pipe@1 = drop_offset(_pipe), _pipe@2 = tempo@naive_datetime:subtract(_pipe@1, Duration_to_subtract), tempo@naive_datetime:set_offset(_pipe@2, erlang:element(3, Datetime)). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 698). -spec to_offset(tempo:date_time(), tempo:offset()) -> tempo:date_time(). to_offset(Datetime, Offset) -> _pipe = Datetime, _pipe@1 = to_utc(_pipe), _pipe@2 = subtract(_pipe@1, tempo@offset:to_duration(Offset)), _pipe@3 = drop_offset(_pipe@2), tempo@naive_datetime:set_offset(_pipe@3, Offset). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 737). -spec to_local(tempo:date_time()) -> tempo:uncertain_conversion(tempo:date_time()). to_local(Datetime) -> gleam@bool:lazy_guard( erlang:element(3, Datetime) =:= tempo@offset:local(), fun() -> {precise, Datetime} end, fun() -> Local_dt = begin _pipe = Datetime, to_offset(_pipe, tempo@offset:local()) end, case erlang:element(2, erlang:element(2, Local_dt)) =:= tempo@date:current_local( ) of true -> {precise, Local_dt}; false -> {imprecise, Local_dt} end end ). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 71). -spec now_local() -> tempo:date_time(). now_local() -> case begin _pipe = now_utc(), to_local(_pipe) end of {precise, Datetime} -> Datetime; {imprecise, Datetime@1} -> Datetime@1 end. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 108). -spec now_text() -> binary(). now_text() -> _pipe = now_local(), _pipe@1 = drop_offset(_pipe), _pipe@2 = tempo@naive_datetime:to_milli_precision(_pipe@1), _pipe@3 = tempo@naive_datetime:to_string(_pipe@2), gleam@string:replace(_pipe@3, <<"T"/utf8>>, <<" "/utf8>>). -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 780). -spec to_local_time(tempo:date_time()) -> tempo:uncertain_conversion(tempo:time()). to_local_time(Datetime) -> case to_local(Datetime) of {precise, Datetime@1} -> _pipe = erlang:element(3, erlang:element(2, Datetime@1)), {precise, _pipe}; {imprecise, Datetime@2} -> _pipe@1 = erlang:element(3, erlang:element(2, Datetime@2)), {imprecise, _pipe@1} end. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 817). -spec to_local_date(tempo:date_time()) -> tempo:uncertain_conversion(tempo:date()). to_local_date(Datetime) -> case to_local(Datetime) of {precise, Datetime@1} -> _pipe = erlang:element(2, erlang:element(2, Datetime@1)), {precise, _pipe}; {imprecise, Datetime@2} -> _pipe@1 = erlang:element(2, erlang:element(2, Datetime@2)), {imprecise, _pipe@1} end. -file("/home/john/Repos/tempo/src/tempo/datetime.gleam", 1154). -spec time_left_in_day(tempo:date_time()) -> tempo:time(). time_left_in_day(Datetime) -> _pipe = erlang:element(3, erlang:element(2, Datetime)), tempo@time:left_in_day(_pipe).