src/automata@internal@calendar.erl

-module(automata@internal@calendar).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/automata/internal/calendar.gleam").
-export([compare/2, less_than/2, less_or_equal/2, greater_than/2, greater_or_equal/2, equals/2, is_valid_time/1, start_of_day/1, at_time/4, at_date/2, set_minute/2, set_hour/2, set_day/2, is_leap_year/1, days_in_month/2, is_valid_date/1, is_valid_datetime/1, days_since_epoch/1, datetime_to_seconds/1, seconds_between/2, add_months/2, next_month/1, next_year/1, set_month/2, set_year/2, add_days/2, add_seconds/2, next_day/1, add_minutes/2, ceil_to_next_minute/1, weekday/1, day_of_week_number/1]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

?MODULEDOC(false).

-file("src/automata/internal/calendar.gleam", 8).
?DOC(false).
-spec compare(
    automata@schedule@ast:date_time(),
    automata@schedule@ast:date_time()
) -> gleam@order:order().
compare(Left, Right) ->
    case erlang:element(2, erlang:element(2, Left)) < erlang:element(
        2,
        erlang:element(2, Right)
    ) of
        true ->
            lt;

        false ->
            case erlang:element(2, erlang:element(2, Left)) > erlang:element(
                2,
                erlang:element(2, Right)
            ) of
                true ->
                    gt;

                false ->
                    case erlang:element(3, erlang:element(2, Left)) < erlang:element(
                        3,
                        erlang:element(2, Right)
                    ) of
                        true ->
                            lt;

                        false ->
                            case erlang:element(3, erlang:element(2, Left)) > erlang:element(
                                3,
                                erlang:element(2, Right)
                            ) of
                                true ->
                                    gt;

                                false ->
                                    case erlang:element(
                                        4,
                                        erlang:element(2, Left)
                                    )
                                    < erlang:element(
                                        4,
                                        erlang:element(2, Right)
                                    ) of
                                        true ->
                                            lt;

                                        false ->
                                            case erlang:element(
                                                4,
                                                erlang:element(2, Left)
                                            )
                                            > erlang:element(
                                                4,
                                                erlang:element(2, Right)
                                            ) of
                                                true ->
                                                    gt;

                                                false ->
                                                    case erlang:element(
                                                        2,
                                                        erlang:element(3, Left)
                                                    )
                                                    < erlang:element(
                                                        2,
                                                        erlang:element(3, Right)
                                                    ) of
                                                        true ->
                                                            lt;

                                                        false ->
                                                            case erlang:element(
                                                                2,
                                                                erlang:element(
                                                                    3,
                                                                    Left
                                                                )
                                                            )
                                                            > erlang:element(
                                                                2,
                                                                erlang:element(
                                                                    3,
                                                                    Right
                                                                )
                                                            ) of
                                                                true ->
                                                                    gt;

                                                                false ->
                                                                    case erlang:element(
                                                                        3,
                                                                        erlang:element(
                                                                            3,
                                                                            Left
                                                                        )
                                                                    )
                                                                    < erlang:element(
                                                                        3,
                                                                        erlang:element(
                                                                            3,
                                                                            Right
                                                                        )
                                                                    ) of
                                                                        true ->
                                                                            lt;

                                                                        false ->
                                                                            case erlang:element(
                                                                                3,
                                                                                erlang:element(
                                                                                    3,
                                                                                    Left
                                                                                )
                                                                            )
                                                                            > erlang:element(
                                                                                3,
                                                                                erlang:element(
                                                                                    3,
                                                                                    Right
                                                                                )
                                                                            ) of
                                                                                true ->
                                                                                    gt;

                                                                                false ->
                                                                                    case erlang:element(
                                                                                        4,
                                                                                        erlang:element(
                                                                                            3,
                                                                                            Left
                                                                                        )
                                                                                    )
                                                                                    < erlang:element(
                                                                                        4,
                                                                                        erlang:element(
                                                                                            3,
                                                                                            Right
                                                                                        )
                                                                                    ) of
                                                                                        true ->
                                                                                            lt;

                                                                                        false ->
                                                                                            case erlang:element(
                                                                                                4,
                                                                                                erlang:element(
                                                                                                    3,
                                                                                                    Left
                                                                                                )
                                                                                            )
                                                                                            > erlang:element(
                                                                                                4,
                                                                                                erlang:element(
                                                                                                    3,
                                                                                                    Right
                                                                                                )
                                                                                            ) of
                                                                                                true ->
                                                                                                    gt;

                                                                                                false ->
                                                                                                    eq
                                                                                            end
                                                                                    end
                                                                            end
                                                                    end
                                                            end
                                                    end
                                            end
                                    end
                            end
                    end
            end
    end.

-file("src/automata/internal/calendar.gleam", 66).
?DOC(false).
-spec less_than(
    automata@schedule@ast:date_time(),
    automata@schedule@ast:date_time()
) -> boolean().
less_than(Left, Right) ->
    compare(Left, Right) =:= lt.

-file("src/automata/internal/calendar.gleam", 70).
?DOC(false).
-spec less_or_equal(
    automata@schedule@ast:date_time(),
    automata@schedule@ast:date_time()
) -> boolean().
less_or_equal(Left, Right) ->
    case compare(Left, Right) of
        lt ->
            true;

        eq ->
            true;

        gt ->
            false
    end.

-file("src/automata/internal/calendar.gleam", 78).
?DOC(false).
-spec greater_than(
    automata@schedule@ast:date_time(),
    automata@schedule@ast:date_time()
) -> boolean().
greater_than(Left, Right) ->
    compare(Left, Right) =:= gt.

-file("src/automata/internal/calendar.gleam", 82).
?DOC(false).
-spec greater_or_equal(
    automata@schedule@ast:date_time(),
    automata@schedule@ast:date_time()
) -> boolean().
greater_or_equal(Left, Right) ->
    case compare(Left, Right) of
        gt ->
            true;

        eq ->
            true;

        lt ->
            false
    end.

-file("src/automata/internal/calendar.gleam", 90).
?DOC(false).
-spec equals(
    automata@schedule@ast:date_time(),
    automata@schedule@ast:date_time()
) -> boolean().
equals(Left, Right) ->
    compare(Left, Right) =:= eq.

-file("src/automata/internal/calendar.gleam", 101).
?DOC(false).
-spec is_valid_time(automata@schedule@ast:time()) -> boolean().
is_valid_time(Time) ->
    (((((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).

-file("src/automata/internal/calendar.gleam", 275).
?DOC(false).
-spec start_of_day(automata@schedule@ast:date_time()) -> automata@schedule@ast:date_time().
start_of_day(Datetime) ->
    {date_time, erlang:element(2, Datetime), {time, 0, 0, 0}}.

-file("src/automata/internal/calendar.gleam", 279).
?DOC(false).
-spec at_time(
    automata@schedule@ast:date_time(),
    integer(),
    integer(),
    integer()
) -> automata@schedule@ast:date_time().
at_time(Datetime, Hour, Minute, Second) ->
    {date_time, erlang:element(2, Datetime), {time, Hour, Minute, Second}}.

-file("src/automata/internal/calendar.gleam", 288).
?DOC(false).
-spec at_date(automata@schedule@ast:date_time(), automata@schedule@ast:date()) -> automata@schedule@ast:date_time().
at_date(Datetime, Date) ->
    {date_time, Date, erlang:element(3, Datetime)}.

-file("src/automata/internal/calendar.gleam", 328).
?DOC(false).
-spec set_minute(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
set_minute(Datetime, Minute) ->
    {date_time,
        erlang:element(2, Datetime),
        {time,
            erlang:element(2, erlang:element(3, Datetime)),
            Minute,
            erlang:element(4, erlang:element(3, Datetime))}}.

-file("src/automata/internal/calendar.gleam", 339).
?DOC(false).
-spec set_hour(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
set_hour(Datetime, Hour) ->
    {date_time,
        erlang:element(2, Datetime),
        {time,
            Hour,
            erlang:element(3, erlang:element(3, Datetime)),
            erlang:element(4, erlang:element(3, Datetime))}}.

-file("src/automata/internal/calendar.gleam", 350).
?DOC(false).
-spec set_day(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
set_day(Datetime, Day) ->
    {date_time,
        {date,
            erlang:element(2, erlang:element(2, Datetime)),
            erlang:element(3, erlang:element(2, Datetime)),
            Day},
        erlang:element(3, Datetime)}.

-file("src/automata/internal/calendar.gleam", 560).
?DOC(false).
-spec month_offset(integer()) -> integer().
month_offset(Month) ->
    case Month of
        1 ->
            0;

        2 ->
            3;

        3 ->
            2;

        4 ->
            5;

        5 ->
            0;

        6 ->
            3;

        7 ->
            5;

        8 ->
            1;

        9 ->
            4;

        10 ->
            6;

        11 ->
            2;

        12 ->
            4;

        _ ->
            0
    end.

-file("src/automata/internal/calendar.gleam", 578).
?DOC(false).
-spec quotient(integer(), integer()) -> integer().
quotient(Dividend, Divisor) ->
    case gleam@int:divide(Dividend, Divisor) of
        {ok, Result} ->
            Result;

        {error, _} ->
            0
    end.

-file("src/automata/internal/calendar.gleam", 585).
?DOC(false).
-spec modulo(integer(), integer()) -> integer().
modulo(Dividend, Divisor) ->
    case gleam@int:modulo(Dividend, Divisor) of
        {ok, Result} ->
            Result;

        {error, _} ->
            0
    end.

-file("src/automata/internal/calendar.gleam", 136).
?DOC(false).
-spec is_leap_year(integer()) -> boolean().
is_leap_year(Year) ->
    By_4 = modulo(Year, 4),
    By_100 = modulo(Year, 100),
    By_400 = modulo(Year, 400),
    (By_400 =:= 0) orelse ((By_4 =:= 0) andalso (By_100 /= 0)).

-file("src/automata/internal/calendar.gleam", 114).
?DOC(false).
-spec days_in_month(integer(), integer()) -> integer().
days_in_month(Year, Month) ->
    case Month of
        1 ->
            31;

        2 ->
            case is_leap_year(Year) of
                true ->
                    29;

                false ->
                    28
            end;

        3 ->
            31;

        4 ->
            30;

        5 ->
            31;

        6 ->
            30;

        7 ->
            31;

        8 ->
            31;

        9 ->
            30;

        10 ->
            31;

        11 ->
            30;

        12 ->
            31;

        _ ->
            0
    end.

-file("src/automata/internal/calendar.gleam", 94).
?DOC(false).
-spec is_valid_date(automata@schedule@ast:date()) -> boolean().
is_valid_date(Date) ->
    (((erlang:element(3, Date) >= 1) andalso (erlang:element(3, Date) =< 12))
    andalso (erlang:element(4, Date) >= 1))
    andalso (erlang:element(4, Date) =< days_in_month(
        erlang:element(2, Date),
        erlang:element(3, Date)
    )).

-file("src/automata/internal/calendar.gleam", 110).
?DOC(false).
-spec is_valid_datetime(automata@schedule@ast:date_time()) -> boolean().
is_valid_datetime(Datetime) ->
    is_valid_date(erlang:element(2, Datetime)) andalso is_valid_time(
        erlang:element(3, Datetime)
    ).

-file("src/automata/internal/calendar.gleam", 196).
?DOC(false).
-spec days_before_month_loop(integer(), integer(), integer(), integer()) -> integer().
days_before_month_loop(Year, Target, Month, Acc) ->
    case Month >= Target of
        true ->
            Acc;

        false ->
            days_before_month_loop(
                Year,
                Target,
                Month + 1,
                Acc + days_in_month(Year, Month)
            )
    end.

-file("src/automata/internal/calendar.gleam", 192).
?DOC(false).
-spec days_before_month(integer(), integer()) -> integer().
days_before_month(Year, Month) ->
    days_before_month_loop(Year, Month, 1, 0).

-file("src/automata/internal/calendar.gleam", 170).
?DOC(false).
-spec days_since_epoch(automata@schedule@ast:date()) -> integer().
days_since_epoch(Date) ->
    Previous = erlang:element(2, Date) - 1,
    Leap_days = (quotient(Previous, 4) - quotient(Previous, 100)) + quotient(
        Previous,
        400
    ),
    Days_before_year = (Previous * 365) + Leap_days,
    (Days_before_year + days_before_month(
        erlang:element(2, Date),
        erlang:element(3, Date)
    ))
    + erlang:element(4, Date).

-file("src/automata/internal/calendar.gleam", 178).
?DOC(false).
-spec datetime_to_seconds(automata@schedule@ast:date_time()) -> integer().
datetime_to_seconds(Datetime) ->
    (((days_since_epoch(erlang:element(2, Datetime)) * 86400) + (erlang:element(
        2,
        erlang:element(3, Datetime)
    )
    * 3600))
    + (erlang:element(3, erlang:element(3, Datetime)) * 60))
    + erlang:element(4, erlang:element(3, Datetime)).

-file("src/automata/internal/calendar.gleam", 188).
?DOC(false).
-spec seconds_between(
    automata@schedule@ast:date_time(),
    automata@schedule@ast:date_time()
) -> integer().
seconds_between(From, To) ->
    datetime_to_seconds(To) - datetime_to_seconds(From).

-file("src/automata/internal/calendar.gleam", 257).
?DOC(false).
-spec add_months(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
add_months(Datetime, Months) ->
    case Months =:= 0 of
        true ->
            Datetime;

        false ->
            Total = (((erlang:element(2, erlang:element(2, Datetime)) * 12) + erlang:element(
                3,
                erlang:element(2, Datetime)
            ))
            - 1)
            + Months,
            Year = quotient(Total, 12),
            Month = modulo(Total, 12) + 1,
            Max_day = days_in_month(Year, Month),
            Day = case erlang:element(4, erlang:element(2, Datetime)) > Max_day of
                true ->
                    Max_day;

                false ->
                    erlang:element(4, erlang:element(2, Datetime))
            end,
            {date_time, {date, Year, Month, Day}, erlang:element(3, Datetime)}
    end.

-file("src/automata/internal/calendar.gleam", 296).
?DOC(false).
-spec next_month(automata@schedule@ast:date_time()) -> automata@schedule@ast:date_time().
next_month(Datetime) ->
    {date_time,
        erlang:element(2, add_months(start_of_day(Datetime), 1)),
        {time, 0, 0, 0}}.

-file("src/automata/internal/calendar.gleam", 303).
?DOC(false).
-spec next_year(automata@schedule@ast:date_time()) -> automata@schedule@ast:date_time().
next_year(Datetime) ->
    add_months({date_time, erlang:element(2, Datetime), {time, 0, 0, 0}}, 12).

-file("src/automata/internal/calendar.gleam", 357).
?DOC(false).
-spec set_month(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
set_month(Datetime, Month) ->
    Max_day = days_in_month(
        erlang:element(2, erlang:element(2, Datetime)),
        Month
    ),
    Day = case erlang:element(4, erlang:element(2, Datetime)) > Max_day of
        true ->
            Max_day;

        false ->
            erlang:element(4, erlang:element(2, Datetime))
    end,
    {date_time,
        {date, erlang:element(2, erlang:element(2, Datetime)), Month, Day},
        erlang:element(3, Datetime)}.

-file("src/automata/internal/calendar.gleam", 370).
?DOC(false).
-spec set_year(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
set_year(Datetime, Year) ->
    Max_day = days_in_month(
        Year,
        erlang:element(3, erlang:element(2, Datetime))
    ),
    Day = case erlang:element(4, erlang:element(2, Datetime)) > Max_day of
        true ->
            Max_day;

        false ->
            erlang:element(4, erlang:element(2, Datetime))
    end,
    {date_time,
        {date, Year, erlang:element(3, erlang:element(2, Datetime)), Day},
        erlang:element(3, Datetime)}.

-file("src/automata/internal/calendar.gleam", 473).
?DOC(false).
-spec add_one_day(automata@schedule@ast:date_time()) -> automata@schedule@ast:date_time().
add_one_day(Datetime) ->
    Max_day = days_in_month(
        erlang:element(2, erlang:element(2, Datetime)),
        erlang:element(3, erlang:element(2, Datetime))
    ),
    case erlang:element(4, erlang:element(2, Datetime)) < Max_day of
        true ->
            {date_time,
                {date,
                    erlang:element(2, erlang:element(2, Datetime)),
                    erlang:element(3, erlang:element(2, Datetime)),
                    erlang:element(4, erlang:element(2, Datetime)) + 1},
                erlang:element(3, Datetime)};

        false ->
            case erlang:element(3, erlang:element(2, Datetime)) < 12 of
                true ->
                    {date_time,
                        {date,
                            erlang:element(2, erlang:element(2, Datetime)),
                            erlang:element(3, erlang:element(2, Datetime)) + 1,
                            1},
                        erlang:element(3, Datetime)};

                false ->
                    {date_time,
                        {date,
                            erlang:element(2, erlang:element(2, Datetime)) + 1,
                            1,
                            1},
                        erlang:element(3, Datetime)}
            end
    end.

-file("src/automata/internal/calendar.gleam", 397).
?DOC(false).
-spec add_positive_days(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
add_positive_days(Datetime, Days) ->
    case Days of
        0 ->
            Datetime;

        _ ->
            add_positive_days(add_one_day(Datetime), Days - 1)
    end.

-file("src/automata/internal/calendar.gleam", 411).
?DOC(false).
-spec add_one_minute(automata@schedule@ast:date_time()) -> automata@schedule@ast:date_time().
add_one_minute(Datetime) ->
    case erlang:element(3, erlang:element(3, Datetime)) < 59 of
        true ->
            {date_time,
                erlang:element(2, Datetime),
                {time,
                    erlang:element(2, erlang:element(3, Datetime)),
                    erlang:element(3, erlang:element(3, Datetime)) + 1,
                    erlang:element(4, erlang:element(3, Datetime))}};

        false ->
            case erlang:element(2, erlang:element(3, Datetime)) < 23 of
                true ->
                    {date_time,
                        erlang:element(2, Datetime),
                        {time,
                            erlang:element(2, erlang:element(3, Datetime)) + 1,
                            0,
                            erlang:element(4, erlang:element(3, Datetime))}};

                false ->
                    {date_time,
                        erlang:element(2, add_one_day(Datetime)),
                        {time,
                            0,
                            0,
                            erlang:element(4, erlang:element(3, Datetime))}}
            end
    end.

-file("src/automata/internal/calendar.gleam", 383).
?DOC(false).
-spec add_positive_minutes(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
add_positive_minutes(Datetime, Minutes) ->
    case Minutes of
        0 ->
            Datetime;

        _ ->
            add_positive_minutes(add_one_minute(Datetime), Minutes - 1)
    end.

-file("src/automata/internal/calendar.gleam", 506).
?DOC(false).
-spec subtract_one_day(automata@schedule@ast:date_time()) -> automata@schedule@ast:date_time().
subtract_one_day(Datetime) ->
    case erlang:element(4, erlang:element(2, Datetime)) > 1 of
        true ->
            {date_time,
                {date,
                    erlang:element(2, erlang:element(2, Datetime)),
                    erlang:element(3, erlang:element(2, Datetime)),
                    erlang:element(4, erlang:element(2, Datetime)) - 1},
                erlang:element(3, Datetime)};

        false ->
            case erlang:element(3, erlang:element(2, Datetime)) > 1 of
                true ->
                    Previous_month = erlang:element(
                        3,
                        erlang:element(2, Datetime)
                    )
                    - 1,
                    {date_time,
                        {date,
                            erlang:element(2, erlang:element(2, Datetime)),
                            Previous_month,
                            days_in_month(
                                erlang:element(2, erlang:element(2, Datetime)),
                                Previous_month
                            )},
                        erlang:element(3, Datetime)};

                false ->
                    {date_time,
                        {date,
                            erlang:element(2, erlang:element(2, Datetime)) - 1,
                            12,
                            days_in_month(
                                erlang:element(2, erlang:element(2, Datetime)) - 1,
                                12
                            )},
                        erlang:element(3, Datetime)}
            end
    end.

-file("src/automata/internal/calendar.gleam", 404).
?DOC(false).
-spec add_negative_days(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
add_negative_days(Datetime, Days) ->
    case Days of
        0 ->
            Datetime;

        _ ->
            add_negative_days(subtract_one_day(Datetime), Days - 1)
    end.

-file("src/automata/internal/calendar.gleam", 246).
?DOC(false).
-spec add_days(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
add_days(Datetime, Days) ->
    case Days =:= 0 of
        true ->
            Datetime;

        false ->
            case Days > 0 of
                true ->
                    add_positive_days(Datetime, Days);

                false ->
                    add_negative_days(Datetime, 0 - Days)
            end
    end.

-file("src/automata/internal/calendar.gleam", 220).
?DOC(false).
-spec add_seconds(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
add_seconds(Datetime, Seconds) ->
    case Seconds of
        0 ->
            Datetime;

        _ ->
            Seconds_in_day = 86400,
            Current_in_day = ((erlang:element(2, erlang:element(3, Datetime)) * 3600)
            + (erlang:element(3, erlang:element(3, Datetime)) * 60))
            + erlang:element(4, erlang:element(3, Datetime)),
            Total = Current_in_day + Seconds,
            In_day = modulo(Total, Seconds_in_day),
            Day_offset = quotient(Total - In_day, Seconds_in_day),
            Hour = quotient(In_day, 3600),
            After_hour = In_day - (Hour * 3600),
            Minute = quotient(After_hour, 60),
            Second = After_hour - (Minute * 60),
            add_days(
                {date_time,
                    erlang:element(2, Datetime),
                    {time, Hour, Minute, Second}},
                Day_offset
            )
    end.

-file("src/automata/internal/calendar.gleam", 292).
?DOC(false).
-spec next_day(automata@schedule@ast:date_time()) -> automata@schedule@ast:date_time().
next_day(Datetime) ->
    add_days(start_of_day(Datetime), 1).

-file("src/automata/internal/calendar.gleam", 442).
?DOC(false).
-spec subtract_one_minute(automata@schedule@ast:date_time()) -> automata@schedule@ast:date_time().
subtract_one_minute(Datetime) ->
    case erlang:element(3, erlang:element(3, Datetime)) > 0 of
        true ->
            {date_time,
                erlang:element(2, Datetime),
                {time,
                    erlang:element(2, erlang:element(3, Datetime)),
                    erlang:element(3, erlang:element(3, Datetime)) - 1,
                    erlang:element(4, erlang:element(3, Datetime))}};

        false ->
            case erlang:element(2, erlang:element(3, Datetime)) > 0 of
                true ->
                    {date_time,
                        erlang:element(2, Datetime),
                        {time,
                            erlang:element(2, erlang:element(3, Datetime)) - 1,
                            59,
                            erlang:element(4, erlang:element(3, Datetime))}};

                false ->
                    {date_time,
                        erlang:element(2, subtract_one_day(Datetime)),
                        {time,
                            23,
                            59,
                            erlang:element(4, erlang:element(3, Datetime))}}
            end
    end.

-file("src/automata/internal/calendar.gleam", 390).
?DOC(false).
-spec add_negative_minutes(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
add_negative_minutes(Datetime, Minutes) ->
    case Minutes of
        0 ->
            Datetime;

        _ ->
            add_negative_minutes(subtract_one_minute(Datetime), Minutes - 1)
    end.

-file("src/automata/internal/calendar.gleam", 209).
?DOC(false).
-spec add_minutes(automata@schedule@ast:date_time(), integer()) -> automata@schedule@ast:date_time().
add_minutes(Datetime, Minutes) ->
    case Minutes =:= 0 of
        true ->
            Datetime;

        false ->
            case Minutes > 0 of
                true ->
                    add_positive_minutes(Datetime, Minutes);

                false ->
                    add_negative_minutes(Datetime, 0 - Minutes)
            end
    end.

-file("src/automata/internal/calendar.gleam", 310).
?DOC(false).
-spec ceil_to_next_minute(automata@schedule@ast:date_time()) -> automata@schedule@ast:date_time().
ceil_to_next_minute(Datetime) ->
    case erlang:element(4, erlang:element(3, Datetime)) =:= 0 of
        true ->
            Datetime;

        false ->
            add_minutes(
                {date_time,
                    erlang:element(2, Datetime),
                    {time,
                        erlang:element(2, erlang:element(3, Datetime)),
                        erlang:element(3, erlang:element(3, Datetime)),
                        0}},
                1
            )
    end.

-file("src/automata/internal/calendar.gleam", 543).
?DOC(false).
-spec weekday_number(integer(), integer(), integer()) -> integer().
weekday_number(Year, Month, Day) ->
    Adjusted_year = case Month < 3 of
        true ->
            Year - 1;

        false ->
            Year
    end,
    modulo(
        ((((Adjusted_year + quotient(Adjusted_year, 4)) - quotient(
            Adjusted_year,
            100
        ))
        + quotient(Adjusted_year, 400))
        + month_offset(Month))
        + Day,
        7
    ).

-file("src/automata/internal/calendar.gleam", 144).
?DOC(false).
-spec weekday(automata@schedule@ast:date_time()) -> automata@schedule@ast:weekday().
weekday(Datetime) ->
    case weekday_number(
        erlang:element(2, erlang:element(2, Datetime)),
        erlang:element(3, erlang:element(2, Datetime)),
        erlang:element(4, erlang:element(2, Datetime))
    ) of
        0 ->
            sunday;

        1 ->
            monday;

        2 ->
            tuesday;

        3 ->
            wednesday;

        4 ->
            thursday;

        5 ->
            friday;

        _ ->
            saturday
    end.

-file("src/automata/internal/calendar.gleam", 158).
?DOC(false).
-spec day_of_week_number(automata@schedule@ast:date_time()) -> integer().
day_of_week_number(Datetime) ->
    case weekday(Datetime) of
        sunday ->
            0;

        monday ->
            1;

        tuesday ->
            2;

        wednesday ->
            3;

        thursday ->
            4;

        friday ->
            5;

        saturday ->
            6
    end.