-module(tempo). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([datetime/2, datetime_get_naive/1, datetime_get_offset/1, naive_datetime/2, naive_datetime_get_date/1, naive_datetime_get_time/1, offset/1, offset_get_minutes/1, validate_offset/1, new_offset/1, offset_from_string/1, date/3, date_get_year/1, date_get_month/1, date_get_day/1, time/5, time_get_hour/1, time_get_minute/1, time_get_second/1, time_get_nano/1, time_get_prec/1, validate_time/1, new_time/3, new_time_milli/4, new_time_micro/4, new_time_nano/4, adjust_12_hour_to_24_hour/2, duration/1, duration_get_ns/1, month_from_int/1, month_from_short_string/1, month_from_long_string/1, month_to_int/1, is_leap_year/1, days_of_month/2, date_from_tuple/1, new_date/3, accept_imprecision/1, error_on_imprecision/1, parse_any/1, now_utc/0, now_monotonic/0, find_year/1, find_month/1, find_day/1, find_hour/1, find_minute/1, find_date/1, find_time/1, find_offset/1, consume_format/2]). -export_type([error/0, date_time/0, naive_date_time/0, offset/0, date/0, period/0, time_precision/0, time/0, duration/0, month_year/0, month/0, uncertain_conversion/1, datetime_part/0]). -type error() :: time_invalid_format | time_out_of_bounds | date_invalid_format | date_out_of_bounds | month_invalid_format | month_out_of_bounds | offset_invalid_format | offset_out_of_bounds | naive_date_time_invalid_format | date_time_invalid_format | invalid_input_shape | {unable_to_parse_directive, binary()} | parse_missing_date | parse_missing_time | parse_missing_offset. -opaque date_time() :: {date_time, naive_date_time(), offset()}. -opaque naive_date_time() :: {naive_date_time, date(), time()}. -opaque offset() :: {offset, integer()}. -opaque date() :: {date, integer(), month(), integer()}. -type period() :: {naive_period, naive_date_time(), naive_date_time()} | {period, date_time(), date_time()}. -type time_precision() :: sec | milli | micro | nano. -opaque time() :: {time, integer(), integer(), integer(), integer(), time_precision()}. -opaque duration() :: {duration, integer()}. -type month_year() :: {month_year, month(), integer()}. -type month() :: jan | feb | mar | apr | may | jun | jul | aug | sep | oct | nov | dec. -type uncertain_conversion(FXO) :: {precise, FXO} | {imprecise, FXO}. -type datetime_part() :: {year, integer()} | {month, integer()} | {day, integer()} | {hour, integer()} | {minute, integer()} | {second, integer()} | {millisecond, integer()} | {microsecond, integer()} | {nanosecond, integer()} | {offset_str, binary()} | {twelve_hour, integer()} | am_period | pm_period | passthrough. -file("/home/john/Repos/tempo/src/tempo.gleam", 41). -spec datetime(naive_date_time(), offset()) -> date_time(). datetime(Naive, Offset) -> {date_time, Naive, Offset}. -file("/home/john/Repos/tempo/src/tempo.gleam", 46). -spec datetime_get_naive(date_time()) -> naive_date_time(). datetime_get_naive(Datetime) -> erlang:element(2, Datetime). -file("/home/john/Repos/tempo/src/tempo.gleam", 51). -spec datetime_get_offset(date_time()) -> offset(). datetime_get_offset(Datetime) -> erlang:element(3, Datetime). -file("/home/john/Repos/tempo/src/tempo.gleam", 63). -spec naive_datetime(date(), time()) -> naive_date_time(). naive_datetime(Date, Time) -> {naive_date_time, Date, Time}. -file("/home/john/Repos/tempo/src/tempo.gleam", 68). -spec naive_datetime_get_date(naive_date_time()) -> date(). naive_datetime_get_date(Naive_datetime) -> erlang:element(2, Naive_datetime). -file("/home/john/Repos/tempo/src/tempo.gleam", 73). -spec naive_datetime_get_time(naive_date_time()) -> time(). naive_datetime_get_time(Naive_datetime) -> erlang:element(3, Naive_datetime). -file("/home/john/Repos/tempo/src/tempo.gleam", 84). -spec offset(integer()) -> offset(). offset(Minutes) -> {offset, Minutes}. -file("/home/john/Repos/tempo/src/tempo.gleam", 89). -spec offset_get_minutes(offset()) -> integer(). offset_get_minutes(Offset) -> erlang:element(2, Offset). -file("/home/john/Repos/tempo/src/tempo.gleam", 162). -spec validate_offset(offset()) -> {ok, offset()} | {error, error()}. validate_offset(Offset) -> case (erlang:element(2, Offset) >= -720) andalso (erlang:element(2, Offset) =< 840) of true -> {ok, Offset}; false -> {error, offset_out_of_bounds} end. -file("/home/john/Repos/tempo/src/tempo.gleam", 97). -spec new_offset(integer()) -> {ok, offset()} | {error, error()}. new_offset(Minutes) -> _pipe = {offset, Minutes}, validate_offset(_pipe). -file("/home/john/Repos/tempo/src/tempo.gleam", 102). -spec offset_from_string(binary()) -> {ok, offset()} | {error, error()}. offset_from_string(Offset) -> _pipe = case Offset of <<"Z"/utf8>> -> {ok, {offset, 0}}; <<"z"/utf8>> -> {ok, {offset, 0}}; _ -> gleam@result:'try'(case gleam@string:split(Offset, <<":"/utf8>>) of [Hour, Minute] -> case {gleam@string:length(Hour), gleam@string:length(Minute)} of {3, 2} -> {ok, {gleam@string:slice(Hour, 0, 1), gleam@string:slice(Hour, 1, 2), Minute}}; {_, _} -> {error, offset_invalid_format} end; _ -> case gleam@string:length(Offset) of 5 -> {ok, {gleam@string:slice(Offset, 0, 1), gleam@string:slice(Offset, 1, 2), gleam@string:slice(Offset, 3, 2)}}; 3 -> {ok, {gleam@string:slice(Offset, 0, 1), gleam@string:slice(Offset, 1, 2), <<"0"/utf8>>}}; 2 -> {ok, {gleam@string:slice(Offset, 0, 1), gleam@string:slice(Offset, 1, 1), <<"0"/utf8>>}}; _ -> {error, offset_invalid_format} end end, fun(_use0) -> {Sign, Hour@1, Minute@1} = _use0, case {Sign, gleam@int:parse(Hour@1), gleam@int:parse(Minute@1)} of {_, {ok, 0}, {ok, 0}} -> {ok, {offset, 0}}; {<<"-"/utf8>>, {ok, Hour@2}, {ok, Minute@2}} when (Hour@2 =< 24) andalso (Minute@2 =< 60) -> {ok, {offset, - ((Hour@2 * 60) + Minute@2)}}; {<<"+"/utf8>>, {ok, Hour@3}, {ok, Minute@3}} when (Hour@3 =< 24) andalso (Minute@3 =< 60) -> {ok, {offset, (Hour@3 * 60) + Minute@3}}; {_, _, _} -> {error, offset_invalid_format} end end) end, gleam@result:'try'(_pipe, fun validate_offset/1). -file("/home/john/Repos/tempo/src/tempo.gleam", 177). -spec date(integer(), month(), integer()) -> date(). date(Year, Month, Day) -> {date, Year, Month, Day}. -file("/home/john/Repos/tempo/src/tempo.gleam", 182). -spec date_get_year(date()) -> integer(). date_get_year(Date) -> erlang:element(2, Date). -file("/home/john/Repos/tempo/src/tempo.gleam", 187). -spec date_get_month(date()) -> month(). date_get_month(Date) -> erlang:element(3, Date). -file("/home/john/Repos/tempo/src/tempo.gleam", 192). -spec date_get_day(date()) -> integer(). date_get_day(Date) -> erlang:element(4, Date). -file("/home/john/Repos/tempo/src/tempo.gleam", 258). -spec time(integer(), integer(), integer(), integer(), time_precision()) -> time(). time(Hour, Minute, Second, Nano, Prec) -> {time, Hour, Minute, Second, Nano, Prec}. -file("/home/john/Repos/tempo/src/tempo.gleam", 263). -spec time_get_hour(time()) -> integer(). time_get_hour(Time) -> erlang:element(2, Time). -file("/home/john/Repos/tempo/src/tempo.gleam", 268). -spec time_get_minute(time()) -> integer(). time_get_minute(Time) -> erlang:element(3, Time). -file("/home/john/Repos/tempo/src/tempo.gleam", 273). -spec time_get_second(time()) -> integer(). time_get_second(Time) -> erlang:element(4, Time). -file("/home/john/Repos/tempo/src/tempo.gleam", 278). -spec time_get_nano(time()) -> integer(). time_get_nano(Time) -> erlang:element(5, Time). -file("/home/john/Repos/tempo/src/tempo.gleam", 283). -spec time_get_prec(time()) -> time_precision(). time_get_prec(Time) -> erlang:element(6, Time). -file("/home/john/Repos/tempo/src/tempo.gleam", 324). -spec validate_time(time()) -> {ok, time()} | {error, error()}. validate_time(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, _, _, _, _, sec} -> {ok, Time}; {time, _, _, _, Millis, milli} when Millis =< 999000000 -> {ok, Time}; {time, _, _, _, Micros, micro} when Micros =< 999999000 -> {ok, Time}; {time, _, _, _, Nanos, nano} when Nanos =< 999999999 -> {ok, Time}; _ -> {error, time_out_of_bounds} end; false -> {error, time_out_of_bounds} end. -file("/home/john/Repos/tempo/src/tempo.gleam", 288). -spec new_time(integer(), integer(), integer()) -> {ok, time()} | {error, error()}. new_time(Hour, Minute, Second) -> _pipe = {time, Hour, Minute, Second, 0, sec}, validate_time(_pipe). -file("/home/john/Repos/tempo/src/tempo.gleam", 293). -spec new_time_milli(integer(), integer(), integer(), integer()) -> {ok, time()} | {error, error()}. new_time_milli(Hour, Minute, Second, Millisecond) -> _pipe = {time, Hour, Minute, Second, Millisecond * 1000000, milli}, validate_time(_pipe). -file("/home/john/Repos/tempo/src/tempo.gleam", 304). -spec new_time_micro(integer(), integer(), integer(), integer()) -> {ok, time()} | {error, error()}. new_time_micro(Hour, Minute, Second, Microsecond) -> _pipe = {time, Hour, Minute, Second, Microsecond * 1000, micro}, validate_time(_pipe). -file("/home/john/Repos/tempo/src/tempo.gleam", 314). -spec new_time_nano(integer(), integer(), integer(), integer()) -> {ok, time()} | {error, error()}. new_time_nano(Hour, Minute, Second, Nanosecond) -> _pipe = {time, Hour, Minute, Second, Nanosecond, nano}, validate_time(_pipe). -file("/home/john/Repos/tempo/src/tempo.gleam", 359). -spec adjust_12_hour_to_24_hour(integer(), boolean()) -> integer(). adjust_12_hour_to_24_hour(Hour, Am) -> case {Am, Hour} of {true, _} when Hour =:= 12 -> 0; {true, _} -> Hour; {false, _} when Hour =:= 12 -> Hour; {false, _} -> Hour + 12 end. -file("/home/john/Repos/tempo/src/tempo.gleam", 380). -spec duration(integer()) -> duration(). duration(Nanoseconds) -> {duration, Nanoseconds}. -file("/home/john/Repos/tempo/src/tempo.gleam", 385). -spec duration_get_ns(duration()) -> integer(). duration_get_ns(Duration) -> erlang:element(2, Duration). -file("/home/john/Repos/tempo/src/tempo.gleam", 414). -spec month_from_int(integer()) -> {ok, month()} | {error, error()}. month_from_int(Month) -> case Month of 1 -> {ok, jan}; 2 -> {ok, feb}; 3 -> {ok, mar}; 4 -> {ok, apr}; 5 -> {ok, may}; 6 -> {ok, jun}; 7 -> {ok, jul}; 8 -> {ok, aug}; 9 -> {ok, sep}; 10 -> {ok, oct}; 11 -> {ok, nov}; 12 -> {ok, dec}; _ -> {error, month_out_of_bounds} end. -file("/home/john/Repos/tempo/src/tempo.gleam", 433). -spec month_from_short_string(binary()) -> {ok, month()} | {error, error()}. month_from_short_string(Month) -> case Month of <<"Jan"/utf8>> -> {ok, jan}; <<"Feb"/utf8>> -> {ok, feb}; <<"Mar"/utf8>> -> {ok, mar}; <<"Apr"/utf8>> -> {ok, apr}; <<"May"/utf8>> -> {ok, may}; <<"Jun"/utf8>> -> {ok, jun}; <<"Jul"/utf8>> -> {ok, jul}; <<"Aug"/utf8>> -> {ok, aug}; <<"Sep"/utf8>> -> {ok, sep}; <<"Oct"/utf8>> -> {ok, oct}; <<"Nov"/utf8>> -> {ok, nov}; <<"Dec"/utf8>> -> {ok, dec}; _ -> {error, month_invalid_format} end. -file("/home/john/Repos/tempo/src/tempo.gleam", 452). -spec month_from_long_string(binary()) -> {ok, month()} | {error, error()}. month_from_long_string(Month) -> case Month of <<"January"/utf8>> -> {ok, jan}; <<"February"/utf8>> -> {ok, feb}; <<"March"/utf8>> -> {ok, mar}; <<"April"/utf8>> -> {ok, apr}; <<"May"/utf8>> -> {ok, may}; <<"June"/utf8>> -> {ok, jun}; <<"July"/utf8>> -> {ok, jul}; <<"August"/utf8>> -> {ok, aug}; <<"September"/utf8>> -> {ok, sep}; <<"October"/utf8>> -> {ok, oct}; <<"November"/utf8>> -> {ok, nov}; <<"December"/utf8>> -> {ok, dec}; _ -> {error, month_invalid_format} end. -file("/home/john/Repos/tempo/src/tempo.gleam", 471). -spec month_to_int(month()) -> integer(). month_to_int(Month) -> case Month of jan -> 1; feb -> 2; mar -> 3; apr -> 4; may -> 5; jun -> 6; jul -> 7; aug -> 8; sep -> 9; oct -> 10; nov -> 11; dec -> 12 end. -file("/home/john/Repos/tempo/src/tempo.gleam", 514). -spec is_leap_year(integer()) -> boolean(). is_leap_year(Year) -> case (Year rem 4) =:= 0 of true -> case (Year rem 100) =:= 0 of true -> case (Year rem 400) =:= 0 of true -> true; false -> false end; false -> true end; false -> false end. -file("/home/john/Repos/tempo/src/tempo.gleam", 489). -spec days_of_month(month(), integer()) -> integer(). days_of_month(Month, Year) -> case Month of jan -> 31; mar -> 31; may -> 31; jul -> 31; aug -> 31; oct -> 31; dec -> 31; _ -> case Month of apr -> 30; jun -> 30; sep -> 30; nov -> 30; _ -> case is_leap_year(Year) of true -> 29; false -> 28 end end end. -file("/home/john/Repos/tempo/src/tempo.gleam", 206). -spec date_from_tuple({integer(), integer(), integer()}) -> {ok, date()} | {error, error()}. date_from_tuple(Date) -> Year = erlang:element(1, Date), Month = erlang:element(2, Date), Day = erlang:element(3, Date), gleam@result:'try'( month_from_int(Month), fun(Month@1) -> case (Year >= 1000) andalso (Year =< 9999) of true -> case (Day >= 1) andalso (Day =< days_of_month(Month@1, Year)) of true -> {ok, {date, Year, Month@1, Day}}; false -> {error, date_out_of_bounds} end; false -> {error, date_out_of_bounds} end end ). -file("/home/john/Repos/tempo/src/tempo.gleam", 197). -spec new_date(integer(), integer(), integer()) -> {ok, date()} | {error, error()}. new_date(Year, Month, Day) -> date_from_tuple({Year, Month, Day}). -file("/home/john/Repos/tempo/src/tempo.gleam", 560). -spec accept_imprecision(uncertain_conversion(FZV)) -> FZV. accept_imprecision(Conv) -> case Conv of {precise, A} -> A; {imprecise, A@1} -> A@1 end. -file("/home/john/Repos/tempo/src/tempo.gleam", 578). -spec error_on_imprecision(uncertain_conversion(FZX)) -> {ok, FZX} | {error, nil}. error_on_imprecision(Conv) -> case Conv of {precise, A} -> {ok, A}; {imprecise, _} -> {error, nil} end. -file("/home/john/Repos/tempo/src/tempo.gleam", 627). -spec parse_any(binary()) -> {ok, {gleam@option:option(date()), gleam@option:option(time()), gleam@option:option(offset())}} | {error, error()}. parse_any(Str) -> gleam@result:'try'( begin _pipe = gleam@regex:from_string(<<"\\d{9,}"/utf8>>), gleam@result:replace_error(_pipe, invalid_input_shape) end, fun(Serial_re) -> gleam@bool:guard( gleam@regex:check(Serial_re, Str), {error, invalid_input_shape}, fun() -> gleam@result:'try'( begin _pipe@1 = gleam@regex:from_string( <<"(\\d{4})[-_/\\.\\s,]{0,2}(\\d{2})[-_/\\.\\s,]{0,2}(\\d{2})"/utf8>> ), gleam@result:replace_error( _pipe@1, invalid_input_shape ) end, fun(Date_re) -> gleam@result:'try'( begin _pipe@2 = gleam@regex:from_string( <<"(\\d{2}|January|Jan|january|jan|February|Feb|february|feb|March|Mar|march|mar|April|Apr|april|apr|May|may|June|Jun|june|jun|July|Jul|july|jul|August|Aug|august|aug|September|Sep|september|sep|October|Oct|october|oct|November|Nov|november|nov|December|Dec|december|dec)[-_/\\.\\s,]{0,2}(\\d{2})[-_/\\.\\s,]{0,2}(\\d{4})"/utf8>> ), gleam@result:replace_error( _pipe@2, invalid_input_shape ) end, fun(Date_human_re) -> gleam@result:'try'( begin _pipe@3 = gleam@regex:from_string( <<"(\\d{1,2})[:_\\.\\s]{0,1}(\\d{1,2})[:_\\.\\s]{0,1}(\\d{0,2})[\\.]{0,1}(\\d{0,9})\\s*(AM|PM|am|pm)?"/utf8>> ), gleam@result:replace_error( _pipe@3, invalid_input_shape ) end, fun(Time_re) -> gleam@result:'try'( begin _pipe@4 = gleam@regex:from_string( <<"([-+]\\d{2}):{0,1}(\\d{1,2})?"/utf8>> ), gleam@result:replace_error( _pipe@4, invalid_input_shape ) end, fun(Offset_re) -> Unconsumed = Str, {Date@1, Unconsumed@1} = (case gleam@regex:scan( Date_re, Unconsumed ) of [{match, Content, [{some, Year}, {some, Month}, {some, Day}]} | _] -> case {gleam@int:parse( Year ), gleam@int:parse( Month ), gleam@int:parse( Day )} of {{ok, Year@1}, {ok, Month@1}, {ok, Day@1}} -> case new_date( Year@1, Month@1, Day@1 ) of {ok, Date} -> {{some, Date}, gleam@string:replace( Unconsumed, Content, <<""/utf8>> )}; _ -> {none, Unconsumed} end; {_, _, _} -> {none, Unconsumed} end; _ -> {none, Unconsumed} end), {Date@3, Unconsumed@2} = (case Date@1 of {some, D} -> {{some, D}, Unconsumed@1}; none -> case gleam@regex:scan( Date_human_re, Unconsumed@1 ) of [{match, Content@1, [{some, Month@2}, {some, Day@2}, {some, Year@2}]} | _] -> case {gleam@int:parse( Year@2 ), begin _pipe@5 = gleam@int:parse( Month@2 ), _pipe@6 = gleam@result:replace_error( _pipe@5, month_invalid_format ), _pipe@7 = gleam@result:'try'( _pipe@6, fun month_from_int/1 ), gleam@result:try_recover( _pipe@7, fun( _ ) -> _pipe@8 = month_from_short_string( Month@2 ), gleam@result:try_recover( _pipe@8, fun( _ ) -> month_from_long_string( Month@2 ) end ) end ) end, gleam@int:parse( Day@2 )} of {{ok, Year@3}, {ok, Month@3}, {ok, Day@3}} -> case new_date( Year@3, month_to_int( Month@3 ), Day@3 ) of {ok, Date@2} -> {{some, Date@2}, gleam@string:replace( Unconsumed@1, Content@1, <<""/utf8>> )}; _ -> {none, Unconsumed@1} end; {_, _, _} -> {none, Unconsumed@1} end; _ -> {none, Unconsumed@1} end end), {Offset@1, Unconsumed@3} = (case gleam@regex:scan( Offset_re, Unconsumed@2 ) of [{match, Content@2, [{some, Hours}, {some, Minutes}]} | _] -> case {gleam@int:parse( Hours ), gleam@int:parse( Minutes )} of {{ok, Hour}, {ok, Minute}} -> case new_offset( (Hour * 60) + Minute ) of {ok, Offset} -> {{some, Offset}, gleam@string:replace( Unconsumed@2, Content@2, <<""/utf8>> )}; _ -> {none, Unconsumed@2} end; {_, _} -> {none, Unconsumed@2} end; _ -> {none, Unconsumed@2} end), {Time, _} = begin Scan_results = gleam@regex:scan( Time_re, Unconsumed@3 ), Adj_hour = case Scan_results of [{match, _, [_, _, _, _, {some, <<"PM"/utf8>>}]} | _] -> fun(_capture) -> adjust_12_hour_to_24_hour( _capture, false ) end; [{match, _, [_, _, _, _, {some, <<"pm"/utf8>>}]} | _] -> fun(_capture@1) -> adjust_12_hour_to_24_hour( _capture@1, false ) end; [{match, _, [_, _, _, _, {some, <<"AM"/utf8>>}]} | _] -> fun(_capture@2) -> adjust_12_hour_to_24_hour( _capture@2, true ) end; [{match, _, [_, _, _, _, {some, <<"am"/utf8>>}]} | _] -> fun(_capture@3) -> adjust_12_hour_to_24_hour( _capture@3, true ) end; _ -> fun(Hour@1) -> Hour@1 end end, case Scan_results of [{match, Content@3, [{some, H}, {some, M}, none, none | _]} | _] -> case {gleam@int:parse( H ), gleam@int:parse( M )} of {{ok, Hour@2}, {ok, Minute@1}} -> case begin _pipe@9 = Adj_hour( Hour@2 ), new_time( _pipe@9, Minute@1, 0 ) end of {ok, Date@4} -> {{some, Date@4}, gleam@string:replace( Unconsumed@3, Content@3, <<""/utf8>> )}; _ -> {none, Unconsumed@3} end; {_, _} -> {none, Unconsumed@3} end; [{match, Content@4, [{some, H@1}, {some, M@1}, {some, S}, none | _]} | _] -> case {gleam@int:parse( H@1 ), gleam@int:parse( M@1 ), gleam@int:parse( S )} of {{ok, Hour@3}, {ok, Minute@2}, {ok, Second}} -> case begin _pipe@10 = Adj_hour( Hour@3 ), new_time( _pipe@10, Minute@2, Second ) end of {ok, Date@5} -> {{some, Date@5}, gleam@string:replace( Unconsumed@3, Content@4, <<""/utf8>> )}; _ -> {none, Unconsumed@3} end; {_, _, _} -> {none, Unconsumed@3} end; [{match, Content@5, [{some, H@2}, {some, M@2}, {some, S@1}, {some, D@1} | _]} | _] -> case {gleam@int:parse( H@2 ), gleam@int:parse( M@2 ), gleam@int:parse( S@1 )} of {{ok, Hour@4}, {ok, Minute@3}, {ok, Second@1}} -> case {gleam@string:length( D@1 ), gleam@int:parse( D@1 )} of {3, {ok, Milli}} -> case begin _pipe@11 = Adj_hour( Hour@4 ), new_time_milli( _pipe@11, Minute@3, Second@1, Milli ) end of {ok, Date@6} -> {{some, Date@6}, gleam@string:replace( Unconsumed@3, Content@5, <<""/utf8>> )}; _ -> {none, Unconsumed@3} end; {6, {ok, Micro}} -> case begin _pipe@12 = Adj_hour( Hour@4 ), new_time_micro( _pipe@12, Minute@3, Second@1, Micro ) end of {ok, Date@7} -> {{some, Date@7}, gleam@string:replace( Unconsumed@3, Content@5, <<""/utf8>> )}; _ -> {none, Unconsumed@3} end; {9, {ok, Nano}} -> case begin _pipe@13 = Adj_hour( Hour@4 ), new_time_nano( _pipe@13, Minute@3, Second@1, Nano ) end of {ok, Date@8} -> {{some, Date@8}, gleam@string:replace( Unconsumed@3, Content@5, <<""/utf8>> )}; _ -> {none, Unconsumed@3} end; {_, _} -> {none, Unconsumed@3} end; {_, _, _} -> {none, Unconsumed@3} end; _ -> {none, Unconsumed@3} end end, {ok, {Date@3, Time, Offset@1}} end ) end ) end ) end ) end ) end ). -file("/home/john/Repos/tempo/src/tempo.gleam", 842). -spec now_utc() -> integer(). now_utc() -> tempo_ffi:now(). -file("/home/john/Repos/tempo/src/tempo.gleam", 846). -spec now_monotonic() -> integer(). now_monotonic() -> tempo_ffi:now_monotonic(). -file("/home/john/Repos/tempo/src/tempo.gleam", 1106). -spec consume_one_or_two_digits(binary(), fun((integer()) -> GQA)) -> {ok, {GQA, binary()}} | {error, nil}. consume_one_or_two_digits(Str, Constructor) -> case begin _pipe = gleam@string:slice(Str, 0, 2), gleam@int:parse(_pipe) end of {ok, Val} -> {ok, {Constructor(Val), gleam@string:drop_left(Str, 2)}}; {error, _} -> case begin _pipe@1 = gleam@string:slice(Str, 0, 1), gleam@int:parse(_pipe@1) end of {ok, Val@1} -> {ok, {Constructor(Val@1), gleam@string:drop_left(Str, 1)}}; {error, _} -> {error, nil} end end. -file("/home/john/Repos/tempo/src/tempo.gleam", 1117). -spec consume_two_digits(binary(), fun((integer()) -> GQT)) -> {ok, {GQT, binary()}} | {error, nil}. consume_two_digits(Str, Constructor) -> gleam@result:map( begin _pipe = gleam@string:slice(Str, 0, 2), gleam@int:parse(_pipe) end, fun(Val) -> {Constructor(Val), gleam@string:drop_left(Str, 2)} end ). -file("/home/john/Repos/tempo/src/tempo.gleam", 1124). -spec find_year(list(datetime_part())) -> {ok, integer()} | {error, error()}. find_year(Parts) -> _pipe = gleam@list:find_map(Parts, fun(P) -> case P of {year, Y} -> {ok, Y}; _ -> {error, nil} end end), gleam@result:replace_error(_pipe, parse_missing_date). -file("/home/john/Repos/tempo/src/tempo.gleam", 1135). -spec find_month(list(datetime_part())) -> {ok, integer()} | {error, error()}. find_month(Parts) -> _pipe = gleam@list:find_map(Parts, fun(P) -> case P of {month, M} -> {ok, M}; _ -> {error, nil} end end), gleam@result:replace_error(_pipe, parse_missing_date). -file("/home/john/Repos/tempo/src/tempo.gleam", 1146). -spec find_day(list(datetime_part())) -> {ok, integer()} | {error, error()}. find_day(Parts) -> _pipe = gleam@list:find_map(Parts, fun(P) -> case P of {day, D} -> {ok, D}; _ -> {error, nil} end end), gleam@result:replace_error(_pipe, parse_missing_date). -file("/home/john/Repos/tempo/src/tempo.gleam", 1157). -spec find_hour(list(datetime_part())) -> {ok, integer()} | {error, error()}. find_hour(Parts) -> gleam@result:try_recover( begin _pipe = gleam@list:find_map(Parts, fun(P) -> case P of {hour, H} -> {ok, H}; _ -> {error, nil} end end), gleam@result:replace_error(_pipe, parse_missing_time) end, fun(_) -> gleam@result:'try'( begin _pipe@1 = gleam@list:find_map(Parts, fun(P@1) -> case P@1 of {twelve_hour, O} -> {ok, O}; _ -> {error, nil} end end), gleam@result:replace_error(_pipe@1, parse_missing_time) end, fun(Twelve_hour) -> Am_period = gleam@list:find_map( Parts, fun(P@2) -> case P@2 of am_period -> {ok, nil}; _ -> {error, nil} end end ), Pm_period = gleam@list:find_map( Parts, fun(P@3) -> case P@3 of pm_period -> {ok, nil}; _ -> {error, nil} end end ), case {Am_period, Pm_period} of {{ok, nil}, {error, nil}} -> _pipe@2 = adjust_12_hour_to_24_hour( Twelve_hour, true ), {ok, _pipe@2}; {{error, nil}, {ok, nil}} -> _pipe@3 = adjust_12_hour_to_24_hour( Twelve_hour, false ), {ok, _pipe@3}; {_, _} -> {error, parse_missing_time} end end ) end ). -file("/home/john/Repos/tempo/src/tempo.gleam", 1205). -spec find_minute(list(datetime_part())) -> {ok, integer()} | {error, error()}. find_minute(Parts) -> _pipe = gleam@list:find_map(Parts, fun(P) -> case P of {minute, M} -> {ok, M}; _ -> {error, nil} end end), gleam@result:replace_error(_pipe, parse_missing_time). -file("/home/john/Repos/tempo/src/tempo.gleam", 1216). -spec find_date(list(datetime_part())) -> {ok, date()} | {error, error()}. find_date(Parts) -> gleam@result:'try'( begin _pipe = gleam@list:find_map(Parts, fun(P) -> case P of {year, Y} -> {ok, Y}; _ -> {error, nil} end end), gleam@result:replace_error(_pipe, parse_missing_date) end, fun(Year) -> gleam@result:'try'( begin _pipe@1 = gleam@list:find_map(Parts, fun(P@1) -> case P@1 of {month, M} -> {ok, M}; _ -> {error, nil} end end), gleam@result:replace_error(_pipe@1, parse_missing_date) end, fun(Month) -> gleam@result:'try'( begin _pipe@2 = gleam@list:find_map( Parts, fun(P@2) -> case P@2 of {day, D} -> {ok, D}; _ -> {error, nil} end end ), gleam@result:replace_error( _pipe@2, parse_missing_date ) end, fun(Day) -> new_date(Year, Month, Day) end ) end ) end ). -file("/home/john/Repos/tempo/src/tempo.gleam", 1251). -spec find_time(list(datetime_part())) -> {ok, time()} | {error, error()}. find_time(Parts) -> gleam@result:'try'( (gleam@result:try_recover( begin _pipe = gleam@list:find_map(Parts, fun(P) -> case P of {hour, H} -> {ok, H}; _ -> {error, nil} end end), gleam@result:replace_error(_pipe, parse_missing_time) end, fun(_) -> gleam@result:'try'( begin _pipe@1 = gleam@list:find_map( Parts, fun(P@1) -> case P@1 of {twelve_hour, O} -> {ok, O}; _ -> {error, nil} end end ), gleam@result:replace_error(_pipe@1, parse_missing_time) end, fun(Twelve_hour) -> Am_period = gleam@list:find_map( Parts, fun(P@2) -> case P@2 of am_period -> {ok, nil}; _ -> {error, nil} end end ), Pm_period = gleam@list:find_map( Parts, fun(P@3) -> case P@3 of pm_period -> {ok, nil}; _ -> {error, nil} end end ), case {Am_period, Pm_period} of {{ok, nil}, {error, nil}} -> _pipe@2 = adjust_12_hour_to_24_hour( Twelve_hour, true ), {ok, _pipe@2}; {{error, nil}, {ok, nil}} -> _pipe@3 = adjust_12_hour_to_24_hour( Twelve_hour, false ), {ok, _pipe@3}; {_, _} -> {error, parse_missing_time} end end ) end )), fun(Hour) -> gleam@result:'try'( begin _pipe@4 = gleam@list:find_map(Parts, fun(P@4) -> case P@4 of {minute, M} -> {ok, M}; _ -> {error, nil} end end), gleam@result:replace_error(_pipe@4, parse_missing_time) end, fun(Minute) -> Second = begin _pipe@5 = gleam@list:find_map( Parts, fun(P@5) -> case P@5 of {second, S} -> {ok, S}; _ -> {error, nil} end end ), gleam@result:unwrap(_pipe@5, 0) end, Millisecond = gleam@list:find_map( Parts, fun(P@6) -> case P@6 of {millisecond, N} -> {ok, N}; _ -> {error, nil} end end ), Microsecond = gleam@list:find_map( Parts, fun(P@7) -> case P@7 of {microsecond, N@1} -> {ok, N@1}; _ -> {error, nil} end end ), Nanosecond = gleam@list:find_map( Parts, fun(P@8) -> case P@8 of {nanosecond, N@2} -> {ok, N@2}; _ -> {error, nil} end end ), case {Nanosecond, Microsecond, Millisecond} of {{ok, Nano}, _, _} -> new_time_nano(Hour, Minute, Second, Nano); {_, {ok, Micro}, _} -> new_time_micro(Hour, Minute, Second, Micro); {_, _, {ok, Milli}} -> new_time_milli(Hour, Minute, Second, Milli); {_, _, _} -> new_time(Hour, Minute, Second) end end ) end ). -file("/home/john/Repos/tempo/src/tempo.gleam", 1351). -spec find_offset(list(datetime_part())) -> {ok, offset()} | {error, error()}. find_offset(Parts) -> gleam@result:'try'( begin _pipe = gleam@list:find_map(Parts, fun(P) -> case P of {offset_str, O} -> {ok, O}; _ -> {error, nil} end end), gleam@result:replace_error(_pipe, parse_missing_offset) end, fun(Offset_str) -> offset_from_string(Offset_str) end ). -file("/home/john/Repos/tempo/src/tempo.gleam", 903). -spec consume_part(binary(), binary()) -> {ok, {datetime_part(), binary()}} | {error, error()}. consume_part(Fmt, Str) -> _pipe@16 = case Fmt of <<"YY"/utf8>> -> gleam@result:map( begin _pipe = gleam@string:slice(Str, 0, 2), gleam@int:parse(_pipe) end, fun(Val) -> Current_year = tempo_ffi:current_year(), Current_century = (Current_year div 100) * 100, Current_two_year_date = Current_year rem 100, case Val > Current_two_year_date of true -> {{year, (Current_century - 100) + Val}, gleam@string:drop_left(Str, 2)}; false -> {{year, Current_century + Val}, gleam@string:drop_left(Str, 2)} end end ); <<"YYYY"/utf8>> -> gleam@result:map( begin _pipe@1 = gleam@string:slice(Str, 0, 4), gleam@int:parse(_pipe@1) end, fun(Year) -> {{year, Year}, gleam@string:drop_left(Str, 4)} end ); <<"M"/utf8>> -> consume_one_or_two_digits(Str, fun(Field@0) -> {month, Field@0} end); <<"MM"/utf8>> -> consume_two_digits(Str, fun(Field@0) -> {month, Field@0} end); <<"MMM"/utf8>> -> case Str of <<"Jan"/utf8, Rest/binary>> -> {ok, {{month, 1}, Rest}}; <<"Feb"/utf8, Rest@1/binary>> -> {ok, {{month, 2}, Rest@1}}; <<"Mar"/utf8, Rest@2/binary>> -> {ok, {{month, 3}, Rest@2}}; <<"Apr"/utf8, Rest@3/binary>> -> {ok, {{month, 4}, Rest@3}}; <<"May"/utf8, Rest@4/binary>> -> {ok, {{month, 5}, Rest@4}}; <<"Jun"/utf8, Rest@5/binary>> -> {ok, {{month, 6}, Rest@5}}; <<"Jul"/utf8, Rest@6/binary>> -> {ok, {{month, 7}, Rest@6}}; <<"Aug"/utf8, Rest@7/binary>> -> {ok, {{month, 8}, Rest@7}}; <<"Sep"/utf8, Rest@8/binary>> -> {ok, {{month, 9}, Rest@8}}; <<"Oct"/utf8, Rest@9/binary>> -> {ok, {{month, 10}, Rest@9}}; <<"Nov"/utf8, Rest@10/binary>> -> {ok, {{month, 11}, Rest@10}}; <<"Dec"/utf8, Rest@11/binary>> -> {ok, {{month, 12}, Rest@11}}; _ -> {error, nil} end; <<"MMMM"/utf8>> -> case Str of <<"January"/utf8, Rest@12/binary>> -> {ok, {{month, 1}, Rest@12}}; <<"February"/utf8, Rest@13/binary>> -> {ok, {{month, 2}, Rest@13}}; <<"March"/utf8, Rest@14/binary>> -> {ok, {{month, 3}, Rest@14}}; <<"April"/utf8, Rest@15/binary>> -> {ok, {{month, 4}, Rest@15}}; <<"May"/utf8, Rest@16/binary>> -> {ok, {{month, 5}, Rest@16}}; <<"June"/utf8, Rest@17/binary>> -> {ok, {{month, 6}, Rest@17}}; <<"July"/utf8, Rest@18/binary>> -> {ok, {{month, 7}, Rest@18}}; <<"August"/utf8, Rest@19/binary>> -> {ok, {{month, 8}, Rest@19}}; <<"September"/utf8, Rest@20/binary>> -> {ok, {{month, 9}, Rest@20}}; <<"October"/utf8, Rest@21/binary>> -> {ok, {{month, 10}, Rest@21}}; <<"November"/utf8, Rest@22/binary>> -> {ok, {{month, 11}, Rest@22}}; <<"December"/utf8, Rest@23/binary>> -> {ok, {{month, 12}, Rest@23}}; _ -> {error, nil} end; <<"D"/utf8>> -> consume_one_or_two_digits(Str, fun(Field@0) -> {day, Field@0} end); <<"DD"/utf8>> -> consume_two_digits(Str, fun(Field@0) -> {day, Field@0} end); <<"H"/utf8>> -> consume_one_or_two_digits(Str, fun(Field@0) -> {hour, Field@0} end); <<"HH"/utf8>> -> consume_two_digits(Str, fun(Field@0) -> {hour, Field@0} end); <<"h"/utf8>> -> consume_one_or_two_digits( Str, fun(Field@0) -> {twelve_hour, Field@0} end ); <<"hh"/utf8>> -> consume_two_digits(Str, fun(Field@0) -> {twelve_hour, Field@0} end); <<"a"/utf8>> -> case Str of <<"am"/utf8, Rest@24/binary>> -> {ok, {am_period, Rest@24}}; <<"pm"/utf8, Rest@25/binary>> -> {ok, {pm_period, Rest@25}}; _ -> {error, nil} end; <<"A"/utf8>> -> case Str of <<"AM"/utf8, Rest@26/binary>> -> {ok, {am_period, Rest@26}}; <<"PM"/utf8, Rest@27/binary>> -> {ok, {pm_period, Rest@27}}; _ -> {error, nil} end; <<"m"/utf8>> -> consume_one_or_two_digits( Str, fun(Field@0) -> {minute, Field@0} end ); <<"mm"/utf8>> -> consume_two_digits(Str, fun(Field@0) -> {minute, Field@0} end); <<"s"/utf8>> -> consume_one_or_two_digits( Str, fun(Field@0) -> {second, Field@0} end ); <<"ss"/utf8>> -> consume_two_digits(Str, fun(Field@0) -> {second, Field@0} end); <<"SSS"/utf8>> -> gleam@result:map( begin _pipe@2 = gleam@string:slice(Str, 0, 3), gleam@int:parse(_pipe@2) end, fun(Milli) -> {{millisecond, Milli}, gleam@string:drop_left(Str, 3)} end ); <<"SSSS"/utf8>> -> gleam@result:map( begin _pipe@3 = gleam@string:slice(Str, 0, 6), gleam@int:parse(_pipe@3) end, fun(Micro) -> {{microsecond, Micro}, gleam@string:drop_left(Str, 6)} end ); <<"SSSSS"/utf8>> -> gleam@result:map( begin _pipe@4 = gleam@string:slice(Str, 0, 9), gleam@int:parse(_pipe@4) end, fun(Nano) -> {{nanosecond, Nano}, gleam@string:drop_left(Str, 9)} end ); <<"z"/utf8>> -> gleam@result:try_recover( begin _pipe@5 = gleam@string:slice(Str, 0, 6), _pipe@7 = (fun(Offset) -> gleam@result:'try'( begin _pipe@6 = gleam@regex:from_string( <<"[-+]\\d\\d:\\d\\d"/utf8>> ), gleam@result:nil_error(_pipe@6) end, fun(Re) -> case gleam@regex:check(Re, Offset) of true -> {ok, Offset}; false -> {error, nil} end end ) end)(_pipe@5), gleam@result:map( _pipe@7, fun(Offset@1) -> {{offset_str, Offset@1}, gleam@string:drop_left(Str, 6)} end ) end, fun(_) -> gleam@result:try_recover( begin _pipe@8 = gleam@string:slice(Str, 0, 5), _pipe@10 = (fun(Offset@2) -> gleam@result:'try'( begin _pipe@9 = gleam@regex:from_string( <<"[-+]\\d\\d\\d\\d"/utf8>> ), gleam@result:nil_error(_pipe@9) end, fun(Re@1) -> case gleam@regex:check(Re@1, Offset@2) of true -> {ok, Offset@2}; false -> {error, nil} end end ) end)(_pipe@8), gleam@result:map( _pipe@10, fun(Offset@3) -> {{offset_str, Offset@3}, gleam@string:drop_left(Str, 5)} end ) end, fun(_) -> gleam@result:try_recover( begin _pipe@11 = gleam@string:slice(Str, 0, 3), _pipe@13 = (fun(Offset@4) -> gleam@result:'try'( begin _pipe@12 = gleam@regex:from_string( <<"[-+]\\d\\d"/utf8>> ), gleam@result:nil_error(_pipe@12) end, fun(Re@2) -> case gleam@regex:check( Re@2, Offset@4 ) of true -> {ok, Offset@4}; false -> {error, nil} end end ) end)(_pipe@11), gleam@result:map( _pipe@13, fun(Offset@5) -> {{offset_str, Offset@5}, gleam@string:drop_left(Str, 3)} end ) end, fun(_) -> gleam@result:try_recover( begin _pipe@14 = gleam@string:slice( Str, 0, 1 ), _pipe@15 = (fun(Offset@6) -> case (Offset@6 =:= <<"Z"/utf8>>) orelse (Offset@6 =:= <<"z"/utf8>>) of true -> {ok, Offset@6}; false -> {error, nil} end end)(_pipe@14), gleam@result:map( _pipe@15, fun(Offset@7) -> {{offset_str, Offset@7}, gleam@string:drop_left( Str, 1 )} end ) end, fun(_) -> {error, nil} end ) end ) end ) end ); <<"Z"/utf8>> -> {ok, {{offset_str, gleam@string:slice(Str, 0, 6)}, gleam@string:drop_left(Str, 6)}}; <<"ZZ"/utf8>> -> {ok, {{offset_str, gleam@string:slice(Str, 0, 5)}, gleam@string:drop_left(Str, 5)}}; Passthrough -> Fmt_length = gleam@string:length(Passthrough), Str_slice = gleam@string:slice(Str, 0, Fmt_length), case Str_slice =:= Passthrough of true -> {ok, {passthrough, gleam@string:drop_left(Str, Fmt_length)}}; false -> {error, nil} end end, gleam@result:replace_error(_pipe@16, {unable_to_parse_directive, Fmt}). -file("/home/john/Repos/tempo/src/tempo.gleam", 867). -spec consume_format(binary(), binary()) -> {ok, {list(datetime_part()), binary()}} | {error, error()}. consume_format(Str, 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}|SSS{3,5}|."/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"/utf8>>, function => <<"consume_format"/utf8>>, line => 868}) end, _pipe = gleam@regex:scan(Re, Fmt), gleam@list:fold(_pipe, {ok, {[], Str}}, fun(Acc, Match) -> case Acc of {ok, Acc@1} -> {Consumed, Input} = Acc@1, Res = case Match of {match, Content, []} -> consume_part(Content, Input); {match, _, [{some, Sub}]} -> {ok, {passthrough, gleam@string:drop_left( Input, gleam@string:length(Sub) )}}; {match, Content@1, _} -> {ok, {passthrough, gleam@string:drop_left( Input, gleam@string:length(Content@1) )}} end, case Res of {ok, {Part, Not_consumed}} -> {ok, {[Part | Consumed], Not_consumed}}; {error, Err} -> {error, Err} end; {error, Err@1} -> {error, Err@1} end end).