Closed ribanez7 closed 1 year ago
@ribanez7, thanks for the suggestion. I'm not sure I completely understand what you're suggesting. I think what you are saying is something like:
iex> Cldr.Unit.new(:kilogram, 100..1000)
Is that the idea? I'm interested but I can see some challenges.
Cldr.Unit.to_string/2
would emit for such a range. Do you have some thoughts?Cldr.Math
ex_cldr_unit_sql
.I'm curious about the use case you have in mind. Can you share an example?
Sure. I am using a custom unit (person), to show company sizes. The japanese case gives us some juice since it also changes the way a range is formatted (using tilde instead of dash).
So given this implementation:
unit_localization(:person, "ja", :long,
nominative: %{
one: "{0} 人",
other: "{0} 人"
},
display_name: "人"
)
Let's say I want something like: 1-10 people
, or even with a current unit, hour
=> 1-2 hr
.
I would like something like:
iex> MyApp.Cldr.Unit.to_string!(MyApp.Cldr.Unit.new!(:hour, 1..2), [unit: :hour, style: :long, locale: :en])
"1-2 hours"
But that implies calling MyApp.Cldr.Number.to_range_string(1..2, locale: :en, format: :long)
and appending the Unit.to_string! result to it, calculated maybe with the last number in the range.
The japanese case I was talking about would result in:
MyApp.Cldr.Unit.to_string!(MyApp.Cldr.Unit.new!(:person 1..2), [style: :long, locale: :ja])
"1〜2人"
I can't come up with examples of it using math operations.
Thanks for the example, I understand better now. I think there is a way to do a unit version analogous to Date.Range
called Unit.Range
with the caveat that both units in the range would need to be the same unit type.
I am working on a series of updates for CLDR 43 data that will launch in about 3 weeks. Is that manageable timing for you?
I can also implement Enumerable
for a Unit.Range
too.
Yep, that will work perfectly. For the meantime I have a helper function to do it "the kind-of-hardcoded-way", by calculating both things separately (the number.to_range_string and the unit.to_string) and placing them together just with a concat. To extend the use of it in more languages I'll wait for the implementation 👍🏼 , now I'm using my function just for controlled situations.
I've closed this issue for now. Still on track for shipping in a couple of weeks. When everything across all the cldr projects is merged it'll be easier for you to test for your own use cases. For now, here's an example:
iex> {:ok, range} = Cldr.Unit.Range.new(Cldr.Unit.new!(:gram, 1), Cldr.Unit.new!(:gram, 5))
iex> Cldr.Unit.to_string(range, locale: :ja)
{:ok, "1~5 グラム"}
Many thanks @kipcole9 , that's awesome.
You're welcome. As a bonus, Cldr.Unit.Range.t
implements the Enumeration
protocol:
iex> range = Cldr.Unit.Range.new!(Cldr.Unit.new!(:gram, 1), Cldr.Unit.new!(:gram, 5))
iex> Enum.to_list(range)
[Cldr.Unit.new!(:gram, 1), Cldr.Unit.new!(:gram, 2), Cldr.Unit.new!(:gram, 3),
Cldr.Unit.new!(:gram, 4), Cldr.Unit.new!(:gram, 5)]
Yess, I've seen that going through the code, brilliant 👍🏼
Currently it is possible to pass float, integer, Decimal or Ratio, but would it be a possibility to pass a range? Or maybe this should be responsibility of
Cldr.Number.to_range_string
?If we include it in
Cldr.Number.to_range_string
, maybe it can be passed as an option, like the currency one. Why not allow an option for unit, if there is an option for currency?And in case that should be responsibility of Cldr.Unit, I could try to do a POC.