diff --git a/lib/cldr/date.ex b/lib/cldr/date.ex index 62dac60..bf3f206 100644 --- a/lib/cldr/date.ex +++ b/lib/cldr/date.ex @@ -22,6 +22,8 @@ defmodule Cldr.Date do import Cldr.DateTime, only: [resolve_plural_format: 4, apply_preference: 2] + @typep options :: Keyword.t() | map() + @format_types [:short, :medium, :long, :full] @default_format_type :medium @default_prefer :unicode @@ -122,7 +124,10 @@ defmodule Cldr.Date do {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :dy"}} """ - @spec to_string(Cldr.Calendar.any_date_time(), Cldr.backend() | Keyword.t(), Keyword.t()) :: + @spec to_string(Cldr.Calendar.any_date_time(), Cldr.backend(), options()) :: + {:ok, String.t()} | {:error, {module, String.t()}} + + @spec to_string(Cldr.Calendar.any_date_time(), options(), []) :: {:ok, String.t()} | {:error, {module, String.t()}} def to_string(date, backend \\ Cldr.Date.default_backend(), options \\ []) @@ -241,8 +246,11 @@ defmodule Cldr.Date do "juin 2024" """ - @spec to_string!(Cldr.Calendar.any_date_time(), Cldr.backend() | Keyword.t(), Keyword.t()) :: - String.t() | no_return + @spec to_string!(Cldr.Calendar.any_date_time(), Cldr.backend(), options()) :: + String.t() | no_return() + + @spec to_string!(Cldr.Calendar.any_date_time(), options(), []) :: + String.t() | no_return() def to_string!(date, backend \\ Cldr.Date.default_backend(), options \\ []) @@ -267,7 +275,7 @@ defmodule Cldr.Date do %{locale: locale, number_system: number_system, format: format, prefer: prefer} end - defp normalize_options(date, backend, options) do + defp normalize_options(date, backend, options) when is_list(options) do {locale, _backend} = Cldr.locale_and_backend_from(options[:locale], backend) locale_number_system = Cldr.Number.System.number_system_from_locale(locale, backend) number_system = Keyword.get(options, :number_system, locale_number_system) @@ -276,12 +284,12 @@ defmodule Cldr.Date do format = format_from_options(date, format_option, @default_format_type, prefer) options - |> Keyword.put(:locale, locale) - |> Keyword.put(:format, format) - |> Keyword.put(:prefer, prefer) - |> Keyword.delete(:style) - |> Keyword.put_new(:number_system, number_system) |> Map.new() + |> Map.put(:locale, locale) + |> Map.put(:format, format) + |> Map.put(:prefer, prefer) + |> Map.delete(:style) + |> Map.put_new(:number_system, number_system) end # Full date, no option, use the default format diff --git a/lib/cldr/date_time.ex b/lib/cldr/date_time.ex index 5f40d89..d71840d 100644 --- a/lib/cldr/date_time.ex +++ b/lib/cldr/date_time.ex @@ -23,6 +23,8 @@ defmodule Cldr.DateTime do alias Cldr.LanguageTag alias Cldr.Locale + @typep options :: Keyword.t() | map() + @format_types [:short, :medium, :long, :full] @default_format_type :medium @default_style :default @@ -185,7 +187,10 @@ defmodule Cldr.DateTime do {:ok, "semaine 1 de 2000"} """ - @spec to_string(Cldr.Calendar.any_date_time(), Cldr.backend() | Keyword.t(), Keyword.t()) :: + @spec to_string(Cldr.Calendar.any_date_time(), Cldr.backend(), options()) :: + {:ok, String.t()} | {:error, {module, String.t()}} + + @spec to_string(Cldr.Calendar.any_date_time(), options(), []) :: {:ok, String.t()} | {:error, {module, String.t()}} def to_string(datetime, backend \\ Cldr.Date.default_backend(), options \\ []) @@ -316,8 +321,11 @@ defmodule Cldr.DateTime do "semaine 1 de 2000" """ - @spec to_string!(Cldr.Calendar.any_date_time(), Cldr.backend() | Keyword.t(), Keyword.t()) :: - String.t() | no_return + @spec to_string!(Cldr.Calendar.any_date_time(), Cldr.backend(), options()) :: + String.t() | no_return() + + @spec to_string!(Cldr.Calendar.any_date_time(), options(), []) :: + String.t() | no_return() def to_string!(datetime, backend \\ Cldr.Date.default_backend(), options \\ []) diff --git a/lib/cldr/interval/date.ex b/lib/cldr/interval/date.ex index ac30bde..ca9673a 100644 --- a/lib/cldr/interval/date.ex +++ b/lib/cldr/interval/date.ex @@ -383,15 +383,11 @@ defmodule Cldr.Date.Interval do def to_string(unquote(date()) = from, unquote(date()) = to, backend, options) do {locale, backend} = Cldr.locale_and_backend_from(options[:locale], backend) formatter = Module.concat(backend, DateTime.Formatter) - format = options[:date_format] || options[:format] || @default_format - locale_number_system = Cldr.Number.System.number_system_from_locale(locale, backend) - number_system = Keyword.get(options, :number_system, locale_number_system) - prefer = Keyword.get(options, :prefer, @default_prefer) |> List.wrap() + options = normalize_options(locale, backend, options) - options = - options - |> Keyword.put(:locale, locale) - |> Keyword.put(:number_system, number_system) + number_system = options.number_system + prefer = options.prefer + format = options.format with {:ok, _} <- from_less_than_or_equal_to(from, to), {:ok, backend} <- Cldr.validate_backend(backend), @@ -659,6 +655,26 @@ defmodule Cldr.Date.Interval do end end + defp normalize_options(_locale, _backend, %{} = options) do + options + end + + defp normalize_options(locale, backend, options) do + format = options[:date_format] || options[:format] || @default_format + locale_number_system = Cldr.Number.System.number_system_from_locale(locale, backend) + number_system = Keyword.get(options, :number_system, locale_number_system) + prefer = Keyword.get(options, :prefer, @default_prefer) |> List.wrap() + style = Keyword.get(options, :style, @default_style) + + options + |> Map.new() + |> Map.put(:format, format) + |> Map.put(:style, style) + |> Map.put(:locale, locale) + |> Map.put(:number_system, number_system) + |> Map.put(:prefer, prefer) + end + defp from_less_than_or_equal_to(from, to) do case Date.compare(from, to) do comp when comp in [:eq, :lt] -> {:ok, comp} @@ -667,13 +683,10 @@ defmodule Cldr.Date.Interval do end defp resolve_format(from, to, formats, options) do - requested_format = Keyword.get(options, :format, @default_format) - requested_style = Keyword.get(options, :style, @default_style) - - with {:ok, style} <- validate_style(requested_style), - {:ok, format} <- validate_format(formats, style, requested_format), + with {:ok, style} <- validate_style(options.style), + {:ok, format} <- validate_format(formats, style, options.format), {:ok, greatest_difference} <- greatest_difference(from, to) do - greatest_difference_format(format, requested_format, requested_style, greatest_difference) + greatest_difference_format(format, format, style, greatest_difference) end end diff --git a/lib/cldr/interval/time.ex b/lib/cldr/interval/time.ex index b21f272..43a9ad6 100644 --- a/lib/cldr/interval/time.ex +++ b/lib/cldr/interval/time.ex @@ -239,15 +239,11 @@ defmodule Cldr.Time.Interval do def to_string(unquote(time()) = from, unquote(time()) = to, backend, options) do {locale, backend} = Cldr.locale_and_backend_from(options[:locale], backend) formatter = Module.concat(backend, DateTime.Formatter) - format = options[:time_format] || options[:format] || @default_format - locale_number_system = Cldr.Number.System.number_system_from_locale(locale, backend) - number_system = Keyword.get(options, :number_system, locale_number_system) - prefer = Keyword.get(options, :prefer, @default_prefer) + options = normalize_options(locale, backend, options) - options = - options - |> Keyword.put(:locale, locale) - |> Keyword.put(:number_system, number_system) + number_system = options.number_system + prefer = options.prefer + format = options.format with {:ok, backend} <- Cldr.validate_backend(backend), {:ok, locale} <- Cldr.validate_locale(locale, backend), @@ -399,6 +395,26 @@ defmodule Cldr.Time.Interval do end end + defp normalize_options(_locale, _backend, %{} = options) do + options + end + + defp normalize_options(locale, backend, options) do + format = options[:time_format] || options[:format] || @default_format + locale_number_system = Cldr.Number.System.number_system_from_locale(locale, backend) + number_system = Keyword.get(options, :number_system, locale_number_system) + prefer = Keyword.get(options, :prefer, @default_prefer) + style = Keyword.get(options, :style, @default_style) + + options + |> Map.new() + |> Map.put(:format, format) + |> Map.put(:style, style) + |> Map.put(:locale, locale) + |> Map.put(:number_system, number_system) + |> Map.put(:prefer, prefer) + end + @doc """ Returns the format code representing the date or time unit that is the greatest difference between @@ -434,19 +450,9 @@ defmodule Cldr.Time.Interval do Cldr.Date.Interval.greatest_difference(from, to) end - # defp from_less_than_or_equal_to(from, to) do - # case Time.compare(from, to) do - # comp when comp in [:eq, :lt] -> {:ok, comp} - # _other -> {:error, Cldr.Date.Interval.datetime_order_error(from, to)} - # end - # end - defp resolve_format(from, to, formats, locale, options) do - format = Keyword.get(options, :format, @default_format) - style = Keyword.get(options, :style, @default_style) - - with {:ok, style} <- validate_style(style), - {:ok, format} <- validate_format(formats, style, locale, format), + with {:ok, style} <- validate_style(options.style), + {:ok, format} <- validate_format(formats, style, locale, options.format), {:ok, greatest_difference} <- greatest_difference(from, to) do greatest_difference_format(from, to, format, greatest_difference) end diff --git a/lib/cldr/time.ex b/lib/cldr/time.ex index 8137f62..5097e71 100644 --- a/lib/cldr/time.ex +++ b/lib/cldr/time.ex @@ -24,6 +24,8 @@ defmodule Cldr.Time do import Cldr.DateTime, only: [resolve_plural_format: 4, apply_preference: 2] + @typep options :: Keyword.t() | map() + @format_types [:short, :medium, :long, :full] @default_format_type :medium @default_prefer :unicode @@ -129,7 +131,10 @@ defmodule Cldr.Time do {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :m"}} """ - @spec to_string(map, Cldr.backend() | Keyword.t(), Keyword.t()) :: + @spec to_string(Cldr.Calendar.any_date_time(), Cldr.backend(), options()) :: + {:ok, String.t()} | {:error, {module, String.t()}} + + @spec to_string(Cldr.Calendar.any_date_time(), options(), []) :: {:ok, String.t()} | {:error, {module, String.t()}} def to_string(time, backend \\ Cldr.Date.default_backend(), options \\ []) @@ -247,7 +252,11 @@ defmodule Cldr.Time do "11:11 PM" """ - @spec to_string!(map, Cldr.backend() | Keyword.t(), Keyword.t()) :: String.t() | no_return + @spec to_string!(Cldr.Calendar.any_date_time(), Cldr.backend(), options()) :: + String.t() | no_return() + + @spec to_string!(Cldr.Calendar.any_date_time(), options(), []) :: + String.t() | no_return() def to_string!(time, backend \\ Cldr.Date.default_backend(), options \\ []) @@ -281,12 +290,12 @@ defmodule Cldr.Time do format = format_from_options(time, format_option, @default_format_type, prefer) options - |> Keyword.put(:locale, locale) - |> Keyword.put(:format, format) - |> Keyword.put(:prefer, prefer) - |> Keyword.delete(:style) - |> Keyword.put_new(:number_system, number_system) |> Map.new() + |> Map.put(:locale, locale) + |> Map.put(:format, format) + |> Map.put(:prefer, prefer) + |> Map.delete(:style) + |> Map.put_new(:number_system, number_system) end # Full date, no option, use the default format