Current section
Files
Jump to
Current section
Files
src/tempo.erl
-module(tempo).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([validate_offset/1, new_offset/1, offset_from_string/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, 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, 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, naive_date_time/0, date_time/0, offset/0, date/0, period/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.
-type naive_date_time() :: {naive_date_time, date(), time()}.
-type date_time() :: {date_time, naive_date_time(), offset()}.
-type offset() :: {offset, integer()}.
-type date() :: {date, integer(), month(), integer()}.
-type period() :: {naive_period, naive_date_time(), naive_date_time()} |
{period, date_time(), date_time()}.
-type time() :: {time, integer(), integer(), integer(), integer()} |
{time_milli, integer(), integer(), integer(), integer()} |
{time_micro, integer(), integer(), integer(), integer()} |
{time_nano, integer(), integer(), integer(), integer()}.
-type 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", 116).
-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", 53).
-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", 57).
-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", 217).
-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, _, _, _, _} ->
{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.
-file("/home/john/Repos/tempo/src/tempo.gleam", 181).
-spec new_time(integer(), integer(), integer()) -> {ok, time()} |
{error, error()}.
new_time(Hour, Minute, Second) ->
_pipe = {time, Hour, Minute, Second, 0},
validate_time(_pipe).
-file("/home/john/Repos/tempo/src/tempo.gleam", 186).
-spec new_time_milli(integer(), integer(), integer(), integer()) -> {ok, time()} |
{error, error()}.
new_time_milli(Hour, Minute, Second, Millisecond) ->
_pipe = {time_milli, Hour, Minute, Second, Millisecond * 1000000},
validate_time(_pipe).
-file("/home/john/Repos/tempo/src/tempo.gleam", 197).
-spec new_time_micro(integer(), integer(), integer(), integer()) -> {ok, time()} |
{error, error()}.
new_time_micro(Hour, Minute, Second, Microsecond) ->
_pipe = {time_micro, Hour, Minute, Second, Microsecond * 1000},
validate_time(_pipe).
-file("/home/john/Repos/tempo/src/tempo.gleam", 207).
-spec new_time_nano(integer(), integer(), integer(), integer()) -> {ok, time()} |
{error, error()}.
new_time_nano(Hour, Minute, Second, Nanosecond) ->
_pipe = {time_nano, Hour, Minute, Second, Nanosecond},
validate_time(_pipe).
-file("/home/john/Repos/tempo/src/tempo.gleam", 252).
-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", 297).
-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", 316).
-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", 334).
-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", 353).
-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", 396).
-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", 371).
-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", 140).
-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", 131).
-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", 442).
-spec accept_imprecision(uncertain_conversion(FYS)) -> FYS.
accept_imprecision(Conv) ->
case Conv of
{precise, A} ->
A;
{imprecise, A@1} ->
A@1
end.
-file("/home/john/Repos/tempo/src/tempo.gleam", 460).
-spec error_on_imprecision(uncertain_conversion(FYU)) -> {ok, FYU} |
{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", 509).
-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", 724).
-spec now_utc() -> integer().
now_utc() ->
tempo_ffi:now().
-file("/home/john/Repos/tempo/src/tempo.gleam", 984).
-spec consume_one_or_two_digits(binary(), fun((integer()) -> GOW)) -> {ok,
{GOW, 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", 995).
-spec consume_two_digits(binary(), fun((integer()) -> GPP)) -> {ok,
{GPP, 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", 1002).
-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", 1013).
-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", 1024).
-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", 1035).
-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", 1083).
-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", 1094).
-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", 1129).
-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", 1229).
-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", 781).
-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", 745).
-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 => 746})
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).