-module(tempo@date). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -define(FILEPATH, "src/tempo/date.gleam"). -export([new/3, get_year/1, get_month/1, get_day/1, get_month_year/1, to_string/1, parse/2, parse_any/1, describe_parse_error/1, format/2, from_tuple/1, from_string/1, literal/1, describe_out_of_bounds_error/1, to_tuple/1, to_calendar_date/1, from_calendar_date/1, from_dynamic_string/1, from_unix_seconds/1, to_unix_seconds/1, from_unix_milli/1, to_unix_milli/1, from_unix_micro/1, current_local/0, current_utc/0, to_unix_micro/1, from_rata_die/1, to_rata_die/1, compare/2, is_earlier/2, is_earlier_or_equal/2, is_equal/2, is_later/2, is_later_or_equal/2, difference/2, as_period/2, add/2, subtract/2, to_day_of_week_number/1, to_day_of_week/1, day_of_week_to_short_string/1, day_of_week_to_long_string/1, next_day_of_week/2, prior_day_of_week/2, is_weekend/1, first_of_month/1, last_of_month/1]). -export_type([day_of_week/0]). -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( " Functions to use with the `Date` type in Tempo.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " import tempo/date\n" "\n" " pub fn main() {\n" " date.literal(\"2024-06-21\")\n" " |> date.to_string\n" " // -> \"2024-06-21\"\n" "\n" " date.parse(\"06/21/2024\", tempo.CustomDate(\"MM/DD/YYYY\"))\n" " |> date.to_string\n" " // -> \"2024-06-21\"\n" "\n" " date.current_local()\n" " |> date.to_string\n" " // -> \"2024-10-09\"\n" " }\n" " ```\n" "\n" " ```gleam\n" " import tempo/date\n" "\n" " pub fn is_older_than_a_week(date_str: String) {\n" " let date = date.from_string(date_str)\n" "\n" " date\n" " |> date.is_earlier(\n" " than: date |> date.subtract(days: 7)\n" " )\n" " }\n" " ```\n" ). -type day_of_week() :: sun | mon | tue | wed | thu | fri | sat. -file("src/tempo/date.gleam", 77). ?DOC( " Creates a new date and validates it.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.new(2024, 6, 13)\n" " // -> Ok(date.literal(\"2024-06-13\"))\n" " ```\n" "\n" " ```gleam\n" " date.new(2024, 6, 31)\n" " // -> Error(tempo_error.DateOutOfBounds)\n" " ```\n" ). -spec new(integer(), integer(), integer()) -> {ok, tempo:date()} | {error, tempo@error:date_out_of_bounds_error()}. new(Year, Month, Day) -> tempo:new_date(Year, Month, Day). -file("src/tempo/date.gleam", 160). ?DOC( " Gets the year value of a date.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-13\")\n" " |> date.get_year\n" " // -> 2024\n" " ```\n" ). -spec get_year(tempo:date()) -> integer(). get_year(Date) -> _pipe = Date, tempo:date_get_year(_pipe). -file("src/tempo/date.gleam", 173). ?DOC( " Gets the month value of a date.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-13\")\n" " |> date.get_month\n" " // -> tempo.Jun\n" " ```\n" ). -spec get_month(tempo:date()) -> gleam@time@calendar:month(). get_month(Date) -> _pipe = Date, tempo:date_get_month(_pipe). -file("src/tempo/date.gleam", 186). ?DOC( " Gets the day value of a date.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-13\")\n" " |> date.get_day\n" " // -> 13\n" " ```\n" ). -spec get_day(tempo:date()) -> integer(). get_day(Date) -> _pipe = Date, tempo:date_get_day(_pipe). -file("src/tempo/date.gleam", 199). ?DOC( " Gets the month value of a date.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-13\")\n" " |> date.get_month_year\n" " // -> calendar.MonthYear(tempo.Jun, 2024)\n" " ```\n" ). -spec get_month_year(tempo:date()) -> tempo:month_year(). get_month_year(Date) -> _pipe = Date, tempo:date_get_month_year(_pipe). -file("src/tempo/date.gleam", 248). -spec split_int_tuple(binary(), binary()) -> {ok, {integer(), integer(), integer()}} | {error, tempo@error:date_parse_error()}. split_int_tuple(Date, Delim) -> _pipe = gleam@string:split(Date, Delim), _pipe@1 = gleam@list:map(_pipe, fun gleam_stdlib:parse_int/1), _pipe@2 = gleam@result:all(_pipe@1), _pipe@3 = gleam@result:'try'(_pipe@2, fun(Date@1) -> case Date@1 of [Year, Month, Day] -> {ok, {Year, Month, Day}}; _ -> {error, nil} end end), gleam@result:replace_error(_pipe@3, {date_invalid_format, Date}). -file("src/tempo/date.gleam", 273). ?DOC( " Returns a string representation of a date value in the format `YYYY-MM-DD`.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-13\")\n" " |> date.to_string\n" " // -> \"2024-06-13\"\n" " ```\n" ). -spec to_string(tempo:date()) -> binary(). to_string(Date) -> tempo:date_to_string(Date). -file("src/tempo/date.gleam", 302). ?DOC( " Parses a date string in the provided format. Always prefer using\n" " this over `parse_any`. All parsed formats must have all parts of a date.\n" "\n" " Values can be escaped by putting brackets around them, like \"[Hello!] YYYY\".\n" "\n" " Available directives: YY (two-digit year), YYYY (four-digit year), M (month),\n" " MM (two-digit month), MMM (short month name), MMMM (full month name),\n" " D (day of the month), DD (two-digit day of the month),\n" "\n" " ## Example\n" "\n" " ```gleam\n" " date.parse(\"2024/06/08, 13:42:11\", \"YYYY/MM/DD\")\n" " // -> Ok(date.literal(\"2024-06-08\"))\n" " ```\n" "\n" " ```gleam\n" " date.parse(\"January 13, 2024\", \"MMMM DD, YYYY\")\n" " // -> Ok(date.literal(\"2024-01-13\"))\n" " ```\n" "\n" " ```gleam\n" " date.parse(\"Hi! 2024 11 13\", \"[Hi!] YYYY M D\")\n" " // -> Ok(date.literal(\"2024-11-13\"))\n" " ```\n" ). -spec parse(binary(), tempo:date_format()) -> {ok, tempo:date()} | {error, tempo@error:date_parse_error()}. parse(Str, Format) -> Format_str = tempo:get_date_format_str(Format), gleam@result:'try'( begin _pipe = tempo:consume_format(Str, Format_str), gleam@result:map_error( _pipe, fun(Field@0) -> {date_invalid_format, Field@0} end ) end, fun(_use0) -> {Parts, _} = _use0, tempo:find_date(Parts) end ). -file("src/tempo/date.gleam", 331). ?DOC( " Tries to parse a given date string without a known format. It will not\n" " parse two digit years and will assume the month always comes before the\n" " day in a date. Will leave out any time or offset values present.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " date.parse_any(\"2024.06.21 01:32 PM -04:00\")\n" " // -> Ok(date.literal(\"2024-06-21\"))\n" " ```\n" "\n" " ```gleam\n" " date.parse_any(\"2024.06.21\")\n" " // -> Ok(date.literal(\"2024-06-21\"))\n" " ```\n" ). -spec parse_any(binary()) -> {ok, tempo:date()} | {error, tempo@error:date_parse_error()}. parse_any(Str) -> case tempo:parse_any(Str) of {{some, Date}, _, _} -> {ok, Date}; {none, _, _} -> {error, {date_invalid_format, <<"Unable to find date in "/utf8, Str/binary>>}} end. -file("src/tempo/date.gleam", 348). ?DOC( " Converts a date parse error to a human readable error message.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " date.parse_any(\"01:32 PM\")\n" " |> snag.map_error(with: date.describe_parse_error)\n" " // -> snag.error(\"Invalid date format: 01:32 PM\")\n" " ```\n" ). -spec describe_parse_error(tempo@error:date_parse_error()) -> binary(). describe_parse_error(Error) -> tempo@error:describe_date_parse_error(Error). -file("src/tempo/date.gleam", 385). ?DOC( " Formats a date value into a string using the provided date format.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " datetime.literal(\"2024-12-26T13:02:01-04:00\")\n" " |> datetime.format(tempo.ISO8601Date)\n" " // -> \"2024-12-26\"\n" " ```\n" "\n" " ```gleam\n" " datetime.literal(\"2024-06-21T13:42:11.314-04:00\")\n" " |> datetime.format(tempo.CustomDate(\"ddd @ h:mm A (z)\"))\n" " // -> \"Fri @ 1:42 PM (-04)\"\n" " ```\n" "\n" " ```gleam\n" " datetime.literal(\"2024-06-03T09:02:01-04:00\")\n" " |> datetime.format(tempo.CustomDate(\"YY YYYY M MM MMM MMMM D DD d dd ddd\"))\n" " // -------------------------------> \"24 2024 6 06 Jun June 3 03 1 Mo Mon\"\n" " ```\n" "\n" " ```gleam\n" " datetime.literal(\"2024-06-03T09:02:01.014920202-00:00\")\n" " |> datetime.format(tempo.CustomDate(\"dddd SSS SSSS SSSSS Z ZZ z\"))\n" " // -> \"Monday 014 014920 014920202 -00:00 -0000 Z\"\n" " ```\n" "\n" " ```gleam\n" " datetime.literal(\"2024-06-03T13:02:01-04:00\")\n" " |> datetime.format(tempo.CustomDate((\"H HH h hh m mm s ss a A [An ant]\"))\n" " // -------------------------------> \"13 13 1 01 2 02 1 01 pm PM An ant\"\n" " ```\n" ). -spec format(tempo:date(), tempo:date_format()) -> binary(). format(Date, Format) -> Format_str = tempo:get_date_format_str(Format), Re@1 = case gleam@regexp: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}|z{1,2}|S{3,4}|GMT|."/utf8>> ) of {ok, Re} -> Re; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"tempo/date"/utf8>>, function => <<"format"/utf8>>, line => 388, value => _assert_fail, start => 9847, 'end' => 9905, pattern_start => 9858, pattern_end => 9864}) end, _pipe = gleam@regexp:scan(Re@1, Format_str), _pipe@1 = lists:reverse(_pipe), _pipe@2 = gleam@list:fold(_pipe@1, [], fun(Acc, Match) -> case Match of {match, Content, []} -> [tempo:date_replace_format(Content, Date) | Acc]; {match, _, [{some, Sub}]} -> [Sub | Acc]; {match, Content@1, _} -> [Content@1 | Acc] end end), gleam@string:join(_pipe@2, <<""/utf8>>). -file("src/tempo/date.gleam", 430). ?DOC( " Returns a date value from a tuple of ints if the values represent the\n" " years, month, and day of a valid date. The year must be greater than 1000.\n" "\n" " Years less than 1000 are technically valid years, but are not common\n" " and usually indicate that either a non-year value was passed as the year\n" " or a two digit year was passed (which are too abiguous to be confidently\n" " accepted).\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.from_tuple(#(2024, 6, 13))\n" " // -> Ok(date.literal(\"2024-06-13\"))\n" " ```\n" "\n" " ```gleam\n" " date.from_tuple(#(98, 6, 13))\n" " // -> Error(tempo_error.DateOutOfBounds)\n" " ```\n" ). -spec from_tuple({integer(), integer(), integer()}) -> {ok, tempo:date()} | {error, tempo@error:date_out_of_bounds_error()}. from_tuple(Date) -> tempo:date_from_tuple(Date). -file("src/tempo/date.gleam", 223). ?DOC( " Parses a date string in the format `YYYY-MM-DD`, `YYYY-M-D`, `YYYY/MM/DD`,\n" " `YYYY/M/D`, `YYYY.MM.DD`, `YYYY.M.D`, `YYYY_MM_DD`, `YYYY_M_D`, `YYYY MM DD`,\n" " `YYYY M D`, or `YYYYMMDD`.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.from_string(\"2024-06-13\")\n" " // -> Ok(date.literal(\"2024-06-13\"))\n" " ```\n" "\n" " ```gleam\n" " date.from_string(\"20240613\")\n" " // -> Ok(date.literal(\"2024-06-13\"))\n" " ```\n" "\n" " ```gleam\n" " date.from_string(\"2409\")\n" " // -> Error(tempo_error.DateInvalidFormat)\n" " ```\n" ). -spec from_string(binary()) -> {ok, tempo:date()} | {error, tempo@error:date_parse_error()}. from_string(Date) -> gleam@result:'try'( begin _pipe = split_int_tuple(Date, <<"-"/utf8>>), _pipe@1 = gleam@result:try_recover( _pipe, fun(_) -> split_int_tuple(Date, <<"/"/utf8>>) end ), _pipe@2 = gleam@result:try_recover( _pipe@1, fun(_) -> split_int_tuple(Date, <<"."/utf8>>) end ), _pipe@3 = gleam@result:try_recover( _pipe@2, fun(_) -> split_int_tuple(Date, <<"_"/utf8>>) end ), _pipe@4 = gleam@result:try_recover( _pipe@3, fun(_) -> split_int_tuple(Date, <<" "/utf8>>) end ), gleam@result:try_recover( _pipe@4, fun(_) -> Year = begin _pipe@5 = gleam@string:slice(Date, 0, 4), gleam_stdlib:parse_int(_pipe@5) end, Month = begin _pipe@6 = gleam@string:slice(Date, 4, 2), gleam_stdlib:parse_int(_pipe@6) end, Day = begin _pipe@7 = gleam@string:slice(Date, 6, 2), gleam_stdlib:parse_int(_pipe@7) end, case {Year, Month, Day} of {{ok, Year@1}, {ok, Month@1}, {ok, Day@1}} -> {ok, {Year@1, Month@1, Day@1}}; {_, _, _} -> {error, {date_invalid_format, Date}} end end ) end, fun(Parts) -> _pipe@8 = from_tuple(Parts), gleam@result:map_error( _pipe@8, fun(_capture) -> {date_out_of_bounds, Date, _capture} end ) end ). -file("src/tempo/date.gleam", 111). ?DOC( " Creates a new date value from a string literal, but will panic if\n" " the string is invalid. Accepted formats are `YYYY-MM-DD`, `YYYY-M-D`,\n" " `YYYY/MM/DD`, `YYYY/M/D`, `YYYY.MM.DD`, `YYYY.M.D`, `YYYY_MM_DD`,\n" " `YYYY_M_D`, `YYYY MM DD`, `YYYY M D`, or `YYYYMMDD`.\n" "\n" " Useful for declaring date literals that you know are valid within your\n" " program.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-13\")\n" " |> date.to_string\n" " // -> \"2024-06-13\"\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"20240613\")\n" " |> date.to_string\n" " // -> \"2024-06-13\"\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2409\")\n" " // -> panic\n" " ```\n" ). -spec literal(binary()) -> tempo:date(). literal(Date) -> case from_string(Date) of {ok, Date@1} -> Date@1; {error, {date_invalid_format, _}} -> erlang:error(#{gleam_error => panic, message => <<"Invalid date literal format"/utf8>>, file => <>, module => <<"tempo/date"/utf8>>, function => <<"literal"/utf8>>, line => 115}); {error, {date_out_of_bounds, _, {date_day_out_of_bounds, _}}} -> erlang:error(#{gleam_error => panic, message => <<"Invalid date literal day value"/utf8>>, file => <>, module => <<"tempo/date"/utf8>>, function => <<"literal"/utf8>>, line => 117}); {error, {date_out_of_bounds, _, {date_month_out_of_bounds, _}}} -> erlang:error(#{gleam_error => panic, message => <<"Invalid date literal month value"/utf8>>, file => <>, module => <<"tempo/date"/utf8>>, function => <<"literal"/utf8>>, line => 119}); {error, {date_out_of_bounds, _, {date_year_out_of_bounds, _}}} -> erlang:error(#{gleam_error => panic, message => <<"Invalid date literal year value"/utf8>>, file => <>, module => <<"tempo/date"/utf8>>, function => <<"literal"/utf8>>, line => 121}) end. -file("src/tempo/date.gleam", 445). ?DOC( " Converts a date out of bounds error to a human readable error message.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " date.from_tuple(#(98, 6, 13))\n" " |> snag.map_error(with: date.describe_out_of_bounds_error)\n" " // -> snag.error(\"Year out of bounds in date: 98\")\n" " ```\n" ). -spec describe_out_of_bounds_error(tempo@error:date_out_of_bounds_error()) -> binary(). describe_out_of_bounds_error(Error) -> tempo@error:describe_date_out_of_bounds_error(Error). -file("src/tempo/date.gleam", 459). ?DOC( " Returns a tuple of ints from a date value that represent the year, month,\n" " and day of the date.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-14\")\n" " |> date.to_tuple\n" " // -> #(2024, 6, 14)\n" " ```\n" ). -spec to_tuple(tempo:date()) -> {integer(), integer(), integer()}. to_tuple(Date) -> {begin _pipe = Date, tempo:date_get_year(_pipe) end, tempo@month:to_int( begin _pipe@1 = Date, tempo:date_get_month(_pipe@1) end ), begin _pipe@2 = Date, tempo:date_get_day(_pipe@2) end}. -file("src/tempo/date.gleam", 468). ?DOC(" Converts a tempo date to a calendar date.\n"). -spec to_calendar_date(tempo:date()) -> gleam@time@calendar:date(). to_calendar_date(Date) -> tempo:date_to_calendar_date(Date). -file("src/tempo/date.gleam", 473). ?DOC(" Converts a calendar date to a tempo date.\n"). -spec from_calendar_date(gleam@time@calendar:date()) -> {ok, tempo:date()} | {error, tempo@error:date_out_of_bounds_error()}. from_calendar_date(Date) -> {date, Year, Month, Day} = Date, from_tuple( {Year, begin _pipe = Month, tempo@month:to_int(_pipe) end, Day} ). -file("src/tempo/date.gleam", 502). ?DOC( " Checks if a dynamic value is a valid date string, and returns the\n" " date if it is.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " dynamic.string(\"2024-06-21\")\n" " |> date.from_dynamic_string\n" " // -> Ok(date.literal(\"2024-06-21\"))\n" " ```\n" "\n" " ```gleam\n" " dynamic.string(\"153\")\n" " |> datetime.from_dynamic_string\n" " // -> Error([\n" " // decode.DecodeError(\n" " // expected: \"tempo.Date\",\n" " // found: \"Invalid format: 153\",\n" " // path: [],\n" " // ),\n" " // ])\n" " ```\n" ). -spec from_dynamic_string(gleam@dynamic:dynamic_()) -> {ok, tempo:date()} | {error, list(gleam@dynamic@decode:decode_error())}. from_dynamic_string(Dynamic_string) -> gleam@result:'try'( begin _pipe = gleam@dynamic@decode:run( Dynamic_string, {decoder, fun gleam@dynamic@decode:decode_string/1} ), gleam@result:map_error( _pipe, fun(Errs) -> gleam@list:map( Errs, fun(Err) -> {decode_error, erlang:element(2, Err), erlang:element(3, Err), erlang:element(4, Err)} end ) end ) end, fun(Date) -> case from_string(Date) of {ok, Date@1} -> {ok, Date@1}; {error, Tempo_error} -> {error, [{decode_error, <<"tempo.Date"/utf8>>, case Tempo_error of {date_invalid_format, Msg} -> Msg; {date_out_of_bounds, Msg@1, _} -> Msg@1 end, []}]} end end ). -file("src/tempo/date.gleam", 548). ?DOC(false). -spec from_unix_seconds(integer()) -> tempo:date(). from_unix_seconds(Unix_ts) -> tempo:date_from_unix_seconds(Unix_ts). -file("src/tempo/date.gleam", 568). ?DOC(false). -spec to_unix_seconds(tempo:date()) -> integer(). to_unix_seconds(Date) -> tempo:date_to_unix_seconds(Date). -file("src/tempo/date.gleam", 588). ?DOC(false). -spec from_unix_milli(integer()) -> tempo:date(). from_unix_milli(Unix_ts) -> from_unix_seconds(Unix_ts div 1000). -file("src/tempo/date.gleam", 608). ?DOC(false). -spec to_unix_milli(tempo:date()) -> integer(). to_unix_milli(Date) -> to_unix_seconds(Date) * 1000. -file("src/tempo/date.gleam", 628). ?DOC(false). -spec from_unix_micro(integer()) -> tempo:date(). from_unix_micro(Unix_ts) -> tempo:date_from_unix_micro(Unix_ts). -file("src/tempo/date.gleam", 134). ?DOC( " Gets the current local date of the host.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.current_local()\n" " |> date.to_string\n" " // -> \"2024-06-13\"\n" " ```\n" ). -spec current_local() -> tempo:date(). current_local() -> _pipe = (tempo_ffi:now() + tempo:offset_local_micro()), from_unix_micro(_pipe). -file("src/tempo/date.gleam", 147). ?DOC( " Gets the current UTC date of the host.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.current_utc()\n" " |> date.to_string\n" " // -> \"2024-06-14\"\n" " ```\n" ). -spec current_utc() -> tempo:date(). current_utc() -> _pipe = tempo_ffi:now(), from_unix_micro(_pipe). -file("src/tempo/date.gleam", 648). ?DOC(false). -spec to_unix_micro(tempo:date()) -> integer(). to_unix_micro(Date) -> tempo:date_to_unix_micro(Date). -file("src/tempo/date.gleam", 661). ?DOC( " Creates a date from a Rata Die value.\n" " Adapted from the very nice Rada Gleam library!\n" "\n" " ## Example\n" "\n" " ```gleam\n" " date.from_rata_die(739_050)\n" " // -> date.literal(\"2024-06-13\")\n" " ```\n" ). -spec from_rata_die(integer()) -> tempo:date(). from_rata_die(Rata_die) -> tempo:date_from_rata_die(Rata_die). -file("src/tempo/date.gleam", 675). ?DOC( " Returns the Rata Die value of the date as an Int.\n" " Adapted from the very nice Rada Gleam library!\n" "\n" " ## Example\n" "\n" " ```gleam\n" " date.literal(\"2024-06-13\")\n" " |> date.to_rata_die\n" " // -> 739_050\n" " ```\n" ). -spec to_rata_die(tempo:date()) -> integer(). to_rata_die(Date) -> tempo:date_to_rata_die(Date). -file("src/tempo/date.gleam", 700). ?DOC( " Compares two dates.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.compare(to: date.literal(\"2024-06-12\"))\n" " // -> order.Eq\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2024-05-12\")\n" " |> date.compare(to: date.literal(\"2024-06-13\"))\n" " // -> order.Lt\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2034-06-12\")\n" " |> date.compare(to: date.literal(\"2024-06-11\"))\n" " // -> order.Gt\n" " ```\n" ). -spec compare(tempo:date(), tempo:date()) -> gleam@order:order(). compare(A, B) -> tempo:date_compare(A, B). -file("src/tempo/date.gleam", 719). ?DOC( " Checks of the first date is earlier than the second date.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.is_earlier(than: date.literal(\"2024-06-13\"))\n" " // -> True\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.is_earlier(than: date.literal(\"2024-06-12\"))\n" " // -> False\n" " ```\n" ). -spec is_earlier(tempo:date(), tempo:date()) -> boolean(). is_earlier(A, B) -> tempo:date_is_earlier(A, B). -file("src/tempo/date.gleam", 737). ?DOC( " Checks if the first date is earlier than or equal to the second date.\n" "\n" " ## Examples\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.is_earlier_or_equal(to: date.literal(\"2024-06-12\"))\n" " // -> True\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.is_earlier_or_equal(to: date.literal(\"2024-06-11\"))\n" " // -> False\n" " ```\n" ). -spec is_earlier_or_equal(tempo:date(), tempo:date()) -> boolean(). is_earlier_or_equal(A, B) -> tempo:date_is_earlier_or_equal(A, B). -file("src/tempo/date.gleam", 750). ?DOC( " Checks if two dates are equal.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.is_equal(to: date.literal(\"2024-06-12\"))\n" " // -> True\n" " ```\n" ). -spec is_equal(tempo:date(), tempo:date()) -> boolean(). is_equal(A, B) -> tempo:date_is_equal(A, B). -file("src/tempo/date.gleam", 769). ?DOC( " Checks if the first date is later than the second date.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-14\")\n" " |> date.is_later(than: date.literal(\"2024-06-13\"))\n" " // -> True\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.is_later(than: date.literal(\"2024-06-12\"))\n" " // -> False\n" " ```\n" ). -spec is_later(tempo:date(), tempo:date()) -> boolean(). is_later(A, B) -> tempo:date_is_later(A, B). -file("src/tempo/date.gleam", 788). ?DOC( " Checks if the first date is later than or equal to the second date.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.is_later_or_equal(to: date.literal(\"2024-06-12\"))\n" " // -> True\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.is_later_or_equal(to: date.literal(\"2024-06-13\"))\n" " // -> False\n" " ```\n" ). -spec is_later_or_equal(tempo:date(), tempo:date()) -> boolean(). is_later_or_equal(A, B) -> tempo:date_is_later_or_equal(A, B). -file("src/tempo/date.gleam", 807). ?DOC( " Gets the difference between two dates.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.difference(from: date.literal(\"2024-06-23\"))\n" " // -> 11\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2024-06-03\")\n" " |> date.difference(from: date.literal(\"2024-06-11\"))\n" " // -> -9\n" " ```\n" ). -spec difference(tempo:date(), tempo:date()) -> integer(). difference(A, B) -> tempo:date_days_apart(A, B). -file("src/tempo/date.gleam", 829). ?DOC( " Creates a period between the first date at 00:00:00 and the second date at\n" " 24:00:00. Periods only represent positive datetime differences.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.as_period(end: date.literal(\"2024-06-23\"))\n" " |> period.as_days\n" " // -> 11\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.as_period(start: date.literal(\"2024-06-09\"))\n" " |> period.comprising_dates\n" " // -> [\"2024-06-09\", \"2024-06-10\", \"2024-06-11\", \"2024-06-12\"]\n" " ```\n" ). -spec as_period(tempo:date(), tempo:date()) -> tempo:period(). as_period(Start, End) -> tempo:period_new_date(Start, End). -file("src/tempo/date.gleam", 848). ?DOC( " Adds a number of days to a date.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.add(days: 1)\n" " // -> date.literal(\"2024-06-13\")\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.add(days: 12)\n" " // -> date.literal(\"2024-06-24\")\n" " ```\n" ). -spec add(tempo:date(), integer()) -> tempo:date(). add(Date, Days) -> tempo:date_add(Date, Days). -file("src/tempo/date.gleam", 867). ?DOC( " Subtracts a number of days from a date.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.subtract(days: 1)\n" " // -> date.literal(\"2024-06-11\")\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2024-06-12\")\n" " |> date.subtract(days: 12)\n" " // -> date.literal(\"2024-05-31\")\n" " ```\n" ). -spec subtract(tempo:date(), integer()) -> tempo:date(). subtract(Date, Days) -> tempo:date_subtract(Date, Days). -file("src/tempo/date.gleam", 881). ?DOC( " Returns the number of the day of week a date falls on.\n" " Will be incorrect for dates before 1752 and dates after 2300.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-21\")\n" " |> date.to_day_of_week_number\n" " // -> 5\n" " ```\n" ). -spec to_day_of_week_number(tempo:date()) -> integer(). to_day_of_week_number(Date) -> tempo:date_to_day_of_week_number(Date). -file("src/tempo/date.gleam", 895). ?DOC( " Returns the day of week a date falls on.\n" " Will be incorrect for dates before 1752 and dates after 2300.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-20\")\n" " |> date.to_day_of_week\n" " // -> Thur\n" " ```\n" ). -spec to_day_of_week(tempo:date()) -> day_of_week(). to_day_of_week(Date) -> case to_day_of_week_number(Date) of 0 -> sun; 1 -> mon; 2 -> tue; 3 -> wed; 4 -> thu; 5 -> fri; 6 -> sat; _ -> erlang:error(#{gleam_error => panic, message => <<"Invalid day of week found after modulo by 7"/utf8>>, file => <>, module => <<"tempo/date"/utf8>>, function => <<"to_day_of_week"/utf8>>, line => 904}) end. -file("src/tempo/date.gleam", 916). ?DOC( " Returns the short string representation of a day of the week.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date|> tempo.date_get_day_of_week_to_short_string(date.Mon)\n" " // -> \"Mon\"\n" " ```\n" ). -spec day_of_week_to_short_string(day_of_week()) -> binary(). day_of_week_to_short_string(Day_of_week) -> case Day_of_week of sun -> <<"Sun"/utf8>>; mon -> <<"Mon"/utf8>>; tue -> <<"Tue"/utf8>>; wed -> <<"Wed"/utf8>>; thu -> <<"Thu"/utf8>>; fri -> <<"Fri"/utf8>>; sat -> <<"Sat"/utf8>> end. -file("src/tempo/date.gleam", 936). ?DOC( " Returns the long string representation of a day of the week.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date|> tempo.date_get_day_of_week_to_long_string(date.Fri)\n" " // -> \"Friday\"\n" " ```\n" ). -spec day_of_week_to_long_string(day_of_week()) -> binary(). day_of_week_to_long_string(Day_of_week) -> case Day_of_week of sun -> <<"Sunday"/utf8>>; mon -> <<"Monday"/utf8>>; tue -> <<"Tuesday"/utf8>>; wed -> <<"Wednesday"/utf8>>; thu -> <<"Thursday"/utf8>>; fri -> <<"Friday"/utf8>>; sat -> <<"Saturday"/utf8>> end. -file("src/tempo/date.gleam", 964). ?DOC( " Gets the date of the next specified day of the week, exclusive of\n" " the passed date.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-21\")\n" " |> date.next_day_of_week(date.Mon)\n" " // -> date.literal(\"2024-06-24\")\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2024-06-21\")\n" " |> date.next_day_of_week(date.Fri)\n" " // -> date.literal(\"2024-06-28\")\n" " ```\n" ). -spec next_day_of_week(tempo:date(), day_of_week()) -> tempo:date(). next_day_of_week(Date, Dow) -> Next = begin _pipe = Date, add(_pipe, 1) end, case begin _pipe@1 = Next, to_day_of_week(_pipe@1) end =:= Dow of true -> Next; false -> next_day_of_week(Next, Dow) end. -file("src/tempo/date.gleam", 992). ?DOC( " Gets the date of the prior specified day of the week, exclusive of\n" " the passed date.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-21\")\n" " |> date.prior_day_of_week(date.Mon)\n" " // -> date.literal(\"2024-06-17\")\n" " ```\n" "\n" " ```gleam\n" " date.literal(\"2024-06-21\")\n" " |> date.prior_day_of_week(date.Fri)\n" " // -> date.literal(\"2024-06-14\")\n" " ```\n" ). -spec prior_day_of_week(tempo:date(), day_of_week()) -> tempo:date(). prior_day_of_week(Date, Dow) -> Prior = begin _pipe = Date, subtract(_pipe, 1) end, case begin _pipe@1 = Prior, to_day_of_week(_pipe@1) end =:= Dow of true -> Prior; false -> prior_day_of_week(Prior, Dow) end. -file("src/tempo/date.gleam", 1013). ?DOC( " Checks if a date falls in a weekend.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-22\")\n" " |> date.is_weekend\n" " // -> True\n" " ```\n" ). -spec is_weekend(tempo:date()) -> boolean(). is_weekend(Date) -> case to_day_of_week(Date) of sat -> true; sun -> true; _ -> false end. -file("src/tempo/date.gleam", 1029). ?DOC( " Gets the first date of the month a date occurs in.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-06-21\")\n" " |> date.first_of_month\n" " // -> date.literal(\"2024-06-01\")\n" " ```\n" ). -spec first_of_month(tempo:date()) -> tempo:date(). first_of_month(Date) -> Calendar_date = tempo:date_to_calendar_date(Date), _pipe = {date, erlang:element(2, Calendar_date), erlang:element(3, Calendar_date), 1}, tempo:date_from_calendar_date(_pipe). -file("src/tempo/date.gleam", 1044). ?DOC( " Gets the last date of the month a date occurs in.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " date.literal(\"2024-02-13\")\n" " |> date.last_of_month\n" " // -> date.literal(\"2024-02-29\")\n" " ```\n" ). -spec last_of_month(tempo:date()) -> tempo:date(). last_of_month(Date) -> Calendar_date = tempo:date_to_calendar_date(Date), _pipe = {date, erlang:element(2, Calendar_date), erlang:element(3, Calendar_date), tempo@month:days( erlang:element(3, Calendar_date), erlang:element(2, Calendar_date) )}, tempo:date_from_calendar_date(_pipe).