Current section
Files
Jump to
Current section
Files
src/birl@time.erl
-module(birl@time).
-compile([no_auto_import, nowarn_unused_vars]).
-export([to_unix/1, from_unix/1, compare/2, difference/2, add/2, subtract/2, range/3, set_offset/2, get_offset/1, now/0, utc_now/0, now_with_offset/1, monotonic_now/0, to_iso8601/1, month/1, string_month/1, short_string_month/1, get_date/1, get_time/1, to_erlang_datetime/1, to_erlang_universal_datetime/1, from_iso8601/1, set_date/2, set_time/2, from_erlang_local_datetime/1, from_erlang_universal_datetime/1, weekday/1, string_weekday/1, short_string_weekday/1, to_http/1, from_http/1]).
-export_type([date_time/0, date/0, time/0, weekday/0, month/0]).
-opaque date_time() :: {date_time,
integer(),
integer(),
gleam@option:option(integer())}.
-type date() :: {date, integer(), integer(), integer()}.
-type time() :: {time, integer(), integer(), integer(), integer()}.
-type weekday() :: mon | tue | wed | thu | fri | sat | sun.
-type month() :: jan |
feb |
mar |
apr |
may |
jun |
jul |
aug |
sep |
oct |
nov |
dec.
-spec to_unix(date_time()) -> integer().
to_unix(Value) ->
case Value of
{date_time, T, _, _} ->
T div 1000000
end.
-spec from_unix(integer()) -> date_time().
from_unix(Value) ->
{date_time, Value * 1000000, 0, none}.
-spec compare(date_time(), date_time()) -> gleam@order:order().
compare(A, B) ->
{date_time, Wta, _, Mta} = A,
{date_time, Wtb, _, Mtb} = B,
{Ta@1, Tb@1} = case {Mta, Mtb} of
{{some, Ta}, {some, Tb}} ->
{Ta, Tb};
_ ->
{Wta, Wtb}
end,
case Ta@1 =:= Tb@1 of
true ->
eq;
false ->
case Ta@1 < Tb@1 of
true ->
lt;
false ->
gt
end
end.
-spec difference(date_time(), date_time()) -> birl@duration:duration().
difference(A, B) ->
{date_time, Wta, _, Mta} = A,
{date_time, Wtb, _, Mtb} = B,
{Ta@1, Tb@1} = case {Mta, Mtb} of
{{some, Ta}, {some, Tb}} ->
{Ta, Tb};
_ ->
{Wta, Wtb}
end,
{duration, Ta@1 - Tb@1}.
-spec add(date_time(), birl@duration:duration()) -> date_time().
add(Value, Duration) ->
{date_time, Wt, O, Mt} = Value,
{duration, Duration@1} = Duration,
case Mt of
{some, Mt@1} ->
{date_time, Wt + Duration@1, O, {some, Mt@1 + Duration@1}};
none ->
{date_time, Wt + Duration@1, O, none}
end.
-spec subtract(date_time(), birl@duration:duration()) -> date_time().
subtract(Value, Duration) ->
{date_time, Wt, O, Mt} = Value,
{duration, Duration@1} = Duration,
case Mt of
{some, Mt@1} ->
{date_time, Wt - Duration@1, O, {some, Mt@1 - Duration@1}};
none ->
{date_time, Wt - Duration@1, O, none}
end.
-spec range(
date_time(),
gleam@option:option(date_time()),
birl@duration:duration()
) -> gleam@iterator:iterator(date_time()).
range(A, B, S) ->
_assert_subject = case B of
{some, B@1} ->
(ranger:create(
fun(_) -> true end,
fun(Duration) ->
{duration, Value} = Duration,
{duration, -1 * Value}
end,
fun add/2,
fun compare/2
))(A, B@1, S);
none ->
(ranger:create_infinite(
fun(_) -> true end,
fun add/2,
fun compare/2
))(A, S)
end,
{ok, Range} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"range"/utf8>>,
line => 390})
end,
_pipe = Range,
ranger:unwrap(_pipe).
-spec parse_offset(binary()) -> {ok, integer()} | {error, nil}.
parse_offset(Offset) ->
gleam@bool:guard(
gleam@list:contains([<<"Z"/utf8>>, <<"z"/utf8>>], Offset),
{ok, 0},
fun() ->
_assert_subject = gleam@regex:from_string(<<"([+-])"/utf8>>),
{ok, Re} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"parse_offset"/utf8>>,
line => 526})
end,
gleam@result:then(case gleam@regex:split(Re, Offset) of
[<<""/utf8>>, <<"+"/utf8>>, Offset@1] ->
{ok, {1, Offset@1}};
[<<""/utf8>>, <<"-"/utf8>>, Offset@2] ->
{ok, {-1, Offset@2}};
[_] ->
{ok, {1, Offset}};
_ ->
{error, nil}
end, fun(_use0) ->
{Sign, Offset@3} = _use0,
case gleam@string:split(Offset@3, <<":"/utf8>>) of
[Hour_str, Minute_str] ->
gleam@result:then(
gleam@int:parse(Hour_str),
fun(Hour) ->
gleam@result:then(
gleam@int:parse(Minute_str),
fun(Minute) ->
{ok,
((Sign * ((Hour * 60) + Minute))
* 60)
* 1000000}
end
)
end
);
[Offset@4] ->
case gleam@string:length(Offset@4) of
1 ->
gleam@result:then(
gleam@int:parse(Offset@4),
fun(Hour@1) ->
{ok,
((Sign * Hour@1) * 3600) * 1000000}
end
);
2 ->
gleam@result:then(
gleam@int:parse(Offset@4),
fun(Hour@1) ->
{ok,
((Sign * Hour@1) * 3600) * 1000000}
end
);
3 ->
_assert_subject@1 = gleam@string:first(
Offset@4
),
{ok, Hour_str@1} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(
#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"birl/time"/utf8>>,
function => <<"parse_offset"/utf8>>,
line => 548}
)
end,
Minute_str@1 = gleam@string:slice(
Offset@4,
1,
2
),
gleam@result:then(
gleam@int:parse(Hour_str@1),
fun(Hour@2) ->
gleam@result:then(
gleam@int:parse(Minute_str@1),
fun(Minute@1) ->
{ok,
((Sign * ((Hour@2 * 60)
+ Minute@1))
* 60)
* 1000000}
end
)
end
);
4 ->
Hour_str@2 = gleam@string:slice(
Offset@4,
0,
2
),
Minute_str@2 = gleam@string:slice(
Offset@4,
2,
2
),
gleam@result:then(
gleam@int:parse(Hour_str@2),
fun(Hour@3) ->
gleam@result:then(
gleam@int:parse(Minute_str@2),
fun(Minute@2) ->
{ok,
((Sign * ((Hour@3 * 60)
+ Minute@2))
* 60)
* 1000000}
end
)
end
);
_ ->
{error, nil}
end;
_ ->
{error, nil}
end
end)
end
).
-spec set_offset(date_time(), binary()) -> {ok, date_time()} | {error, nil}.
set_offset(Value, New_offset) ->
gleam@result:then(
parse_offset(New_offset),
fun(New_offset_number) -> case Value of
{date_time, T, _, Mt} ->
_pipe = {date_time, T, New_offset_number, Mt},
{ok, _pipe}
end end
).
-spec generate_offset(integer()) -> {ok, binary()} | {error, nil}.
generate_offset(Offset) ->
gleam@bool:guard(
Offset =:= 0,
{ok, <<"Z"/utf8>>},
fun() ->
case begin
_pipe = [{Offset, micro_second}],
_pipe@1 = birl@duration:new(_pipe),
birl@duration:decompose(_pipe@1)
end of
[{Hour, hour}, {Minute, minute}] ->
_pipe@10 = [case Hour > 0 of
true ->
gleam@string:concat(
[<<"+"/utf8>>,
begin
_pipe@2 = Hour,
_pipe@3 = gleam@int:to_string(
_pipe@2
),
gleam@string:pad_left(
_pipe@3,
2,
<<"0"/utf8>>
)
end]
);
false ->
gleam@string:concat(
[<<"-"/utf8>>,
begin
_pipe@4 = Hour,
_pipe@5 = gleam@int:absolute_value(
_pipe@4
),
_pipe@6 = gleam@int:to_string(
_pipe@5
),
gleam@string:pad_left(
_pipe@6,
2,
<<"0"/utf8>>
)
end]
)
end, begin
_pipe@7 = Minute,
_pipe@8 = gleam@int:absolute_value(_pipe@7),
_pipe@9 = gleam@int:to_string(_pipe@8),
gleam@string:pad_left(_pipe@9, 2, <<"0"/utf8>>)
end],
_pipe@11 = gleam@string:join(_pipe@10, <<":"/utf8>>),
{ok, _pipe@11};
[{Hour@1, hour}] ->
_pipe@17 = [case Hour@1 > 0 of
true ->
gleam@string:concat(
[<<"+"/utf8>>,
begin
_pipe@12 = Hour@1,
_pipe@13 = gleam@int:to_string(
_pipe@12
),
gleam@string:pad_left(
_pipe@13,
2,
<<"0"/utf8>>
)
end]
);
false ->
gleam@string:concat(
[<<"-"/utf8>>,
begin
_pipe@14 = Hour@1,
_pipe@15 = gleam@int:absolute_value(
_pipe@14
),
_pipe@16 = gleam@int:to_string(
_pipe@15
),
gleam@string:pad_left(
_pipe@16,
2,
<<"0"/utf8>>
)
end]
)
end, <<"00"/utf8>>],
_pipe@18 = gleam@string:join(_pipe@17, <<":"/utf8>>),
{ok, _pipe@18};
_ ->
{error, nil}
end
end
).
-spec get_offset(date_time()) -> binary().
get_offset(Value) ->
{date_time, _, Offset, _} = Value,
_assert_subject = generate_offset(Offset),
{ok, Offset@1} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"get_offset"/utf8>>,
line => 428})
end,
Offset@1.
-spec parse_iso_section(binary(), binary(), integer()) -> list({ok, integer()} |
{error, nil}).
parse_iso_section(Section, Pattern_string, Default) ->
_assert_subject = gleam@regex:from_string(Pattern_string),
{ok, Pattern} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"parse_iso_section"/utf8>>,
line => 674})
end,
case gleam@regex:scan(Pattern, Section) of
[{match, _, [{some, Major}]}] ->
[gleam@int:parse(Major), {ok, Default}, {ok, Default}];
[{match, _, [{some, Major@1}, {some, Middle}]}] ->
[gleam@int:parse(Major@1), gleam@int:parse(Middle), {ok, Default}];
[{match, _, [{some, Major@2}, {some, Middle@1}, {some, Minor}]}] ->
[gleam@int:parse(Major@2),
gleam@int:parse(Middle@1),
gleam@int:parse(Minor)];
_ ->
[{error, nil}]
end.
-spec parse_date(binary()) -> {ok, list(integer())} | {error, nil}.
parse_date(Date) ->
_assert_subject = gleam@regex:from_string(
<<"(\\d{4})(?:-(1[0-2]|0?[0-9]))?(?:-(3[0-1]|[1-2][0-9]|0?[0-9]))?"/utf8>>
),
{ok, Dash_pattern} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"parse_date"/utf8>>,
line => 629})
end,
_pipe = case gleam@regex:scan(Dash_pattern, Date) of
[{match, _, [{some, Major}]}] ->
[gleam@int:parse(Major), {ok, 1}, {ok, 1}];
[{match, _, [{some, Major@1}, {some, Middle}]}] ->
[gleam@int:parse(Major@1), gleam@int:parse(Middle), {ok, 1}];
[{match, _, [{some, Major@2}, {some, Middle@1}, {some, Minor}]}] ->
[gleam@int:parse(Major@2),
gleam@int:parse(Middle@1),
gleam@int:parse(Minor)];
_ ->
parse_iso_section(
Date,
<<"(\\d{4})(1[0-2]|0?[0-9])?(3[0-1]|[1-2][0-9]|0?[0-9])?"/utf8>>,
1
)
end,
gleam@list:try_map(_pipe, fun gleam@function:identity/1).
-spec parse_time(binary()) -> {ok, list(integer())} | {error, nil}.
parse_time(Time) ->
_pipe = parse_iso_section(
Time,
<<"(2[0-3]|1[0-9]|0?[0-9])([1-5][0-9]|0?[0-9])?([1-5][0-9]|0?[0-9])?"/utf8>>,
0
),
gleam@list:try_map(_pipe, fun gleam@function:identity/1).
-spec now() -> date_time().
now() ->
Now = birl_ffi:now(),
Offset_in_minutes = birl_ffi:local_offset(),
Monotonic_now = birl_ffi:monotonic_now(),
{date_time, Now, Offset_in_minutes * 60000000, {some, Monotonic_now}}.
-spec utc_now() -> date_time().
utc_now() ->
Now = birl_ffi:now(),
Monotonic_now = birl_ffi:monotonic_now(),
{date_time, Now, 0, {some, Monotonic_now}}.
-spec now_with_offset(binary()) -> {ok, date_time()} | {error, nil}.
now_with_offset(Offset) ->
gleam@result:then(
parse_offset(Offset),
fun(Offset@1) ->
Now = birl_ffi:now(),
Monotonic_now = birl_ffi:monotonic_now(),
_pipe = {date_time, Now, Offset@1, {some, Monotonic_now}},
{ok, _pipe}
end
).
-spec monotonic_now() -> integer().
monotonic_now() ->
birl_ffi:monotonic_now().
-spec to_parts(date_time()) -> {{integer(), integer(), integer()},
{integer(), integer(), integer(), integer()},
binary()}.
to_parts(Value) ->
case Value of
{date_time, T, O, _} ->
{Date, Time} = birl_ffi:to_parts(T, O),
_assert_subject = generate_offset(O),
{ok, Offset} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"to_parts"/utf8>>,
line => 507})
end,
{Date, Time, Offset}
end.
-spec to_iso8601(date_time()) -> binary().
to_iso8601(Value) ->
{{Year, Month, Day}, {Hour, Minute, Second, Milli_second}, Offset} = to_parts(
Value
),
<<<<<<<<<<<<<<<<<<<<<<<<<<(gleam@int:to_string(Year))/binary, "-"/utf8>>/binary,
(begin
_pipe = Month,
_pipe@1 = gleam@int:to_string(
_pipe
),
gleam@string:pad_left(
_pipe@1,
2,
<<"0"/utf8>>
)
end)/binary>>/binary,
"-"/utf8>>/binary,
(begin
_pipe@2 = Day,
_pipe@3 = gleam@int:to_string(
_pipe@2
),
gleam@string:pad_left(
_pipe@3,
2,
<<"0"/utf8>>
)
end)/binary>>/binary,
"T"/utf8>>/binary,
(begin
_pipe@4 = Hour,
_pipe@5 = gleam@int:to_string(_pipe@4),
gleam@string:pad_left(
_pipe@5,
2,
<<"0"/utf8>>
)
end)/binary>>/binary,
":"/utf8>>/binary,
(begin
_pipe@6 = Minute,
_pipe@7 = gleam@int:to_string(_pipe@6),
gleam@string:pad_left(_pipe@7, 2, <<"0"/utf8>>)
end)/binary>>/binary,
":"/utf8>>/binary,
(begin
_pipe@8 = Second,
_pipe@9 = gleam@int:to_string(_pipe@8),
gleam@string:pad_left(_pipe@9, 2, <<"0"/utf8>>)
end)/binary>>/binary,
"."/utf8>>/binary,
(begin
_pipe@10 = Milli_second,
_pipe@11 = gleam@int:to_string(_pipe@10),
gleam@string:pad_left(_pipe@11, 3, <<"0"/utf8>>)
end)/binary>>/binary,
Offset/binary>>.
-spec month(date_time()) -> month().
month(Value) ->
{{_, Month, _}, _, _} = to_parts(Value),
_assert_subject = gleam@list:at(
[jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec],
Month - 1
),
{ok, Month@1} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"month"/utf8>>,
line => 366})
end,
Month@1.
-spec string_month(date_time()) -> binary().
string_month(Value) ->
Month = month(Value),
_assert_subject = gleam@list:key_find(
[{jan, {<<"January"/utf8>>, <<"Jan"/utf8>>}},
{feb, {<<"February"/utf8>>, <<"Feb"/utf8>>}},
{mar, {<<"March"/utf8>>, <<"Mar"/utf8>>}},
{apr, {<<"April"/utf8>>, <<"Apr"/utf8>>}},
{may, {<<"May"/utf8>>, <<"May"/utf8>>}},
{jun, {<<"June"/utf8>>, <<"Jun"/utf8>>}},
{jul, {<<"July"/utf8>>, <<"Jul"/utf8>>}},
{aug, {<<"August"/utf8>>, <<"Aug"/utf8>>}},
{sep, {<<"September"/utf8>>, <<"Sep"/utf8>>}},
{oct, {<<"October"/utf8>>, <<"Oct"/utf8>>}},
{nov, {<<"November"/utf8>>, <<"Nov"/utf8>>}},
{dec, {<<"December"/utf8>>, <<"Dec"/utf8>>}}],
Month
),
{ok, {Month@1, _}} = case _assert_subject of
{ok, {_, _}} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"string_month"/utf8>>,
line => 372})
end,
Month@1.
-spec short_string_month(date_time()) -> binary().
short_string_month(Value) ->
Month = month(Value),
_assert_subject = gleam@list:key_find(
[{jan, {<<"January"/utf8>>, <<"Jan"/utf8>>}},
{feb, {<<"February"/utf8>>, <<"Feb"/utf8>>}},
{mar, {<<"March"/utf8>>, <<"Mar"/utf8>>}},
{apr, {<<"April"/utf8>>, <<"Apr"/utf8>>}},
{may, {<<"May"/utf8>>, <<"May"/utf8>>}},
{jun, {<<"June"/utf8>>, <<"Jun"/utf8>>}},
{jul, {<<"July"/utf8>>, <<"Jul"/utf8>>}},
{aug, {<<"August"/utf8>>, <<"Aug"/utf8>>}},
{sep, {<<"September"/utf8>>, <<"Sep"/utf8>>}},
{oct, {<<"October"/utf8>>, <<"Oct"/utf8>>}},
{nov, {<<"November"/utf8>>, <<"Nov"/utf8>>}},
{dec, {<<"December"/utf8>>, <<"Dec"/utf8>>}}],
Month
),
{ok, {_, Month@1}} = case _assert_subject of
{ok, {_, _}} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"short_string_month"/utf8>>,
line => 378})
end,
Month@1.
-spec get_date(date_time()) -> date().
get_date(Value) ->
{{Year, Month, Day}, _, _} = to_parts(Value),
{date, Year, Month, Day}.
-spec get_time(date_time()) -> time().
get_time(Value) ->
{_, {Hour, Minute, Second, Milli_second}, _} = to_parts(Value),
{time, Hour, Minute, Second, Milli_second}.
-spec to_erlang_datetime(date_time()) -> {{integer(), integer(), integer()},
{integer(), integer(), integer()}}.
to_erlang_datetime(Value) ->
{Date, {Hour, Minute, Second, _}, _} = to_parts(Value),
{Date, {Hour, Minute, Second}}.
-spec to_erlang_universal_datetime(date_time()) -> {{integer(),
integer(),
integer()},
{integer(), integer(), integer()}}.
to_erlang_universal_datetime(Value) ->
_assert_subject = set_offset(Value, <<"0"/utf8>>),
{ok, Value@1} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"to_erlang_universal_datetime"/utf8>>,
line => 470})
end,
{Date, {Hour, Minute, Second, _}, _} = to_parts(Value@1),
{Date, {Hour, Minute, Second}}.
-spec from_parts(
{integer(), integer(), integer()},
{integer(), integer(), integer(), integer()},
binary()
) -> {ok, date_time()} | {error, nil}.
from_parts(Date, Time, Offset) ->
gleam@result:then(
parse_offset(Offset),
fun(Offset_number) ->
_pipe = birl_ffi:from_parts({Date, Time}, Offset_number),
_pipe@1 = {date_time, _pipe, Offset_number, none},
{ok, _pipe@1}
end
).
-spec from_iso8601(binary()) -> {ok, date_time()} | {error, nil}.
from_iso8601(Value) ->
_assert_subject = gleam@regex:from_string(<<"(.*)([+|\\-].*)"/utf8>>),
{ok, Offset_pattern} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"from_iso8601"/utf8>>,
line => 118})
end,
Value@1 = gleam@string:trim(Value),
{Date_string@2, Offsetted_time_string@1} = case gleam@string:split(
Value@1,
<<"T"/utf8>>
) of
[Date_string] ->
{Date_string, <<"00"/utf8>>};
[Date_string@1, Offsetted_time_string] ->
{Date_string@1, Offsetted_time_string}
end,
{Time_string@1, Offset_string@1} = case gleam@string:ends_with(
Offsetted_time_string@1,
<<"Z"/utf8>>
) of
true ->
{gleam@string:drop_right(Offsetted_time_string@1, 1),
<<"+00:00"/utf8>>};
false ->
case gleam@regex:scan(Offset_pattern, Offsetted_time_string@1) of
[{match, _, [{some, Time_string}, {some, Offset_string}]}] ->
{Time_string, Offset_string};
[] ->
Local_offset_in_minutes = birl_ffi:local_offset(),
_assert_subject@1 = generate_offset(
Local_offset_in_minutes * 60000000
),
{ok, Local_offset_string} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"birl/time"/utf8>>,
function => <<"from_iso8601"/utf8>>,
line => 141})
end,
{Offsetted_time_string@1, Local_offset_string}
end
end,
Time_string@2 = gleam@string:replace(
Time_string@1,
<<":"/utf8>>,
<<""/utf8>>
),
{Time_string@5, Milli_seconds_result} = case gleam@string:split(
Time_string@2,
<<"."/utf8>>
) of
[Time_string@3] ->
{Time_string@3, {ok, 0}};
[Time_string@4, Milli_seconds_string] ->
{Time_string@4, gleam@int:parse(Milli_seconds_string)}
end,
case Milli_seconds_result of
{ok, Milli_seconds} ->
gleam@result:then(
parse_date(Date_string@2),
fun(_use0) ->
[Year, Month, Day] = _use0,
gleam@result:then(
parse_time(Time_string@5),
fun(_use0@1) ->
[Hour, Minute, Second] = _use0@1,
case from_parts(
{Year, Month, Day},
{Hour, Minute, Second, Milli_seconds},
Offset_string@1
) of
{ok, {date_time, Timestamp, Offset, none}} ->
{ok, {date_time, Timestamp, Offset, none}};
{error, nil} ->
{error, nil}
end
end
)
end
);
{error, nil} ->
{error, nil}
end.
-spec set_date(date_time(), date()) -> date_time().
set_date(Value, Date) ->
{_, Time, Offset} = to_parts(Value),
{date, Year, Month, Day} = Date,
_assert_subject = from_parts({Year, Month, Day}, Time, Offset),
{ok, New_value} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"set_date"/utf8>>,
line => 435})
end,
New_value.
-spec set_time(date_time(), time()) -> date_time().
set_time(Value, Time) ->
{Date, _, Offset} = to_parts(Value),
{time, Hour, Minute, Second, Milli_second} = Time,
_assert_subject = from_parts(
Date,
{Hour, Minute, Second, Milli_second},
Offset
),
{ok, New_value} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"set_time"/utf8>>,
line => 447})
end,
New_value.
-spec from_erlang_local_datetime(
{{integer(), integer(), integer()}, {integer(), integer(), integer()}}
) -> date_time().
from_erlang_local_datetime(Erlang_datetime) ->
{Date, Time} = Erlang_datetime,
Offset_in_minutes = birl_ffi:local_offset(),
{date_time, Wall_time, _, none} = begin
_pipe = {date_time, 0, 0, none},
_pipe@1 = set_date(
_pipe,
{date,
erlang:element(1, Date),
erlang:element(2, Date),
erlang:element(3, Date)}
),
set_time(
_pipe@1,
{time,
erlang:element(1, Time),
erlang:element(2, Time),
erlang:element(3, Time),
0}
)
end,
{date_time, Wall_time, Offset_in_minutes * 60000000, none}.
-spec from_erlang_universal_datetime(
{{integer(), integer(), integer()}, {integer(), integer(), integer()}}
) -> date_time().
from_erlang_universal_datetime(Erlang_datetime) ->
{Date, Time} = Erlang_datetime,
_pipe = {date_time, 0, 0, none},
_pipe@1 = set_date(
_pipe,
{date,
erlang:element(1, Date),
erlang:element(2, Date),
erlang:element(3, Date)}
),
set_time(
_pipe@1,
{time,
erlang:element(1, Time),
erlang:element(2, Time),
erlang:element(3, Time),
0}
).
-spec weekday(date_time()) -> weekday().
weekday(Value) ->
case Value of
{date_time, T, O, _} ->
_assert_subject = gleam@list:at(
[mon, tue, wed, thu, fri, sat, sun],
birl_ffi:weekday(T, O)
),
{ok, Weekday} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"weekday"/utf8>>,
line => 346})
end,
Weekday
end.
-spec string_weekday(date_time()) -> binary().
string_weekday(Value) ->
Weekday = weekday(Value),
_assert_subject = gleam@list:key_find(
[{mon, {<<"Monday"/utf8>>, <<"Mon"/utf8>>}},
{tue, {<<"Tuesday"/utf8>>, <<"Tue"/utf8>>}},
{wed, {<<"Wednesday"/utf8>>, <<"Wed"/utf8>>}},
{thu, {<<"Thursday"/utf8>>, <<"Thu"/utf8>>}},
{fri, {<<"Friday"/utf8>>, <<"Fri"/utf8>>}},
{sat, {<<"Saturday"/utf8>>, <<"Sat"/utf8>>}},
{sun, {<<"Sunday"/utf8>>, <<"Sun"/utf8>>}}],
Weekday
),
{ok, {Weekday@1, _}} = case _assert_subject of
{ok, {_, _}} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"string_weekday"/utf8>>,
line => 354})
end,
Weekday@1.
-spec short_string_weekday(date_time()) -> binary().
short_string_weekday(Value) ->
Weekday = weekday(Value),
_assert_subject = gleam@list:key_find(
[{mon, {<<"Monday"/utf8>>, <<"Mon"/utf8>>}},
{tue, {<<"Tuesday"/utf8>>, <<"Tue"/utf8>>}},
{wed, {<<"Wednesday"/utf8>>, <<"Wed"/utf8>>}},
{thu, {<<"Thursday"/utf8>>, <<"Thu"/utf8>>}},
{fri, {<<"Friday"/utf8>>, <<"Fri"/utf8>>}},
{sat, {<<"Saturday"/utf8>>, <<"Sat"/utf8>>}},
{sun, {<<"Sunday"/utf8>>, <<"Sun"/utf8>>}}],
Weekday
),
{ok, {_, Weekday@1}} = case _assert_subject of
{ok, {_, _}} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"short_string_weekday"/utf8>>,
line => 360})
end,
Weekday@1.
-spec to_http(date_time()) -> binary().
to_http(Value) ->
_assert_subject = set_offset(Value, <<"Z"/utf8>>),
{ok, Utc_value} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"to_http"/utf8>>,
line => 185})
end,
{{Year, _, Day}, {Hour, Minute, Second, _}, _} = to_parts(Utc_value),
Short_weekday = short_string_weekday(Utc_value),
Short_month = short_string_month(Utc_value),
<<<<<<<<<<<<<<<<<<<<<<<<<<Short_weekday/binary, ", "/utf8>>/binary,
(begin
_pipe = Day,
_pipe@1 = gleam@int:to_string(
_pipe
),
gleam@string:pad_left(
_pipe@1,
2,
<<"0"/utf8>>
)
end)/binary>>/binary,
" "/utf8>>/binary,
Short_month/binary>>/binary,
" "/utf8>>/binary,
(gleam@int:to_string(Year))/binary>>/binary,
" "/utf8>>/binary,
(begin
_pipe@2 = Hour,
_pipe@3 = gleam@int:to_string(_pipe@2),
gleam@string:pad_left(_pipe@3, 2, <<"0"/utf8>>)
end)/binary>>/binary,
":"/utf8>>/binary,
(begin
_pipe@4 = Minute,
_pipe@5 = gleam@int:to_string(_pipe@4),
gleam@string:pad_left(_pipe@5, 2, <<"0"/utf8>>)
end)/binary>>/binary,
":"/utf8>>/binary,
(begin
_pipe@6 = Second,
_pipe@7 = gleam@int:to_string(_pipe@6),
gleam@string:pad_left(_pipe@7, 2, <<"0"/utf8>>)
end)/binary>>/binary,
" GMT"/utf8>>.
-spec from_http(binary()) -> {ok, date_time()} | {error, nil}.
from_http(Value) ->
Value@1 = gleam@string:trim(Value),
[Weekday, Rest] = gleam@string:split(Value@1, <<","/utf8>>),
gleam@bool:guard(
not gleam@list:contains(
gleam@list:map(
[{mon, {<<"Monday"/utf8>>, <<"Mon"/utf8>>}},
{tue, {<<"Tuesday"/utf8>>, <<"Tue"/utf8>>}},
{wed, {<<"Wednesday"/utf8>>, <<"Wed"/utf8>>}},
{thu, {<<"Thursday"/utf8>>, <<"Thu"/utf8>>}},
{fri, {<<"Friday"/utf8>>, <<"Fri"/utf8>>}},
{sat, {<<"Saturday"/utf8>>, <<"Sat"/utf8>>}},
{sun, {<<"Sunday"/utf8>>, <<"Sun"/utf8>>}}],
fun(Weekday@1) ->
Strings = erlang:element(2, Weekday@1),
erlang:element(2, Strings)
end
),
Weekday
),
{error, nil},
fun() ->
Rest@1 = gleam@string:trim(Rest),
_assert_subject = gleam@regex:from_string(<<"\\s+"/utf8>>),
{ok, Whitespace_pattern} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"birl/time"/utf8>>,
function => <<"from_http"/utf8>>,
line => 229})
end,
case gleam@regex:split(Whitespace_pattern, Rest@1) of
[Day_string,
Short_month,
Year_string,
Time_string,
<<"GMT"/utf8>>] ->
Time_string@1 = gleam@string:replace(
Time_string,
<<":"/utf8>>,
<<""/utf8>>
),
case {gleam@int:parse(Day_string),
begin
_pipe = [{jan, {<<"January"/utf8>>, <<"Jan"/utf8>>}},
{feb, {<<"February"/utf8>>, <<"Feb"/utf8>>}},
{mar, {<<"March"/utf8>>, <<"Mar"/utf8>>}},
{apr, {<<"April"/utf8>>, <<"Apr"/utf8>>}},
{may, {<<"May"/utf8>>, <<"May"/utf8>>}},
{jun, {<<"June"/utf8>>, <<"Jun"/utf8>>}},
{jul, {<<"July"/utf8>>, <<"Jul"/utf8>>}},
{aug, {<<"August"/utf8>>, <<"Aug"/utf8>>}},
{sep, {<<"September"/utf8>>, <<"Sep"/utf8>>}},
{oct, {<<"October"/utf8>>, <<"Oct"/utf8>>}},
{nov, {<<"November"/utf8>>, <<"Nov"/utf8>>}},
{dec, {<<"December"/utf8>>, <<"Dec"/utf8>>}}],
_pipe@1 = gleam@list:index_map(
_pipe,
fun(Index, Month) ->
Strings@1 = erlang:element(2, Month),
{Index, erlang:element(2, Strings@1)}
end
),
gleam@list:find(
_pipe@1,
fun(Month@1) ->
erlang:element(2, Month@1) =:= Short_month
end
)
end,
gleam@int:parse(Year_string),
parse_time(Time_string@1)} of
{{ok, Day},
{ok, {Month_index, _}},
{ok, Year},
{ok, [Hour, Minute, Second]}} ->
case from_parts(
{Year, Month_index + 1, Day},
{Hour, Minute, Second, 0},
<<"Z"/utf8>>
) of
{ok, Value@2} ->
Correct_weekday = short_string_weekday(
Value@2
),
case Correct_weekday =:= Weekday of
true ->
{ok, Value@2};
false ->
{error, nil}
end;
{error, nil} ->
{error, nil}
end;
_ ->
{error, nil}
end;
_ ->
{error, nil}
end
end
).