-module(dateformat). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([compile_format/1, format/2, main/0]). -spec run_format(list(fun((birl:time()) -> binary())), birl:time()) -> binary(). run_format(Fmts, Time) -> _pipe = gleam@list:fold( Fmts, gleam@string_builder:new(), fun(Acc, Fmt) -> gleam@string_builder:append(Acc, Fmt(Time)) end ), gleam@string_builder:to_string(_pipe). -spec date(birl:time()) -> integer(). date(Time) -> Day = begin _pipe = Time, birl:get_day(_pipe) end, erlang:element(4, Day). -spec parse_match(gleam@regex: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), gleam@int:to_string(_pipe@4) end}; <<"x"/utf8>> -> {ok, fun(T@3) -> _pipe@5 = T@3, _pipe@6 = birl:to_unix_milli(_pipe@5), gleam@int:to_string(_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), gleam@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 = gleam@int:to_string(_pipe@9), gleam@string:pad_left(_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), gleam@int:to_string(_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 = gleam@int:to_string(_pipe@14), gleam@string:pad_left(_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 ), gleam@int:to_string(_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 = gleam@int:to_string(_pipe@19), gleam@string:pad_left(_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 ), gleam@int:to_string(_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 = gleam@int:to_string(_pipe@24), gleam@string:pad_left(_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 ), gleam@int:to_string(_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 = gleam@int:to_string(_pipe@29), gleam@string:pad_left(_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 = gleam@int:to_string(_pipe@32), gleam@string:pad_left(_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, gleam@int:to_string(_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 ), gleam@int:to_string(_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, gleam@int:to_string(_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, gleam@int:to_string(_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 ), gleam@int:to_string(_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 = gleam@int:to_string(_pipe@49), gleam@string:pad_left(_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 ), gleam@int:to_string(_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 ), gleam@int:to_string(_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), gleam@int:to_string(_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 = gleam@int:to_string(_pipe@67), gleam@string:pad_left(_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), gleam@int:to_string(_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 = gleam@int:to_string(_pipe@74), gleam@string:pad_left(_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), gleam@int:to_string(_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 = gleam@int:to_string(_pipe@81), gleam@string:pad_left(_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. -spec compile_format(binary()) -> {ok, fun((birl:time()) -> binary())} | {error, nil}. compile_format(Fmt) -> _assert_subject = gleam@regex: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>> ), {ok, Regex} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"dateformat"/utf8>>, function => <<"compile_format"/utf8>>, line => 117}) end, gleam@result:'try'( begin _pipe = gleam@regex:scan(Regex, Fmt), gleam@list:try_map(_pipe, fun parse_match/1) end, fun(Fmts) -> {ok, fun(_capture) -> run_format(Fmts, _capture) end} end ). -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 ). -spec main() -> {ok, binary()} | {error, nil}. main() -> gleam@io:println(<<"Hello from dateformat!"/utf8>>), _pipe = gleam@list:range(-12, 12), gleam@list:each( _pipe, fun(I) -> Dt = birl:add(birl:now(), birl@duration:hours(I)), gleam@io:debug( <<<<(birl:to_iso8601(Dt))/binary, " "/utf8>>/binary, (begin _pipe@1 = format( <<"A a H HH h hh k kk m mm s ss S SS SSS Z ZZ zz X x"/utf8>>, Dt ), gleam@result:unwrap(_pipe@1, <<""/utf8>>) end)/binary>> ) end ), _pipe@2 = birl:parse(<<"20120214T15:30:17.123+00:00"/utf8>>), _pipe@3 = gleam@result:unwrap(_pipe@2, birl:now()), _pipe@4 = birl:get_offset(_pipe@3), gleam@io:debug(_pipe@4), _pipe@5 = birl:from_unix_milli(1234567890123), _pipe@6 = birl:to_iso8601(_pipe@5), gleam@io:debug(_pipe@6), T = birl:from_unix_milli(1234567890123), _pipe@7 = format(<<"DD-MMM-YYYY HH:mm"/utf8>>, T), gleam@io:debug(_pipe@7).