View Source Cldr.LanguageTag (Cldr v2.38.0)

Represents a language tag as defined in rfc5646 with extensions "u" and "t" as defined in BCP 47.

Language tags are used to help identify languages, whether spoken, written, signed, or otherwise signaled, for the purpose of communication. This includes constructed and artificial languages but excludes languages not intended primarily for human communication, such as programming languages.


A language tag is composed from a sequence of one or more "subtags", each of which refines or narrows the range of language identified by the overall tag. Subtags, in turn, are a sequence of alphanumeric characters (letters and digits), distinguished and separated from other subtags in a tag by a hyphen ("-", [Unicode] U+002D).

There are different types of subtag, each of which is distinguished by length, position in the tag, and content: each subtag's type can be recognized solely by these features. This makes it possible to extract and assign some semantic information to the subtags, even if the specific subtag values are not recognized. Thus, a language tag processor need not have a list of valid tags or subtags (that is, a copy of some version of the IANA Language Subtag Registry) in order to perform common searching and matching operations. The only exceptions to this ability to infer meaning from subtag structure are the grandfathered tags listed in the productions 'regular' and 'irregular' below. These tags were registered under [RFC3066] and are a fixed list that can never change.

The syntax of the language tag in ABNF is:

Language-Tag = langtag ; normal language tags

           / privateuse          ; private use tag
           / grandfathered       ; grandfathered tags

langtag = language

             ["-" script]
             ["-" region]
             *("-" variant)
             *("-" extension)
             ["-" privateuse]

language = 2*3ALPHA ; shortest ISO 639 code

             ["-" extlang]       ; sometimes followed by
                                 ; extended language subtags
           / 4ALPHA              ; or reserved for future use
           / 5*8ALPHA            ; or registered language subtag

extlang = 3ALPHA ; selected ISO 639 codes

             *2("-" 3ALPHA)      ; permanently reserved

script = 4ALPHA ; ISO 15924 code

region = 2ALPHA ; ISO 3166-1 code

           / 3DIGIT              ; UN M.49 code

variant = 5*8alphanum ; registered variants

           / (DIGIT 3alphanum)

extension = singleton 1("-" (28alphanum))

                                 ; Single alphanumerics
                                 ; "x" reserved for private use

singleton = DIGIT ; 0 - 9

           / %x41-57             ; A - W
           / %x59-5A             ; Y - Z
           / %x61-77             ; a - w
           / %x79-7A             ; y - z

privateuse = "x" 1("-" (18alphanum))

grandfathered = irregular ; non-redundant tags registered

           / regular             ; during the RFC 3066 era

irregular = "en-GB-oed" ; irregular tags do not match

           / "i-ami"             ; the 'langtag' production and
           / "i-bnn"             ; would not otherwise be
           / "i-default"         ; considered 'well-formed'
           / "i-enochian"        ; These tags are all valid,
           / "i-hak"             ; but most are deprecated
           / "i-klingon"         ; in favor of more modern
           / "i-lux"             ; subtags or subtag
           / "i-mingo"           ; combination
           / "i-navajo"
           / "i-pwn"
           / "i-tao"
           / "i-tay"
           / "i-tsu"
           / "sgn-BE-FR"
           / "sgn-BE-NL"
           / "sgn-CH-DE"

regular = "art-lojban" ; these tags match the 'langtag'

           / "cel-gaulish"       ; production, but their subtags
           / "no-bok"            ; are not extended language
           / "no-nyn"            ; or variant subtags: their meaning
           / "zh-guoyu"          ; is defined by their registration
           / "zh-hakka"          ; and all of these are deprecated
           / "zh-min"            ; in favor of a more modern
           / "zh-min-nan"        ; subtag or sequence of subtags
           / "zh-xiang"

alphanum = (ALPHA / DIGIT) ; letters and numbers

All subtags have a maximum length of eight characters. Whitespace is not permitted in a language tag. There is a subtlety in the ABNF production 'variant': a variant starting with a digit has a minimum length of four characters, while those starting with a letter have a minimum length of five characters.

Unicode BCP 47 Extension type "u" - Locale

