You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# to help a user make sense of large numbers, they should include delimetersCldr.Number.to_string!(1_234_567_890)
"1,234,567,890"
# you may be used to showing one delimeter every three chartacters, but some# locales have different conventions, e.g. in India:Cldr.Number.to_string!(1_234_567_890,locale: "hi-IN")
"1,23,45,67,890"
sample_number=1_234_567.89# sample_number = 10000000# the characters used for delimeters and decimals often differ by locale, e.g:Cldr.Number.to_string!(sample_number,locale: "en-US")|>IO.inspect(label: "English ")Cldr.Number.to_string!(sample_number,locale: "pt-BR")|>IO.inspect(label: "Portuguese ")Cldr.Number.to_string!(sample_number,locale: "fr-FR")|>IO.inspect(label: "French ")# but notice how the delimeters can also be expected at different places:Cldr.Number.to_string!(sample_number,locale: "hi-IN")|>IO.inspect(label: "Hindi (India) ")# and the script or numbering system itself might also differ:Cldr.Number.to_string!(sample_number,locale: "ar-EG")|>IO.inspect(label: "Arabic (Egypt)"):ok
English : "1,234,567.89"
Portuguese : "1.234.567,89"
French : "1 234 567,89"
Hindi (India) : "12,34,567.89"
Arabic (Egypt): "١٬٢٣٤٬٥٦٧٫٨٩"
:ok
# we can display numbers in a few predefined formatsCldr.Number.to_string!(0.12345,format: :standard)|>IO.puts()Cldr.Number.to_string!(0.12345,format: :scientific)|>IO.puts()Cldr.Number.to_string!(0.12345,format: :percent)|>IO.puts()
0.123
1.2345E-1
12%
:ok
# you can list the available formatsCldr.Number.Format.format_styles_for("en",:latn,DemoApp.Backend)
# but there are a few number systems (e.g. Roman, Greek, Japanese, Chinese & Korean) # where these format rules wouldn't make senseCldr.Number.Format.format_styles_for("ja",:jpan,DemoApp.Backend)
{:ok, []}
# a special format template string can be prescribed# the characters are interpreted as:# . - decimal point# , - delimeter# 0 - zero-padded number# # - number without paddingCldr.Number.to_string!(1234.56789,format: "#,#,#,0.###")|>IO.puts()
09:32:23.415 [warning] ex_cldr_numbers: number format "#,#,#,0.###" is being compiled. For performance reasons please consider adding this format to the `precompile_number_formats` list in the backend configuration.
1,2,3,4.568
# depending on the locale, a 'native' number system may be used# e.g. for some of the most popular languages in India:[{"hi","hindi"},{"bn","bengali"},{"mr","marathi"},{"te","telugu"},{"ta","tamil"},{"gu","gujarati"}]|>Enum.each(fn{locale,language}->IO.puts(language)Cldr.Number.System.number_systems_for!(locale,DemoApp.Backend)|>Enum.each(fn{type,name}->IO.puts("#{type} (#{name})")IO.puts("\t#{type} (#{name}): "<>Cldr.Number.to_string!(12345,locale: locale,number_system: type))end)# IO.puts("\tdefault: " <> Cldr.Number.to_string!(12345, locale: locale))# IO.puts("\tnative: " <> Cldr.Number.to_string!(12345, locale: locale, number_system: :native))IO.puts("")end)
# the currency format is very usefulCldr.Number.to_string!(1345.32,currency: "USD")
"$1,345.32"
# the same currency and value might be diplayed differently, depending on the locale# e.g in Brazil:Cldr.Number.to_string!(1345.32,locale: "pt-BR",currency: "USD")
"US$ 1.345,32"
Cldr.Number.to_string!(10.0,currency: "USD")
"$10.00"
# using ex_money, we can decide to display the fractional digits only if they are relevant3|>Money.to_string!(no_fraction_if_integer: true)|>IO.puts()Money.from_float!(:USD,10.0)|>Money.to_string!(no_fraction_if_integer: true)|>IO.puts():ok
$9.99
$10
:ok
# the 'accounting' format can be used to display negative values in brackets[1345.32,-10.00,99.95]|>Enum.map(fnnumber->Cldr.Number.to_string!(number,currency: "BRL",format: :accounting)end)|>Enum.each(&IO.puts/1)
R$1,345.32
(R$10.00)
R$99.95
:ok
# if you are using the ex_money package, you can format money structs # a little less verboselymoney_struct=Money.from_float!(:USD,12.50)Cldr.to_string(money_struct)
"$12.50"
Phone numbers
# for phone numbers, we need to look outside of CLDR, to the 'ex_phone_number' package# e.g. a phone number from India{:ok,phone_number}=ExPhoneNumber.parse("+91 2212345678",nil)
# this can then be formatted in a few differnet waysExPhoneNumber.format(phone_number,:national)|>IO.puts()ExPhoneNumber.format(phone_number,:international)|>IO.puts()ExPhoneNumber.format(phone_number,:e164)|>IO.puts()ExPhoneNumber.format(phone_number,:rfc3966)|>IO.puts():ok
# notice how in different countries the numbers are formatted differently# e.g. for France the spaces are in differnt placese{:ok,phone_number}=ExPhoneNumber.parse("+33 109758351",nil)ExPhoneNumber.format(phone_number,:international)
"+33 1 09 75 83 51"
# numbers can be parsed from a variety of input formatsparsed_numbers=[{"US ","+1 (555) 123-4567"},{"UK ","+44 7911 123456"},{"India ","+91 22 1234 5678"},{"France ","+33 1 23 45 67 89"},{"Brazil ","+55 21 9 1234 5678"}]|>Enum.map(fn{country,str_phone_number}->{:ok,phone_number}=ExPhoneNumber.parse(str_phone_number,nil){country,phone_number}end)
# parsed numbers can then be cast into a few different useful formats, # e.g, for dispaying them to a local audience, without the international dialling codesIO.puts("National display format")IO.puts("-----------------------")parsed_numbers|>Enum.each(fn{country,phone_number}->"#{country}#{ExPhoneNumber.format(phone_number,:national)}"|>IO.puts()end)
National display format
-----------------------
US (555) 123-4567
UK 07911 123456
India 022 1234 5678
France 01 23 45 67 89
Brazil (21) 91234-5678
# or for international audiencesIO.puts("International format")IO.puts("-----------------------")parsed_numbers|>Enum.each(fn{country,phone_number}->"#{country}#{ExPhoneNumber.format(phone_number,:international)}"|>IO.puts()end)
International format
-----------------------
US +1 555-123-4567
UK +44 7911 123456
India +91 22 1234 5678
France +33 1 23 45 67 89
Brazil +55 21 91234-5678
:ok
# or for storing them consistently in a databaseIO.puts("E164 Standard format")IO.puts("-----------------------")parsed_numbers|>Enum.each(fn{country,phone_number}->"#{country}#{ExPhoneNumber.format(phone_number,:e164)}"|>IO.puts()end)
E164 Standard format
-----------------------
US +15551234567
UK +447911123456
India +912212345678
France +33123456789
Brazil +5521912345678
:ok
Ordinals, Roman numerals, words
# and there are certain applications where you may want to spell out numbers explicitly["en-US","hi-IN","pt-BR"]|>Enum.each(fnlocale->Cldr.Number.to_string!(1234,format: :spellout,locale: locale)|>IO.puts()end)
one thousand two hundred thirty-four
एक हज़ार दो सौ चौंतीस
mil duzentos e trinta e quatro
:ok
# in some languages, year values are sometimes treated differently:Cldr.Number.to_string!(1989,format: :spellout,locale: "en-US")|>IO.puts()Cldr.Number.to_string!(1989,format: :spellout_year,locale: "en-US")|>IO.puts()
one thousand nine hundred eighty-nine
nineteen eighty-nine
:ok
# why is it so difficult to count in French?IO.puts("English:")[60,70,80,90]|>Enum.each(fnnumber->Cldr.Number.to_string!(number,format: :spellout,locale: "en-US")|>IO.puts()end)IO.puts("\nvs French:")[60,70,80,90]|>Enum.each(fnnumber->Cldr.Number.to_string!(number,format: :spellout,locale: "fr-FR")|>IO.puts()end)
# Roman numerals are sometimes used for naming things, like sections, chapters, or events("Super Bowl "<>Cldr.Number.to_string!(59,format: :roman))|>IO.puts()# they can also useful for displaying a year value in an interresting way("Since "<>Cldr.Number.to_string!(2018,format: :roman))|>IO.puts()
Super Bowl LIX
Since MMXVIII
:ok
# you may want to show a number as a position (a.k.a. an ordinal number), e.g.Cldr.Number.to_string!(1,format: :ordinal)|>IO.puts()Cldr.Number.to_string!(1,format: :ordinal,locale: "hi-IN")|>IO.puts()Cldr.Number.to_string!(1,format: :ordinal,locale: "pt-BR")|>IO.puts()
08:05:28.898 [warning] ex_cldr_numbers: number format "#,##0" is being compiled. For performance reasons please consider adding this format to the `precompile_number_formats` list in the backend configuration.
1st
1ला
1º
:ok
Using formatted numbers in markup
# you can specify your own wrapper function for adding custom markup to number elementsCldr.Number.to_string!(73.46,format: :currency,currency: :USD,locale: "es-US",wrapper: fncurr,:currency_symbol->"<span class=\"text-sm\">"<>curr<>"</span>"num,:number->"<span class=\"text-lg font-semibold\">"<>num<>"</span>"el,_other->elend)
# we suggest using Phoenix.HTML.Tag to ensure valid HTML is generatedCldr.Number.to_string!(73.46,format: :currency,currency: :USD,wrapper: fncurr,:currency_symbol->Phoenix.HTML.Tag.content_tag(:span,curr,class: "text-sm")num,:number->Phoenix.HTML.Tag.content_tag(:span,num,class: "text-lg font-semibold")el,_other->elend)