-module(dateformat). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/dateformat.gleam"). -export([compile_format/1, format/2]). -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( " Enables formatting of birl Time records\n" "\n" " | | **Token** | **Output** |\n" " |------------------------|-----------|--------------------------------|\n" " | **Hour of Day** | HH | 00 - 23 |\n" " | | H | 0 - 23 |\n" " | | hh | 01 - 12 |\n" " | | h | 1 - 12 |\n" " | **Minute of Hour** | mm | 00 - 59 |\n" " | | m | 0 - 59 |\n" " | **Second of Minute** | ss | 00 - 59 |\n" " | | s | 0 - 59 |\n" " | **Fraction of Second** | SSS | 000 - 999 |\n" " | | SS | 00 - 99 |\n" " | | S | 0 - 9 |\n" " | **Period of Day** | A | AM or PM |\n" " | | a | am or pm |\n" " | **Time Zone/Offsets** | Z | -14:00 - +14:00 |\n" " | | z | Europe/London, US/Central, etc |\n" " | **Unix Timestamp** | X | Unix seconds |\n" " | | x | Unix milliseconds |\n" " | **Day of Week** | d | 0 - 6 |\n" " | | do | 0th - 6th |\n" " | | dd | Su - Sa |\n" " | | ddd | Sun - Sat |\n" " | | dddd | Sunday - Saturday |\n" " | **Day of Week (ISO)** | E | 1 - 7 |\n" " | **Day of Month** | D | 1 - 31 |\n" " | | Do | 1st - 31st |\n" " | | DD | 01 - 31 |\n" " | **Day of Year** | DDD | 1 - 366 |\n" " | | DDDo | 1st - 366th |\n" " | | DDDD | 001 - 366 |\n" " | **Week of Year (ISO)** | W | 1 - 53 |\n" " | | Wo | 1st - 53rd |\n" " | | WW | 01 - 53 |\n" " | **Month** | M | 1 - 12 |\n" " | | Mo | 1st - 12th |\n" " | | MM | 01 - 12 |\n" " | | MMM | Jan - Dec |\n" " | | MMMM | January - December |\n" " | **Quarter** | Q | 1 - 4 |\n" " | | Qo | 1st - 4th |\n" " | **Year** | YY | 70 - 69 |\n" " | | YYYY | 1970 - 2069 |\n" "\n" " Other characters are just output as is\n" " Characters contained with [...] will be output without formats\n" "\n" ). -file("src/dateformat.gleam", 91). -spec run_format(list(fun((birl:time()) -> binary())), birl:time()) -> binary(). run_format(Fmts, Time) -> _pipe = gleam@list:fold( Fmts, gleam@string_tree:new(), fun(Acc, Fmt) -> gleam@string_tree:append(Acc, Fmt(Time)) end ), unicode:characters_to_binary(_pipe). -file("src/dateformat.gleam", 251). -spec date(birl:time()) -> integer(). date(Time) -> Day = begin _pipe = Time, birl:get_day(_pipe) end, erlang:element(4, Day). -file("src/dateformat.gleam", 98). -spec parse_match(gleam@regexp:match()) -> {ok, fun((birl:time()) -> binary())} | {error, nil}. parse_match(Match) -> case erlang:element(2, Match) of <<"Z"/utf8>> -> {ok, fun(T) -> case begin _pipe = T, birl:get_offset(_pipe) end of <<"Z"/utf8>> -> <<"+00:00"/utf8>>; Z -> Z end end}; <<"z"/utf8>> -> {ok, fun(T@1) -> _pipe@1 = T@1, _pipe@2 = birl:get_timezone(_pipe@1), gleam@option:unwrap(_pipe@2, <<""/utf8>>) end}; <<"X"/utf8>> -> {ok, fun(T@2) -> _pipe@3 = T@2, _pipe@4 = birl:to_unix(_pipe@3), erlang:integer_to_binary(_pipe@4) end}; <<"x"/utf8>> -> {ok, fun(T@3) -> _pipe@5 = T@3, _pipe@6 = birl:to_unix_milli(_pipe@5), erlang:integer_to_binary(_pipe@6) end}; <<"A"/utf8>> -> {ok, fun(T@4) -> dateformat@internal@time:to_day_period(T@4) end}; <<"a"/utf8>> -> {ok, fun(T@5) -> _pipe@7 = dateformat@internal@time:to_day_period(T@5), string:lowercase(_pipe@7) end}; <<"HH"/utf8>> -> {ok, fun(T@6) -> _pipe@8 = T@6, _pipe@9 = dateformat@internal@time:to_hour_of_day(_pipe@8), _pipe@10 = erlang:integer_to_binary(_pipe@9), gleam@string:pad_start(_pipe@10, 2, <<"0"/utf8>>) end}; <<"H"/utf8>> -> {ok, fun(T@7) -> _pipe@11 = T@7, _pipe@12 = dateformat@internal@time:to_hour_of_day(_pipe@11), erlang:integer_to_binary(_pipe@12) end}; <<"hh"/utf8>> -> {ok, fun(T@8) -> _pipe@13 = T@8, _pipe@14 = dateformat@internal@time:to_hour_of_period( _pipe@13 ), _pipe@15 = erlang:integer_to_binary(_pipe@14), gleam@string:pad_start(_pipe@15, 2, <<"0"/utf8>>) end}; <<"h"/utf8>> -> {ok, fun(T@9) -> _pipe@16 = T@9, _pipe@17 = dateformat@internal@time:to_hour_of_period( _pipe@16 ), erlang:integer_to_binary(_pipe@17) end}; <<"mm"/utf8>> -> {ok, fun(T@10) -> _pipe@18 = T@10, _pipe@19 = dateformat@internal@time:to_minute_of_hour( _pipe@18 ), _pipe@20 = erlang:integer_to_binary(_pipe@19), gleam@string:pad_start(_pipe@20, 2, <<"0"/utf8>>) end}; <<"m"/utf8>> -> {ok, fun(T@11) -> _pipe@21 = T@11, _pipe@22 = dateformat@internal@time:to_minute_of_hour( _pipe@21 ), erlang:integer_to_binary(_pipe@22) end}; <<"ss"/utf8>> -> {ok, fun(T@12) -> _pipe@23 = T@12, _pipe@24 = dateformat@internal@time:to_second_of_minute( _pipe@23 ), _pipe@25 = erlang:integer_to_binary(_pipe@24), gleam@string:pad_start(_pipe@25, 2, <<"0"/utf8>>) end}; <<"s"/utf8>> -> {ok, fun(T@13) -> _pipe@26 = T@13, _pipe@27 = dateformat@internal@time:to_second_of_minute( _pipe@26 ), erlang:integer_to_binary(_pipe@27) end}; <<"SSS"/utf8>> -> {ok, fun(T@14) -> _pipe@28 = T@14, _pipe@29 = dateformat@internal@time:to_milli_of_second( _pipe@28 ), _pipe@30 = erlang:integer_to_binary(_pipe@29), gleam@string:pad_start(_pipe@30, 3, <<"0"/utf8>>) end}; <<"SS"/utf8>> -> {ok, fun(T@15) -> _pipe@32 = begin _pipe@31 = T@15, dateformat@internal@time:to_milli_of_second(_pipe@31) end div 10, _pipe@33 = erlang:integer_to_binary(_pipe@32), gleam@string:pad_start(_pipe@33, 2, <<"0"/utf8>>) end}; <<"S"/utf8>> -> {ok, fun(T@16) -> _pipe@35 = begin _pipe@34 = T@16, dateformat@internal@time:to_milli_of_second(_pipe@34) end div 100, erlang:integer_to_binary(_pipe@35) end}; <<"YYYY"/utf8>> -> {ok, fun(T@17) -> _pipe@37 = erlang:element( 2, begin _pipe@36 = T@17, birl:get_day(_pipe@36) end ), erlang:integer_to_binary(_pipe@37) end}; <<"YY"/utf8>> -> {ok, fun(T@18) -> _pipe@39 = erlang:element( 2, begin _pipe@38 = T@18, birl:get_day(_pipe@38) end ) rem 100, erlang:integer_to_binary(_pipe@39) end}; <<"Q"/utf8>> -> {ok, fun(T@19) -> _pipe@42 = (begin _pipe@40 = T@19, _pipe@41 = birl:month(_pipe@40), dateformat@internal@month:to_month_num(_pipe@41) end div 4) + 1, erlang:integer_to_binary(_pipe@42) end}; <<"Qo"/utf8>> -> {ok, fun(T@20) -> _pipe@45 = (begin _pipe@43 = T@20, _pipe@44 = birl:month(_pipe@43), dateformat@internal@month:to_month_num(_pipe@44) end div 4) + 1, dateformat@internal@util:to_ordinal(_pipe@45) end}; <<"W"/utf8>> -> {ok, fun(T@21) -> _pipe@46 = T@21, _pipe@47 = dateformat@internal@day:to_iso_week_of_year( _pipe@46 ), erlang:integer_to_binary(_pipe@47) end}; <<"WW"/utf8>> -> {ok, fun(T@22) -> _pipe@48 = T@22, _pipe@49 = dateformat@internal@day:to_iso_week_of_year( _pipe@48 ), _pipe@50 = erlang:integer_to_binary(_pipe@49), gleam@string:pad_start(_pipe@50, 2, <<"0"/utf8>>) end}; <<"Wo"/utf8>> -> {ok, fun(T@23) -> _pipe@51 = T@23, _pipe@52 = dateformat@internal@day:to_iso_week_of_year( _pipe@51 ), dateformat@internal@util:to_ordinal(_pipe@52) end}; <<"E"/utf8>> -> {ok, fun(T@24) -> _pipe@53 = T@24, _pipe@54 = dateformat@internal@day:to_day_of_week( _pipe@53, true ), erlang:integer_to_binary(_pipe@54) end}; <<"d"/utf8>> -> {ok, fun(T@25) -> _pipe@55 = T@25, _pipe@56 = dateformat@internal@day:to_day_of_week( _pipe@55, false ), erlang:integer_to_binary(_pipe@56) end}; <<"do"/utf8>> -> {ok, fun(T@26) -> _pipe@57 = T@26, _pipe@58 = dateformat@internal@day:to_day_of_week( _pipe@57, false ), dateformat@internal@util:to_ordinal(_pipe@58) end}; <<"dd"/utf8>> -> {ok, fun(T@27) -> _pipe@59 = T@27, dateformat@internal@day:to_weekday_shorter_string(_pipe@59) end}; <<"ddd"/utf8>> -> {ok, fun(T@28) -> _pipe@60 = T@28, dateformat@internal@day:to_weekday_short_string(_pipe@60) end}; <<"dddd"/utf8>> -> {ok, fun(T@29) -> _pipe@61 = T@29, dateformat@internal@day:to_weekday_string(_pipe@61) end}; <<"D"/utf8>> -> {ok, fun(T@30) -> _pipe@62 = T@30, _pipe@63 = date(_pipe@62), erlang:integer_to_binary(_pipe@63) end}; <<"Do"/utf8>> -> {ok, fun(T@31) -> _pipe@64 = T@31, _pipe@65 = date(_pipe@64), dateformat@internal@util:to_ordinal(_pipe@65) end}; <<"DD"/utf8>> -> {ok, fun(T@32) -> _pipe@66 = T@32, _pipe@67 = date(_pipe@66), _pipe@68 = erlang:integer_to_binary(_pipe@67), gleam@string:pad_start(_pipe@68, 2, <<"0"/utf8>>) end}; <<"DDD"/utf8>> -> {ok, fun(T@33) -> _pipe@69 = T@33, _pipe@70 = dateformat@internal@day:to_day_of_year(_pipe@69), erlang:integer_to_binary(_pipe@70) end}; <<"DDDo"/utf8>> -> {ok, fun(T@34) -> _pipe@71 = T@34, _pipe@72 = dateformat@internal@day:to_day_of_year(_pipe@71), dateformat@internal@util:to_ordinal(_pipe@72) end}; <<"DDDD"/utf8>> -> {ok, fun(T@35) -> _pipe@73 = T@35, _pipe@74 = dateformat@internal@day:to_day_of_year(_pipe@73), _pipe@75 = erlang:integer_to_binary(_pipe@74), gleam@string:pad_start(_pipe@75, 2, <<"0"/utf8>>) end}; <<"M"/utf8>> -> {ok, fun(T@36) -> _pipe@76 = T@36, _pipe@77 = birl:month(_pipe@76), _pipe@78 = dateformat@internal@month:to_month_num(_pipe@77), erlang:integer_to_binary(_pipe@78) end}; <<"MM"/utf8>> -> {ok, fun(T@37) -> _pipe@79 = T@37, _pipe@80 = birl:month(_pipe@79), _pipe@81 = dateformat@internal@month:to_month_num(_pipe@80), _pipe@82 = erlang:integer_to_binary(_pipe@81), gleam@string:pad_start(_pipe@82, 2, <<"0"/utf8>>) end}; <<"MMM"/utf8>> -> {ok, fun(T@38) -> _pipe@83 = T@38, _pipe@84 = birl:month(_pipe@83), dateformat@internal@month:to_short_month(_pipe@84) end}; <<"MMMM"/utf8>> -> {ok, fun(T@39) -> _pipe@85 = T@39, _pipe@86 = birl:month(_pipe@85), dateformat@internal@month:to_long_month(_pipe@86) end}; <<"Mo"/utf8>> -> {ok, fun(T@40) -> _pipe@87 = T@40, _pipe@88 = birl:month(_pipe@87), dateformat@internal@month:to_ordinal_month(_pipe@88) end}; El -> case erlang:element(3, Match) of [] -> {ok, fun(_) -> El end}; [{some, El@1}] -> {ok, fun(_) -> El@1 end}; _ -> {error, nil} end end. -file("src/dateformat.gleam", 78). ?DOC( " Generates a function that can then be used to format\n" " given Time records\n" " Can return error if the format doesn't parse successfully\n" ). -spec compile_format(binary()) -> {ok, fun((birl:time()) -> binary())} | {error, nil}. compile_format(Fmt) -> Regex@1 = case gleam@regexp:from_string( <<"\\[([^\\]]*)\\]|(?:Mo|M{1,4}|DDDo|Do|D{1,4}|do|d{1,4}|E|wo|w{1,2}|Wo|W{1,2}|Qo|Q|YYYY|YY|HH|H|hh|h|mm|m|ss|s|SSS|SS|S|X|x|z|Z|.)"/utf8>> ) of {ok, Regex} -> Regex; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"dateformat"/utf8>>, function => <<"compile_format"/utf8>>, line => 79, value => _assert_fail, start => 4275, 'end' => 4465, pattern_start => 4286, pattern_end => 4295}) end, gleam@result:'try'( begin _pipe = gleam@regexp:scan(Regex@1, Fmt), gleam@list:try_map(_pipe, fun parse_match/1) end, fun(Fmts) -> {ok, fun(_capture) -> run_format(Fmts, _capture) end} end ). -file("src/dateformat.gleam", 68). ?DOC( " Formats the given Time using the specified format\n" " Can return error if the format doesn't parse successfully\n" ). -spec format(binary(), birl:time()) -> {ok, binary()} | {error, nil}. format(Fmt, Time) -> gleam@result:'try'( compile_format(Fmt), fun(Cmp_fmt) -> {ok, Cmp_fmt(Time)} end ).