Skip to content

Commit

Permalink
Support formatting durations as times
Browse files Browse the repository at this point in the history
  • Loading branch information
kipcole9 committed Jul 26, 2024
1 parent 0e9bc19 commit 89b05cb
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
elixir 1.16.2-otp-26
erlang 26.2.2
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

**Note that `ex_cldr_dates_times` version 2.18.0 and later are supported on Elixir 1.12 and later only.**

## Cldr_Dates_Times v2.20.1

This is the changelog for Cldr_Dates_Times v2.20.1 released on July 27th, 2024. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_cldr_dates_times/tags)

### Bug Fixes

* Supports formatting `t:Cldr.Calendar.Duration.t/0` and, on Elixir 1.17 or later, `t:Duration.t/0` structs. For these structs, and only these structs, the `:hour` can be any number. In other cases the number is required to be in the range `0..24`.

## Cldr_Dates_Times v2.20.0

This is the changelog for Cldr_Dates_Times v2.20.0 released on July 26th, 2024. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_cldr_dates_times/tags)
Expand Down
25 changes: 25 additions & 0 deletions lib/cldr/format/date_time_formatter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ defmodule Cldr.DateTime.Formatter do
alias Cldr.Calendar.Gregorian
alias Cldr.Locale

@duration_modules [Cldr.Calendar.Duration, Duration]
@default_format 1

@doc false
Expand Down Expand Up @@ -2404,6 +2405,12 @@ defmodule Cldr.DateTime.Formatter do
|> maybe_wrap(:h12, options)
end

def h12(%module{hour: hour}, n, _locale, _backend, options) when module in @duration_modules do
hour
|> pad(n)
|> maybe_wrap(:h12, options)
end

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)}"}}
Expand Down Expand Up @@ -2497,6 +2504,12 @@ defmodule Cldr.DateTime.Formatter do
|> maybe_wrap(:h11, options)
end

def h11(%module{hour: hour}, n, _locale, _backend, options) when module in @duration_modules do
hour
|> pad(n)
|> maybe_wrap(:h11, options)
end

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)}"}}
Expand Down Expand Up @@ -2581,6 +2594,12 @@ defmodule Cldr.DateTime.Formatter do
|> maybe_wrap(:h24, options)
end

def h24(%module{hour: hour}, n, _locale, _backend, options) when module in @duration_modules do
hour
|> pad(n)
|> maybe_wrap(:h24, options)
end

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)}"}}
Expand Down Expand Up @@ -2665,6 +2684,12 @@ defmodule Cldr.DateTime.Formatter do
|> maybe_wrap(:h23, options)
end

def h23(%module{hour: hour}, n, _locale, _backend, options) when module in @duration_modules do
hour
|> pad(n)
|> maybe_wrap(:h23, options)
end

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)}"}}
Expand Down
3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Cldr.DatesTimes.Mixfile do
use Mix.Project

@version "2.20.0"
@version "2.20.1"

