Skip to content

Commit

Permalink
Mix format
Browse files Browse the repository at this point in the history
  • Loading branch information
kipcole9 committed Jul 7, 2024
1 parent 7c28315 commit 594dc76
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 73 deletions.
4 changes: 2 additions & 2 deletions lib/cldr/backend/date_time.ex
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ defmodule Cldr.DateAndTime.Backend do
"""
@spec to_string!(Cldr.Calendar.any_date_time(), Keyword.t()) ::
String.t() | no_return
String.t() | no_return

def to_string!(date, options \\ []) do
Cldr.Date.to_string!(date, unquote(backend), options)
Expand Down Expand Up @@ -489,7 +489,7 @@ defmodule Cldr.DateAndTime.Backend do
"""
@spec to_string!(Cldr.Calendar.any_date_time(), Keyword.t()) ::
String.t() | no_return
String.t() | no_return

def to_string!(time, options \\ []) do
Cldr.Time.to_string!(time, unquote(backend), options)
Expand Down
8 changes: 4 additions & 4 deletions lib/cldr/date.ex
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ defmodule Cldr.Date do
"""
@spec to_string!(Cldr.Calendar.any_date_time(), Cldr.backend() | Keyword.t(), Keyword.t()) ::
String.t() | no_return
String.t() | no_return

def to_string!(date, backend \\ Cldr.Date.default_backend(), options \\ [])

Expand Down Expand Up @@ -428,7 +428,7 @@ defmodule Cldr.Date do
# applied.
@doc false
def find_format(date, format, locale, calendar, backend)
when format in @format_types and is_full_date(date) do
when format in @format_types and is_full_date(date) do
%LanguageTag{cldr_locale_name: locale_name} = locale

with {:ok, date_formats} <- formats(locale_name, calendar, backend) do
Expand All @@ -439,7 +439,7 @@ defmodule Cldr.Date do
# If its a partial date and a standard format is requested, its an error

def find_format(date, format, _locale, _calendar, _backend)
when format in @format_types and not is_full_date(date) do
when format in @format_types and not is_full_date(date) do
{:error,
{
Cldr.DateTime.UnresolvedFormat,
Expand Down Expand Up @@ -472,7 +472,7 @@ defmodule Cldr.Date do
# it directly.

def find_format(_date, format_string, _locale, _calendar, _backend)
when is_binary(format_string) do
when is_binary(format_string) do
{:ok, format_string}
end

Expand Down
29 changes: 17 additions & 12 deletions lib/cldr/date_time.ex
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,23 @@ defmodule Cldr.DateTime do
a date.
"""
defguard has_date(datetime)
when is_map_key(datetime, :year) or is_map_key(datetime, :month) or is_map_key(datetime, :day)
when is_map_key(datetime, :year) or is_map_key(datetime, :month) or
is_map_key(datetime, :day)

@doc """
Guards whether the given datetime has components of
a time.
"""
defguard has_time(datetime)
when is_map_key(datetime, :hour) or is_map_key(datetime, :minute) or is_map_key(datetime, :second)
when is_map_key(datetime, :hour) or is_map_key(datetime, :minute) or
is_map_key(datetime, :second)

@doc """
Guard whether the given datetime has components of
both a date and a time.
"""
defguard has_date_and_time(datetime)
when has_date(datetime) and has_time(datetime)
when has_date(datetime) and has_time(datetime)

