diff --git a/lib/cldr/backend/date_time.ex b/lib/cldr/backend/date_time.ex index d7f913e..8ebc298 100644 --- a/lib/cldr/backend/date_time.ex +++ b/lib/cldr/backend/date_time.ex @@ -247,7 +247,7 @@ defmodule Cldr.DateAndTime.Backend do # CLDR defined format. iex> #{inspect(__MODULE__)}.to_string(%{year: 2024, day: 3}, locale: "fr") {:error, - {Cldr.DateTime.UnresolvedFormat, "No available format resolved for \\"dy\\""}} + {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :dy"}} """ @spec to_string(Cldr.Calendar.any_date_time(), Keyword.t()) :: @@ -408,7 +408,7 @@ defmodule Cldr.DateAndTime.Backend do # CLDR defined format. iex> #{inspect(__MODULE__)}.to_string(%{minute: 11}) {:error, - {Cldr.DateTime.UnresolvedFormat, "No available format resolved for \\"m\\""}} + {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :m"}} """ @spec to_string(Cldr.Calendar.any_date_time(), Keyword.t()) :: diff --git a/lib/cldr/date.ex b/lib/cldr/date.ex index f8f0224..a0fa42d 100644 --- a/lib/cldr/date.ex +++ b/lib/cldr/date.ex @@ -118,7 +118,7 @@ defmodule Cldr.Date do # CLDR-defined format. iex> Cldr.Date.to_string(%{year: 2024, day: 3}, MyApp.Cldr, locale: "fr") {:error, - {Cldr.DateTime.UnresolvedFormat, "No available format resolved for \\"dy\\""}} + {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :dy"}} """ @spec to_string(Cldr.Calendar.any_date_time(), Cldr.backend() | Keyword.t(), Keyword.t()) :: @@ -464,9 +464,7 @@ defmodule Cldr.Date do if Map.has_key?(available_formats, format) do Map.fetch(available_formats, format) else - with {:ok, match} <- Cldr.DateTime.Format.best_match(format, locale, calendar, backend) do - {:ok, Map.fetch!(available_formats, match)} - end + resolve_format(format, available_formats, locale, calendar, backend) end end @@ -478,6 +476,20 @@ defmodule Cldr.Date do {:ok, format_string} end + @doc false + def resolve_format(format, available_formats, locale, calendar, backend) do + with {:ok, match} <- Cldr.DateTime.Format.best_match(format, locale, calendar, backend), + {:ok, format} <- Map.fetch(available_formats, match) do + {:ok, format} + else + :error -> + {:error, Cldr.DateTime.Format.no_format_resolved_error(format)} + + other -> + other + end + end + defp error_return(map, requirements) do requirements = requirements diff --git a/lib/cldr/format/date_time_format.ex b/lib/cldr/format/date_time_format.ex index 76b8ab5..f35f3d6 100644 --- a/lib/cldr/format/date_time_format.ex +++ b/lib/cldr/format/date_time_format.ex @@ -632,13 +632,13 @@ defmodule Cldr.DateTime.Format do ) :: {:ok, format_id()} | {:error, {module(), String.t()}} def best_match( - skeleton, + original_skeleton, locale \\ Cldr.get_locale(), calendar \\ Cldr.Calendar.default_cldr_calendar(), backend \\ Cldr.Date.default_backend() ) do with {:ok, locale} <- Cldr.validate_locale(locale, backend), - skeleton = to_string(skeleton), + skeleton = to_string(original_skeleton), {:ok, skeleton} <- put_preferred_time_symbols(skeleton, locale), {:ok, skeleton_tokens} <- Compiler.tokenize_skeleton(skeleton) do # match_with_day_periods? = @@ -663,11 +663,7 @@ defmodule Cldr.DateTime.Format do case candidates do [] -> - {:error, - { - Cldr.DateTime.UnresolvedFormat, - "No available format resolved for #{inspect(skeleton)}" - }} + {:error, no_format_resolved_error(original_skeleton)} [{format_id, _} | _rest] -> {:ok, format_id} @@ -675,6 +671,14 @@ defmodule Cldr.DateTime.Format do end end + @doc false + def no_format_resolved_error(skeleton) do + { + Cldr.DateTime.UnresolvedFormat, + "No available format resolved for #{inspect(skeleton)}" + } + end + # https://www.unicode.org/reports/tr35/tr35-dates.html#Matching_Skeletons # For skeleton and id fields with symbols representing the same type (year, month, day, etc): # Most symbols have a small distance from each other. @@ -785,6 +789,9 @@ defmodule Cldr.DateTime.Format do when different_but_compatible({symbol_a, count_a}, {symbol_b, count_b}) and different_types({symbol_a, count_a}, {symbol_b, count_b}) -> acc + abs(count_a - count_b) + 10 + + _other_a, _other_b, acc -> + acc + 10 end) {token_id, distance} diff --git a/lib/cldr/time.ex b/lib/cldr/time.ex index 19ea559..cd95a99 100644 --- a/lib/cldr/time.ex +++ b/lib/cldr/time.ex @@ -125,7 +125,7 @@ defmodule Cldr.Time do # CLDR-defined format. iex> Cldr.Time.to_string(%{minute: 11}) {:error, - {Cldr.DateTime.UnresolvedFormat, "No available format resolved for \\"m\\""}} + {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :m"}} """ @spec to_string(map, Cldr.backend() | Keyword.t(), Keyword.t()) :: @@ -347,9 +347,7 @@ defmodule Cldr.Time do if Map.has_key?(available_formats, format) do Map.fetch(available_formats, format) else - with {:ok, match} <- Cldr.DateTime.Format.best_match(format, locale, calendar, backend) do - {:ok, Map.fetch!(available_formats, match)} - end + resolve_format(format, available_formats, locale, calendar, backend) end end @@ -361,6 +359,9 @@ defmodule Cldr.Time do {:ok, format_string} end + @doc false + defdelegate resolve_format(format, available_formats, locale, calendar, backend), to: Cldr.Date + @doc """ Returns a map of the standard time formats for a given locale and calendar. diff --git a/test/partial_date_times_test.exs b/test/partial_date_times_test.exs index 6ed7d9e..cfbdf6f 100644 --- a/test/partial_date_times_test.exs +++ b/test/partial_date_times_test.exs @@ -15,7 +15,7 @@ defmodule Cldr.DateTime.PartialTest do assert Cldr.Date.to_string(%{year: 3, day: 5}) == {:error, - {Cldr.DateTime.UnresolvedFormat, "No available format resolved for \"dy\""}} + {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :dy"}} end test "Partial Times" do @@ -43,7 +43,7 @@ defmodule Cldr.DateTime.PartialTest do assert Cldr.Time.to_string(%{hour: 23, second: 45}) == {:error, - {Cldr.DateTime.UnresolvedFormat, "No available format resolved for \"sh\""}} + {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :sh"}} assert Cldr.Time.to_string(%{hour: 23, second: 45}, format: "h:m:s") == {:error, @@ -58,7 +58,7 @@ defmodule Cldr.DateTime.PartialTest do assert Cldr.DateTime.to_string(%{year: 2024, minute: 10}) == {:error, - {Cldr.DateTime.UnresolvedFormat, "No available format resolved for \"m\""}} + {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :m"}} end