def project do
[
Expand Down Expand Up @@ -73,6 +73,7 @@ defmodule Cldr.DatesTimes.Mixfile do
{:ex_cldr, "~> 2.40"},
{:ex_cldr_calendars, "~> 1.25"},
{:calendar_interval, "~> 0.2", optional: true},
{:ex_cldr_units, "~> 3.17", optional: true},
{:ex_doc, "~> 0.25", optional: true, only: [:dev, :release], runtime: false},
{:jason, "~> 1.0", optional: true},
{:tz, "~> 0.26", optional: true},
Expand Down
6 changes: 4 additions & 2 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
"earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"},
"erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"},
"ex_cldr": {:hex, :ex_cldr, "2.40.0", "624717778dbf0a8cd307f1576eabbd44470c16190172abf293fed24150440a5a", [:mix], [{:cldr_utils, "~> 2.28", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.19", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: true]}], "hexpm", "113394b6dd23aaf7912da583aab103d9cf082b9821bc4a6e287543a895af7cb4"},
"ex_cldr_calendars": {:hex, :ex_cldr_calendars, "1.25.2", "7c6c84503a52edb512b09d62ad1a2946996b47dbfe29211a99c3a3ffb6043991", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:ex_cldr_lists, "~> 2.10", [hex: :ex_cldr_lists, repo: "hexpm", optional: true]}, {:ex_cldr_numbers, "~> 2.31", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_cldr_units, "~> 3.16", [hex: :ex_cldr_units, repo: "hexpm", optional: true]}, {:ex_doc, "~> 0.21", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "a04b0a189bcf38bad919b03fd586938b75454f3a4d56d049b7159bb1cadd7843"},
"ex_cldr_calendars": {:hex, :ex_cldr_calendars, "1.26.0", "855721dedb3c1eddcb6ad219257b8896e8c4993ef1db65a4f281f119c7235ab1", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:ex_cldr_lists, "~> 2.10", [hex: :ex_cldr_lists, repo: "hexpm", optional: true]}, {:ex_cldr_numbers, "~> 2.31", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_cldr_units, "~> 3.16", [hex: :ex_cldr_units, repo: "hexpm", optional: true]}, {:ex_doc, "~> 0.21", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9160acc0573ae72d0af91b58b7130c5058609acd3904224425bcb94d57bf9264"},
"ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.16.1", "29317f533cb5ec046d04523256cca4090291e9157028f28731395149b06ff8b2", [:mix], [{:ex_cldr, "~> 2.38", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "095d5e973bf0ee066dd1153990d10cb6fa6d8ff0e028295bdce7a7821c70a0e4"},
"ex_cldr_lists": {:hex, :ex_cldr_lists, "2.11.0", "1d39e75f0e493ccc95adfc85c55b4ca34f0771626350ce326d9ab8813d91444e", [:mix], [{:ex_cldr_numbers, "~> 2.25", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_doc, "~> 0.18", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "8132b30a5506ae8a09e5c9a21c23fd60c8837ce6c3a1de9966d813eb78951695"},
"ex_cldr_numbers": {:hex, :ex_cldr_numbers, "2.33.1", "49dc6e77e6d9ad22660aaa2480a7408ad3aedfbe517e4e83e5fe3a7bf5345770", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:digital_token, "~> 0.3 or ~> 1.0", [hex: :digital_token, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.38", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, "~> 2.16", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "c003bfaa3fdee6bab5195f128b94038c2ce1cf4879a759eef431dd075d9a5dac"},
"ex_cldr_units": {:hex, :ex_cldr_units, "3.17.0", "f26dcde31a8fbb7808afa106ce2c7cbf38e0e0e0678ac523e795cdfdc67ab502", [:mix], [{:cldr_utils, "~> 2.25", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ex_cldr_lists, "~> 2.10", [hex: :ex_cldr_lists, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.33.0", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_doc, "~> 0.18", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "b9f09c420f5e3b86ed41f135751086bc59bf2bb8e633516e8d3e9f24d6d9e777"},
"ex_doc": {:hex, :ex_doc, "0.34.2", "13eedf3844ccdce25cfd837b99bea9ad92c4e511233199440488d217c92571e8", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "5ce5f16b41208a50106afed3de6a2ed34f4acfd65715b82a0b84b49d995f95c1"},
"exprintf": {:hex, :exprintf, "0.2.1", "b7e895dfb00520cfb7fc1671303b63b37dc3897c59be7cbf1ae62f766a8a0314", [:mix], [], "hexpm", "20a0e8c880be90e56a77fcc82533c5d60c643915c7ce0cc8aa1e06ed6001da28"},
"exprof": {:hex, :exprof, "0.2.4", "13ddc0575a6d24b52e7c6809d2a46e9ad63a4dd179628698cdbb6c1f6e497c98", [:mix], [{:exprintf, "~> 0.2", [hex: :exprintf, repo: "hexpm", optional: false]}], "hexpm", "0884bcb66afc421c75d749156acbb99034cc7db6d3b116c32e36f32551106957"},
"jason": {:hex, :jason, "1.4.3", "d3f984eeb96fe53b85d20e0b049f03e57d075b5acda3ac8d465c969a2536c17b", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "9a90e868927f7c777689baa16d86f4d0e086d968db5c05d917ccff6d443e58a3"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"},
"makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"},
Expand Down
2 changes: 1 addition & 1 deletion mix/my_app_backend.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule MyApp.Cldr do
use Cldr,
locales: ["en", "fr", "af", "ja", "de", "pl", "th", "fa", "es", "da", "en-*"],
providers: [Cldr.Number, Cldr.Calendar, Cldr.DateTime],
providers: [Cldr.Number, Cldr.Calendar, Cldr.DateTime, Cldr.Unit, Cldr.List],
precompile_number_formats: ["#,##0"],
precompile_transliterations: [{:latn, :thai}]
end
15 changes: 15 additions & 0 deletions test/duration_format_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule Cldr.DateTime.DurationFormatTest do
use ExUnit.Case, async: true

test "Formatting a Cldr.Calendar.Duration" do
duration = Cldr.Calendar.Duration.new_from_seconds 136092
assert {:ok, "37:48:12"} = Cldr.Time.to_string(duration, format: "hh:mm:ss")
end

if Code.ensure_loaded?(Duration) do
test "Formatting a Duration" do
duration = Duration.new!(hour: 28, minute: 15, second: 6)
assert {:ok, "28:15:06"} = Cldr.Time.to_string(duration, format: "hh:mm:ss")
end
end
end

0 comments on commit 89b05cb

Please sign in to comment.