@@ -461,25 +461,30 @@ defmodule Calendar do
461
461
it can't contain the `%X` format and defaults to `"%H:%M:%S"`
462
462
if the option is not received
463
463
464
- * `:am_pm_names` - a function that receives either `:am` or `:pm` and returns
464
+ * `:am_pm_names` - a function that receives either `:am` or `:pm`
465
+ (and also the datetime if the function is arity/2) and returns
465
466
the name of the period of the day, if the option is not received it defaults
466
467
to a function that returns `"am"` and `"pm"`, respectively
467
468
468
- * `:month_names` - a function that receives a number and returns the name of
469
+ * `:month_names` - a function that receives a number (and also the
470
+ datetime if the function is arity/2) and returns the name of
469
471
the corresponding month, if the option is not received it defaults to a
470
472
function that returns the month names in English
471
473
472
- * `:abbreviated_month_names` - a function that receives a number and returns the
474
+ * `:abbreviated_month_names` - a function that receives a number (and also
475
+ the datetime if the function is arity/2) and returns the
473
476
abbreviated name of the corresponding month, if the option is not received it
474
477
defaults to a function that returns the abbreviated month names in English
475
478
476
- * `:day_of_week_names` - a function that receives a number and returns the name of
479
+ * `:day_of_week_names` - a function that receives a number and (and also the
480
+ datetime if the function is arity/2) returns the name of
477
481
the corresponding day of week, if the option is not received it defaults to a
478
482
function that returns the day of week names in English
479
483
480
- * `:abbreviated_day_of_week_names` - a function that receives a number and returns
481
- the abbreviated name of the corresponding day of week, if the option is not received
482
- it defaults to a function that returns the abbreviated day of week names in English
484
+ * `:abbreviated_day_of_week_names` - a function that receives a number (and also
485
+ the datetime if the function is arity/2) and returns the abbreviated name of
486
+ the corresponding day of week, if the option is not received it defaults to a
487
+ function that returns the abbreviated day of week names in English
483
488
484
489
## Formatting syntax
485
490
@@ -650,12 +655,12 @@ defmodule Calendar do
650
655
format_modifiers ( rest , width , pad , datetime , format_options , acc )
651
656
end
652
657
653
- defp am_pm ( hour , format_options ) when hour > 11 do
654
- format_options . am_pm_names . ( :pm )
658
+ defp am_pm ( hour , format_options , datetime ) when hour > 11 do
659
+ apply_format ( :pm , format_options . am_pm_names , datetime )
655
660
end
656
661
657
- defp am_pm ( hour , format_options ) when hour <= 11 do
658
- format_options . am_pm_names . ( :am )
662
+ defp am_pm ( hour , format_options , datetime ) when hour <= 11 do
663
+ apply_format ( :am , format_options . am_pm_names , datetime )
659
664
end
660
665
661
666
defp default_pad ( format ) when format in ~c" aAbBpPZ" , do: ?\s
@@ -676,7 +681,7 @@ defmodule Calendar do
676
681
result =
677
682
datetime
678
683
|> Date . day_of_week ( )
679
- |> format_options . abbreviated_day_of_week_names . ( )
684
+ |> apply_format ( format_options . abbreviated_day_of_week_names , datetime )
680
685
|> pad_leading ( width , pad )
681
686
682
687
parse ( rest , datetime , format_options , [ result | acc ] )
@@ -687,7 +692,7 @@ defmodule Calendar do
687
692
result =
688
693
datetime
689
694
|> Date . day_of_week ( )
690
- |> format_options . day_of_week_names . ( )
695
+ |> apply_format ( format_options . day_of_week_names , datetime )
691
696
|> pad_leading ( width , pad )
692
697
693
698
parse ( rest , datetime , format_options , [ result | acc ] )
@@ -697,15 +702,18 @@ defmodule Calendar do
697
702
defp format_modifiers ( "b" <> rest , width , pad , datetime , format_options , acc ) do
698
703
result =
699
704
datetime . month
700
- |> format_options . abbreviated_month_names . ( )
705
+ |> apply_format ( format_options . abbreviated_month_names , datetime )
701
706
|> pad_leading ( width , pad )
702
707
703
708
parse ( rest , datetime , format_options , [ result | acc ] )
704
709
end
705
710
706
711
# Full month name
707
712
defp format_modifiers ( "B" <> rest , width , pad , datetime , format_options , acc ) do
708
- result = datetime . month |> format_options . month_names . ( ) |> pad_leading ( width , pad )
713
+ result =
714
+ datetime . month
715
+ |> apply_format ( format_options . month_names , datetime )
716
+ |> pad_leading ( width , pad )
709
717
710
718
parse ( rest , datetime , format_options , [ result | acc ] )
711
719
end
@@ -783,7 +791,11 @@ defmodule Calendar do
783
791
784
792
# "AM" or "PM" (noon is "PM", midnight as "AM")
785
793
defp format_modifiers ( "p" <> rest , width , pad , datetime , format_options , acc ) do
786
- result = datetime . hour |> am_pm ( format_options ) |> String . upcase ( ) |> pad_leading ( width , pad )
794
+ result =
795
+ datetime . hour
796
+ |> am_pm ( format_options , datetime )
797
+ |> String . upcase ( )
798
+ |> pad_leading ( width , pad )
787
799
788
800
parse ( rest , datetime , format_options , [ result | acc ] )
789
801
end
@@ -792,7 +804,7 @@ defmodule Calendar do
792
804
defp format_modifiers ( "P" <> rest , width , pad , datetime , format_options , acc ) do
793
805
result =
794
806
datetime . hour
795
- |> am_pm ( format_options )
807
+ |> am_pm ( format_options , datetime )
796
808
|> String . downcase ( )
797
809
|> pad_leading ( width , pad )
798
810
@@ -958,6 +970,18 @@ defmodule Calendar do
958
970
defp do_pad_leading ( count , padding , acc ) ,
959
971
do: do_pad_leading ( count - 1 , padding , [ padding | acc ] )
960
972
973
+ defp apply_format ( term , formatter , _datetime ) when is_function ( formatter , 1 ) do
974
+ formatter . ( term )
975
+ end
976
+
977
+ defp apply_format ( term , formatter , datetime ) when is_function ( formatter , 2 ) do
978
+ formatter . ( term , datetime )
979
+ end
980
+
981
+ defp apply_format ( _term , formatter , _datetime ) do
982
+ raise ArgumentError , "formatter functions must be of arity 1 or 2, got: #{ inspect ( formatter ) } "
983
+ end
984
+
961
985
defp options ( user_options ) do
962
986
default_options = % {
963
987
preferred_date: "%Y-%m-%d" ,
0 commit comments