-module(birl@datetime). -compile(no_auto_import). -export([now/0, to_parts/1, from_parts/2, to_iso/1, from_iso/1, compare/2, difference/2, add/2, subtract/2]). -export_type([date_time/0, date/0, time/0]). -opaque date_time() :: {date_time, integer()}. -type date() :: {date, integer(), integer(), integer()}. -type time() :: {time, integer(), integer(), integer()}. -spec now() -> date_time(). now() -> _pipe = birl_ffi:now(), {date_time, _pipe}. -spec to_parts(date_time()) -> {date(), time()}. to_parts(Value) -> case Value of {date_time, T} -> case birl_ffi:to_parts(T) of {{Year, Month, Day}, {Hour, Minute, Second}} -> {{date, Year, Month, Day}, {time, Hour, Minute, Second}} end end. -spec from_parts(date(), time()) -> date_time(). from_parts(Date, Time) -> String_date = case Date of {date, Year, Month, Day} -> _pipe = [gleam@int:to_string(Year), gleam@int:to_string(Month), gleam@int:to_string(Day)], _pipe@1 = gleam@list:map( _pipe, fun gleam@string_builder:from_string/1 ), gleam@string_builder:join(_pipe@1, <<"-"/utf8>>) end, String_time = case Time of {time, Hour, Minute, Second} -> _pipe@2 = [gleam@int:to_string(Hour), gleam@int:to_string(Minute), gleam@int:to_string(Second)], _pipe@3 = gleam@list:map( _pipe@2, fun gleam@string_builder:from_string/1 ), _pipe@4 = gleam@string_builder:join(_pipe@3, <<":"/utf8>>), gleam@string_builder:append(_pipe@4, <<".000Z"/utf8>>) end, case begin _pipe@5 = gleam@string_builder:join( [String_date, String_time], <<"T"/utf8>> ), _pipe@6 = gleam@string_builder:to_string(_pipe@5), from_iso(_pipe@6) end of {ok, Value} -> Value; {error, nil} -> {date_time, 0} end. -spec to_iso(date_time()) -> binary(). to_iso(Value) -> case Value of {date_time, T} -> birl_ffi:to_iso(T) end. -spec from_iso(binary()) -> {ok, date_time()} | {error, nil}. from_iso(Value) -> case gleam@regex:from_string( <<"\\d{4}-\\d{1,2}-\\d{1,2}T\\d{1,2}:\\d{1,2}:\\d{1,2}.\\d{3}Z"/utf8>> ) of {ok, Pattern} -> case gleam@regex:check(Pattern, Value) of true -> _pipe = Value, _pipe@1 = birl_ffi:from_iso(_pipe), _pipe@2 = {date_time, _pipe@1}, {ok, _pipe@2}; false -> {error, nil} end; {error, _@1} -> {error, nil} end. -spec compare(date_time(), date_time()) -> gleam@order:order(). compare(A, B) -> {date_time, Dta} = A, {date_time, Dtb} = B, case Dta =:= Dtb of true -> eq; false -> case Dta < Dtb of true -> lt; false -> gt end end. -spec difference(date_time(), date_time()) -> birl@duration:duration(). difference(A, B) -> {date_time, Dta} = A, {date_time, Dtb} = B, {duration, Dtb - Dta}. -spec add(date_time(), birl@duration:duration()) -> date_time(). add(Value, Duration) -> {date_time, Timestamp} = Value, {duration, Duration@1} = Duration, {date_time, Timestamp + Duration@1}. -spec subtract(date_time(), birl@duration:duration()) -> date_time(). subtract(Value, Duration) -> {date_time, Timestamp} = Value, {duration, Duration@1} = Duration, {date_time, Timestamp - Duration@1}.