caCalendar typebuddhist, chinese, gregory
cfCurrency format stylestandard, account
coCollation typestandard, search, phonetic, pinyin
cuCurrency typeISO4217 code like "USD", "EUR"
fwFirst day of the week identifiersun, mon, tue, wed, ...
hcHour cycle identifierh12, h23, h11, h24
lbLine break style identifierstrict, normal, loose
lwWord break identifiernormal, breakall, keepall, phrase
msMeasurement system identifiermetric, ussystem, uksystem
muMeasurement unit overridecelsius, fahrenhe, kelvin which overrides the ms key
nuNumber system identifierarabext, armnlow, roman, tamldec
rgRegion overrideThe value is a unicode_region_subtag for a regular region (not a macroregion), suffixed by "ZZZZ"
sdSubdivision identifierA unicode_subdivision_id, which is a unicode_region_subtagconcatenated with a unicode_subdivision_suffix.
ssBreak suppressions identifiernone, standard
tzTimezone identifierShort identifiers defined in terms of a TZ time zone database
vaCommon variant typePOSIX style locale variant

Unicode BCP 47 Extension type "t" - Transforms

moTransform extension mechanism: to reference an authority or rules for a type of transformation
s0Transform source: for non-languages/scripts, such as fullwidth-halfwidth conversion.
d0Transform sdestination: for non-languages/scripts, such as fullwidth-halfwidth conversion.
i0Input Method Engine transform
k0Keyboard transform
t0Machine Translation: Used to indicate content that has been machine translated
h0Hybrid Locale Identifiers: h0 with the value 'hybrid' indicates that the -t- value is a language that is mixed into the main language tag to form a hybrid
x0Private use transform

Extensions are formatted by specifying keyword pairs after an extension separator. The example de-DE-u-co-phonebk specifies German as spoken in Germany with a collation of phonebk. Another example, "en-latn-AU-u-cf-account" represents English as spoken in Australia, with the number system "latn" but formatting currencies with the "accounting" style.



Parse a locale name into a t:Cldr.LanguageTag struct.

Parse a locale name into a Cldr.LanguageTag struct and raises on error

Reconstitute a textual language tag from a LanguageTag that is suitable to pass to a collator.


@type t() :: %Cldr.LanguageTag{
  backend: Cldr.backend(),
  canonical_locale_name: String.t(),
  cldr_locale_name: Cldr.Locale.locale_name(),
  extensions: map(),
  gettext_locale_name: String.t() | nil,
  language: Cldr.Locale.language(),
  language_subtags: [String.t()],
  language_variants: [String.t()],
  locale: Cldr.LanguageTag.U.t() | %{},
  private_use: [String.t()],
  rbnf_locale_name: Cldr.Locale.locale_name(),
  requested_locale_name: String.t(),
  script: Cldr.Locale.script(),
  territory: Cldr.Locale.territory_code(),
  transform: Cldr.LanguageTag.T.t() | %{}


@spec parse(String.t()) :: {:ok, t()} | {:error, {module(), String.t()}}

Parse a locale name into a t:Cldr.LanguageTag struct.


  • locale_name is any BCP 47 string.


  • {:ok, t:Cldr.LanguageTag} or

  • {:error, reason}

@spec parse!(String.t()) :: t() | none()

Parse a locale name into a Cldr.LanguageTag struct and raises on error


  • locale_name is any BCP 47 string.


  • t:Cldr.LanguageTag or

  • raises an exception

Link to this function

to_string(language_tag, omit_singular_script? \\ true)

View Source

Reconstitute a textual language tag from a LanguageTag that is suitable to pass to a collator.

Note that this function will always calculate the canonical locale name. Kernel.to_string/1 will return the pre-calculated canonical locale name and is to be preferred.


  • locale is a Cldr.LanguageTag struct returned by!/2

  • omit_singular_script? is a boolean indicating if the script name should be omitted if the landuage_tag territory has only this one script. The default is false.


  • A formatted string representation of the language tag that is also parseable back into a Cldr.LanguageTag.t()


iex> {:ok, locale} = Cldr.validate_locale "en-US", MyApp.Cldr
iex> Cldr.LanguageTag.to_string(locale)

iex> {:ok, locale} = Cldr.validate_locale "en-US-u-co-phonebk-nu-arab", MyApp.Cldr
iex> Cldr.LanguageTag.to_string(locale)