Closed DaTrader closed 2 years ago
ex_cldr_units is (mostly) your friend here. These are considered as time units
with the emphasis on unit
which is why they occur in that particular library. Some examples:
iex> MyApp.Cldr.Unit.to_string Cldr.Unit.new!(2, :week)
{:ok, "2 weeks"}
iex> MyApp.Cldr.Unit.to_string Cldr.Unit.new!(2, :week), locale: "fr"
{:ok, "2 semaines"}
At present, CLDR knows about the following time units:
iex> Cldr.Unit.known_units_by_category |> Map.get(:duration)
[:century, :day, :decade, :hour, :microsecond, :millisecond, :minute, :month,
:nanosecond, :second, :week, :year]
Which means that :quarter
isn't a known unit unfortunately. I will submit a ticket to CLDR but I wouldn't expect a quick outcome.
As an aside, in ex_cldr_calendars there is a module Cldr.Calendar.Duration that will calculate the difference between two dates/date_times and it will also use Cldr.Unit.to_string/1
for formatting if ex_cldr_units
is configured. For example:
iex> {:ok, duration} = Cldr.Calendar.Duration.new(~D[2020-10-19], ~D[2021-12-01])
{:ok,
%Cldr.Calendar.Duration{
day: 13,
hour: 0,
microsecond: 0,
minute: 0,
month: 1,
second: 0,
year: 1
}}
iex> Cldr.Calendar.Duration.to_string(duration)
{:ok, "1 year, 1 month, and 13 days"}
Thanks, Kip!
Just so you know that little by little your libraries are becoming invaluable to my app.
Thanks for the encouragement, definitely helps with motivation to know the work is useful!
Kip, just to let you known I'm getting the following warning when compiling the deps (I'm still on Elixir 1.10.3).
warning: Date.to_gregorian_days/1 is undefined or private
lib/cldr/calendar/behaviour.ex:6: Cldr.Calendar.Behaviour.__using__/1
And Merry Christmas.
There is a a solution for days and weeks, but not quarters. It requires using the ex_cldr_units library.
iex> days = Cldr.Unit.new!(:day, 2)
#Cldr.Unit<:day, 2>
iex> MyApp.Cldr.Unit.to_string days
{:ok, "2 days"}
iex> weeks = Cldr.Unit.new!(:week, 2)
#Cldr.Unit<:week, 2>
iex> MyApp.Cldr.Unit.to_string weeks
{:ok, "2 weeks"}
iex> MyApp.Cldr.Unit.to_string weeks, locale: "fr"
{:ok, "2 semaines"}
iex> MyApp.Cldr.Unit.to_string weeks, locale: "de"
{:ok, "2 Wochen"}
iex> MyApp.Cldr.Unit.to_string weeks, locale: "he"
{:ok, "שבועיים"}
I have opened this issue to add a quarter
unit type on CLDR but that's not likely to happen quickly.
There may be a way to format quarters using ex_cldr_messages or perhaps gettext. I'll have to think on that a bit.
Hey Kip,
looking at the API over and over again, I can't seem to find a way to format a duration (a time period) regardless of when it starts or ends e.g.:
2 days 3 weeks 2 quarters
Can you help with this one?
Thanks,
Damir