defmodule Formats do
@moduledoc false
Expand Down Expand Up @@ -306,7 +308,7 @@ defmodule Cldr.DateTime do
"""
@spec to_string!(Cldr.Calendar.any_date_time(), Cldr.backend() | Keyword.t(), Keyword.t()) ::
String.t() | no_return
String.t() | no_return

def to_string!(datetime, backend \\ Cldr.Date.default_backend(), options \\ [])

Expand Down Expand Up @@ -377,27 +379,28 @@ defmodule Cldr.DateTime do
end

defp validate_formats_consistent(format, nil = _date_format, nil = _time_format)
when is_atom(format) or is_binary(format) do
when is_atom(format) or is_binary(format) do
:ok
end

defp validate_formats_consistent(nil, date_format, time_format)
when not is_nil(date_format) and not is_nil(time_format) do
when not is_nil(date_format) and not is_nil(time_format) do
:ok
end

defp validate_formats_consistent(format, date_format, time_format)
when format in @format_types and date_format in @format_types and time_format in @format_types do
when format in @format_types and date_format in @format_types and
time_format in @format_types do
:ok
end

defp validate_formats_consistent(format, date_format, time_format)
when is_atom(format) or is_binary(format) do
{:error, {Cldr.DateTime.InvalidFormat,
when is_atom(format) or is_binary(format) do
{:error,
{Cldr.DateTime.InvalidFormat,
":date_format and :time_format cannot be specified if :format is also specified as " <>
"a format id or a format string. Found [time_format: #{inspect time_format}, " <>
"date_format: #{inspect date_format}]"
}}
"a format id or a format string. Found [time_format: #{inspect(time_format)}, " <>
"date_format: #{inspect(date_format)}]"}}
end

# Returns the CLDR calendar type for a calendar
Expand Down Expand Up @@ -524,8 +527,10 @@ defmodule Cldr.DateTime do
# Format with a number system
defp find_format(datetime, %{} = format, locale, calendar, backend, options) do
%{number_system: number_system, format: format} = format

{:ok, format_string, options} =
find_format(datetime, format, locale, calendar, backend, options)

{:ok, %{number_system: number_system, format: format_string}, options}
end

Expand Down
8 changes: 4 additions & 4 deletions lib/cldr/format/date_time_formatter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2406,7 +2406,7 @@ defmodule Cldr.DateTime.Formatter do

def h12(%{hour: hour}, _n, _locale, _backend, _options) when is_integer(hour) do
{:error,
{Cldr.DateTime.FormatError, "Hour must be in the range of 0..24. Found #{inspect hour}"}}
{Cldr.DateTime.FormatError, "Hour must be in the range of 0..24. Found #{inspect(hour)}"}}
end

def h12(time, _n, _locale, _backend, _options) do
Expand Down Expand Up @@ -2499,7 +2499,7 @@ defmodule Cldr.DateTime.Formatter do

def h11(%{hour: hour}, _n, _locale, _backend, _options) when is_integer(hour) do
{:error,
{Cldr.DateTime.FormatError, "Hour must be in the range of 0..24. Found #{inspect hour}"}}
{Cldr.DateTime.FormatError, "Hour must be in the range of 0..24. Found #{inspect(hour)}"}}
end

def h11(time, _n, _locale, _backend, _options) do
Expand Down Expand Up @@ -2583,7 +2583,7 @@ defmodule Cldr.DateTime.Formatter do

def h24(%{hour: hour}, _n, _locale, _backend, _options) when is_integer(hour) do
{:error,
{Cldr.DateTime.FormatError, "Hour must be in the range of 0..24. Found #{inspect hour}"}}
{Cldr.DateTime.FormatError, "Hour must be in the range of 0..24. Found #{inspect(hour)}"}}
end

def h24(time, _n, _locale, _backend, _options) do
Expand Down Expand Up @@ -2667,7 +2667,7 @@ defmodule Cldr.DateTime.Formatter do

def h23(%{hour: hour}, _n, _locale, _backend, _options) when is_integer(hour) do
{:error,
{Cldr.DateTime.FormatError, "Hour must be in the range of 0..24. Found #{inspect hour}"}}
{Cldr.DateTime.FormatError, "Hour must be in the range of 0..24. Found #{inspect(hour)}"}}
end

def h23(time, _n, _locale, _backend, _options) do
Expand Down
6 changes: 3 additions & 3 deletions lib/cldr/time.ex
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ defmodule Cldr.Time do
# applied.
@doc false
def find_format(time, format, locale, calendar, backend)
when format in @format_types and is_full_time(time) do
when format in @format_types and is_full_time(time) do
%LanguageTag{cldr_locale_name: locale_name} = locale

with {:ok, time_formats} <- formats(locale_name, calendar, backend) do
Expand All @@ -322,7 +322,7 @@ defmodule Cldr.Time do
# If its a partial date and a standard format is requested, its an error

def find_format(time, format, _locale, _calendar, _backend)
when format in @format_types and not is_full_time(time) do
when format in @format_types and not is_full_time(time) do
{:error,
{
Cldr.DateTime.UnresolvedFormat,
Expand Down Expand Up @@ -355,7 +355,7 @@ defmodule Cldr.Time do
# it directly.

def find_format(_time, format_string, _locale, _calendar, _backend)
when is_binary(format_string) do
when is_binary(format_string) do
{:ok, format_string}
end

Expand Down
52 changes: 32 additions & 20 deletions test/cldr_dates_times_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ defmodule Cldr.DatesTimes.Test do
end

test "Era variants" do
assert {:ok, "2024/7/6 CE"} = Cldr.Date.to_string(~D[2024-07-06], era: :variant, format: "y/M/d G")
assert {:ok, "2024/7/6 CE"} =
Cldr.Date.to_string(~D[2024-07-06], era: :variant, format: "y/M/d G")

assert {:ok, "2024/7/6 AD"} = Cldr.Date.to_string(~D[2024-07-06], format: "y/M/d G")
end

Expand All @@ -86,40 +88,50 @@ defmodule Cldr.DatesTimes.Test do
assert {:ok, "10:48 AM"} = Cldr.Time.to_string(~T[10:48:00], format: :hmJ)

assert Cldr.Date.to_string(~T[10:48:00], format: :hmc) ==
{:error,
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for :hmc"}}
{:error, {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :hmc"}}

assert Cldr.Time.to_string(~T[10:48:00], format: :hme) ==
{:error,
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for :hme"}}
{:error, {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :hme"}}
end

test "Datetime formatting with standard formats" do
datetime = ~U[2024-07-07 21:36:00.440105Z]

assert {:ok, "Jul 7, 2024, 9:36:00 PM"} =
Cldr.DateTime.to_string(datetime)
Cldr.DateTime.to_string(datetime)

assert {:ok, "7/7/24, 9:36:00 PM GMT"} =
Cldr.DateTime.to_string(datetime, date_format: :short, time_format: :full)
Cldr.DateTime.to_string(datetime, date_format: :short, time_format: :full)

assert {:ok, "7/7/24, 9:36:00 PM GMT"} =
Cldr.DateTime.to_string(datetime, format: :medium, date_format: :short, time_format: :full)
Cldr.DateTime.to_string(datetime,
format: :medium,
date_format: :short,
time_format: :full
)
end

test "Datetime format option consistency" do
datetime = ~U[2024-07-07 21:36:00.440105Z]

assert Cldr.DateTime.to_string(datetime, format: "yyy", date_format: :short, time_format: :medium)
{:error,
{Cldr.DateTime.InvalidFormat,
":date_format and :time_format cannot be specified if :format is also specified as a " <>
"format id or a format string. Found [time_format: :medium, date_format: :short]"}}

assert Cldr.DateTime.to_string(datetime, format: :yMd, date_format: :short, time_format: :medium)
{:error,
{Cldr.DateTime.InvalidFormat,
":date_format and :time_format cannot be specified if :format is also specified as a " <>
"format id or a format string. Found [time_format: :medium, date_format: :short]"}}
end
assert Cldr.DateTime.to_string(datetime,
format: "yyy",
date_format: :short,
time_format: :medium
) ==
{:error,
{Cldr.DateTime.InvalidFormat,
":date_format and :time_format cannot be specified if :format is also specified as a " <>
"format id or a format string. Found [time_format: :medium, date_format: :short]"}}

assert Cldr.DateTime.to_string(datetime,
format: :yMd,
date_format: :short,
time_format: :medium
) ==
{:error,
{Cldr.DateTime.InvalidFormat,
":date_format and :time_format cannot be specified if :format is also specified as a " <>
"format id or a format string. Found [time_format: :medium, date_format: :short]"}}
end
end
56 changes: 28 additions & 28 deletions test/partial_date_times_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,66 +8,66 @@ defmodule Cldr.DateTime.PartialTest do
assert {:ok, "5-3"} = Cldr.Date.to_string(%{month: 3, day: 5}, format: "d-M")

assert Cldr.Date.to_string(%{year: 3, day: 5}, format: "d-M") ==
{:error,
{Cldr.DateTime.FormatError,
"The format symbol 'M' requires at map with at least :month. " <>
"Found: %{calendar: Cldr.Calendar.Gregorian, day: 5, year: 3}"}}
{:error,
{Cldr.DateTime.FormatError,
"The format symbol 'M' requires at map with at least :month. " <>
"Found: %{calendar: Cldr.Calendar.Gregorian, day: 5, year: 3}"}}

assert Cldr.Date.to_string(%{year: 3, day: 5}) ==
{:error,
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for :dy"}}
{:error, {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :dy"}}
end

test "Partial Times" do
assert {:ok, "11 PM"} = Cldr.Time.to_string(%{hour: 23})
assert {:ok, "11:15 PM"} = Cldr.Time.to_string(%{hour: 23, minute: 15})
assert {:ok, "11:15:45 PM"} = Cldr.Time.to_string(%{hour: 23, minute: 15, second: 45})
assert {:ok, "23:45"} = Cldr.Time.to_string(%{minute: 23, second: 45})

assert {:ok, "5:23 AM Australia/Sydney"} =
Cldr.Time.to_string(%{hour: 5, minute: 23, time_zone: "Australia/Sydney"})
Cldr.Time.to_string(%{hour: 5, minute: 23, time_zone: "Australia/Sydney"})

assert {:ok, "5:23 unk"} =
Cldr.Time.to_string(%{hour: 5, minute: 23, zone_abbr: "AEST"}, format: "h:m V")
Cldr.Time.to_string(%{hour: 5, minute: 23, zone_abbr: "AEST"}, format: "h:m V")

assert {:ok, "5:23 AEST"} =
Cldr.Time.to_string(%{hour: 5, minute: 23, zone_abbr: "AEST"}, format: "h:m VV")
Cldr.Time.to_string(%{hour: 5, minute: 23, zone_abbr: "AEST"}, format: "h:m VV")

assert {:ok, "5:23 GMT"} =
Cldr.Time.to_string(%{hour: 5, minute: 23, zone_abbr: "AEST", utc_offset: 0, std_offset: 0}, format: "h:m VVVV")
Cldr.Time.to_string(
%{hour: 5, minute: 23, zone_abbr: "AEST", utc_offset: 0, std_offset: 0},
format: "h:m VVVV"
)

assert Cldr.Time.to_string(%{hour: 5, minute: 23, zone_abbr: "AEST"}, format: "h:m VVVV")
{:error,
{Cldr.DateTime.FormatError,
"The format symbol 'x' requires at map with at least :utc_offset. " <>
"Found: %{calendar: Cldr.Calendar.Gregorian, minute: 23, hour: 5, zone_abbr: \"AEST\"}"}}

{:error,
{Cldr.DateTime.FormatError,
"The format symbol 'x' requires at map with at least :utc_offset. " <>
"Found: %{calendar: Cldr.Calendar.Gregorian, minute: 23, hour: 5, zone_abbr: \"AEST\"}"}}

assert Cldr.Time.to_string(%{hour: 23, second: 45}) ==
{:error,
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for :sh"}}
{:error, {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :sh"}}

assert Cldr.Time.to_string(%{hour: 23, second: 45}, format: "h:m:s") ==
{:error,
{Cldr.DateTime.FormatError,
"The format symbol 'm' requires at map with at least :minute. " <>
"Found: %{second: 45, calendar: Cldr.Calendar.Gregorian, hour: 23}"}}
{:error,
{Cldr.DateTime.FormatError,
"The format symbol 'm' requires at map with at least :minute. " <>
"Found: %{second: 45, calendar: Cldr.Calendar.Gregorian, hour: 23}"}}
end

test "Partial date times" do
assert {:ok, "11/2024, 10 AM"} = Cldr.DateTime.to_string(%{year: 2024, month: 11, hour: 10})
assert {:ok, "2024, 10 AM"} = Cldr.DateTime.to_string(%{year: 2024, hour: 10})

assert Cldr.DateTime.to_string(%{year: 2024, minute: 10}) ==
{:error,
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for :m"}}

{:error, {Cldr.DateTime.UnresolvedFormat, "No available format resolved for :m"}}
end

test "Additional error returns" do
assert Cldr.DateTime.to_string(%{hour: 2024}) ==
{:error,
{Cldr.DateTime.FormatError, "Hour must be in the range of 0..24. Found 2024"}}
{:error, {Cldr.DateTime.FormatError, "Hour must be in the range of 0..24. Found 2024"}}

assert Cldr.Time.to_string(%{hour: 2024}) ==
{:error,
{Cldr.DateTime.FormatError, "Hour must be in the range of 0..24. Found 2024"}}
{:error, {Cldr.DateTime.FormatError, "Hour must be in the range of 0..24. Found 2024"}}
end
end
end

0 comments on commit 594dc76

Please sign in to comment.