This document maps the features defined in Unicode Technical Standard #35 (LDML) version 49 against the implementation status of the Localize library.

Two areas are explicitly out of scope:

  • Part 7 — Keyboards. Not relevant to a formatting library.

  • Part 8 — Person Names. Implemented as the separate localize_person_names package, which uses Localize's person-name locale data (stored under the :person_names key in each locale ETF) and implements the full TR35 Part 8 formatting algorithm.

Legend

  • Implemented — feature is present and tested.
  • Partial — core functionality exists but some sub-features are missing.
  • Not implemented — feature is absent.

Part 1 — Core (tr35.html)

Unicode Language and Locale Identifiers

FeatureStatusNotes
BCP 47 / RFC 5646 language tag parsingImplementedLocalize.Rfc5646.Parser, pre-compiled NimbleParsec grammar.
Unicode locale extensions (-u-)ImplementedCalendar (ca), collation (co), currency (cu), number system (nu), hour cycle (hc), first day (fw), region override (rg), measurement system (ms), and others.
Transformed extensions (-t-)ImplementedParser and struct support in Localize.LanguageTag.
Private use subtags (-x-)Implemented
Grandfathered and irregular tagsImplemented
Locale ID canonicalizationPartialAlias resolution via supplemental data. Full Annex C canonicalization algorithm not independently verified.

Locale Inheritance and Matching

FeatureStatusNotes
Parent locale chainImplementedLocalize.Locale.parent/1 uses CLDR parent locale data.
Likely subtagsImplementedLocalize.LanguageTag.add_likely_subtags/1 and remove_likely_subtags/2, including both the favor-script (default) and favor-region removal variants, verified against the CLDR likely-subtags test data.
Locale matching / best matchImplementedLocalize.LanguageTag.best_match/3 using CLDR language matching data.
Default content localesNot implemented
Locale inheritance for data lookupPartialLocale.get/3 supports :fallback option to walk parent chain. Not all data accessors use it consistently.

Validity Data

FeatureStatusNotes
Language validityImplementedSubtags are checked against the CLDR validity data by Localize.validate_locale/1 and the other Localize.validate_* functions.
Script validityImplemented
Territory validityImplemented
Variant validityImplemented
Unit validityImplemented
Subdivision validityImplemented
U and T extension validityImplemented

Part 2 — General (tr35-general.html)

Display Names

FeatureStatusNotes
Language display namesImplementedLocalize.Language.display_name/2 with :standard, :short, :long, :menu, and :variant styles.
Script display namesImplementedLocalize.Script.display_name/2 with :prefer values :standard, :short, :stand_alone, :variant.
Territory display namesImplementedLocalize.Territory.display_name/2 with :prefer values :standard, :short, :variant.
Variant display namesImplementedRendered as a subtag by Localize.Locale.LocaleDisplay.display_name/2 — de-1901 is "German (Traditional German orthography)", en-US-posix is "English (United States, Computer)".
Key/type display namesImplementedDrives Localize.Locale.LocaleDisplay.display_name/2 — en-u-kn-true renders "English (Sort Digits Numerically)". type_value_name/2 returns the localized name of a boolean keyword value ("On"/"Off"), and key_name/2 and type_name/3 return the key and type names on their own for menu use.
Locale display namesImplementedLocalize.Locale.LocaleDisplay.display_name/2 implements the CLDR locale display name algorithm.

Layout

FeatureStatusNotes
Character order (LTR/RTL)PartialData ships and is readable — Localize.Locale.get(:ar, [:layout]) gives %{character_order: :rtl, line_order: :ttb} — but there is no dedicated accessor and nothing in the library consumes it.
Line orderPartialSame :layout map; :ttb for every locale CLDR records.

Character Elements

FeatureStatusNotes
Exemplar charactersNot implemented
Ellipsis patternsImplementedLocalize.ellipsis/2 with :initial, :medial, :final, :word_initial, :word_medial, :word_final styles.
Parse lenient charactersImplementedConsumed by Localize.Number.Parser, which accepts the locale's lenient sets for the date, general and number scopes when parsing.

Delimiters

FeatureStatusNotes
Quotation marksImplementedLocalize.quote/2 with locale-appropriate primary and alternate quotation marks.

Measurement System Data

FeatureStatusNotes
Measurement system per territoryImplementedLocalize.validate_measurement_system/1 and supplemental data.
Paper size per territoryImplementedLocalize.Unit.measurement_system_for_territory(:US, :paper_size) returns :us_letter, :FR returns :a4.

Unit Elements

FeatureStatusNotes
Unit identifiers (simple, compound)ImplementedLocalize.Unit.Parser parses full CLDR unit identifier syntax including SI prefixes, powers, per-units.
Unit formatting with plural patternsImplementedLocalize.Unit.to_string/2 with :long, :short, :narrow styles.
Compound unit formattingImplementedMultiplication, division, and power patterns.
Mixed/sequence unitsPartialLocalize.Unit struct supports mixed units; formatting coverage not fully verified.
Duration unit patterns (hms)ImplementedLocalize.Duration.to_time_string/2 formats durations as "hh:mm:ss" with unbounded hours. to_string/2 formats as localized unit list (e.g., "11 months, 30 days").
Coordinate units (N/S/E/W)Not implemented
Unit conversionImplementedLocalize.Unit.Conversion with factor/offset mappings to base units.
Unit preferences by territoryImplementedTerritory and usage-based unit selection from supplemental data.
Grammatical case in unitsPartial:grammatical_case option supported in formatter with :nominative default. Full case/gender/definiteness coverage depends on locale data.
Grammatical gender in unitsPartialData structures present; not all locales exercised.

Transforms

FeatureStatusNotes
General character transformsSeparate libraryunicode_transform implements the CLDR transform rules engine.
Script-to-script transliterationSeparate libraryProvided by unicode_transform.
Number digit transliterationImplementedLocalize.Number.Transliterate for numeric digit systems (e.g., Latin → Arabic-Indic).

List Patterns

FeatureStatusNotes
Conjunction lists ("a, b, and c")ImplementedLocalize.List.to_string/2 with :and, :and_short styles.
Disjunction lists ("a, b, or c")Implemented:or style.
Unit lists ("3 ft, 7 in")Implemented:unit, :unit_short, :unit_narrow styles.

Context Transforms

FeatureStatusNotes
Capitalization by contextNot implementedNo context-dependent capitalization for display names.

Segmentation

FeatureStatusNotes
Grapheme cluster boundariesSeparate libraryunicode_string implements Unicode text segmentation.
Word boundariesSeparate libraryProvided by unicode_string.
Sentence boundariesSeparate libraryProvided by unicode_string.
Line break boundariesSeparate libraryProvided by unicode_string.

Annotations

FeatureStatusNotes
Character/emoji labelsNot implemented
Typographic namesNot implemented

POSIX Elements

FeatureStatusNotes
Yes/no stringsImplementedLocalize.affirmative_responses/1 and negative_responses/1 return CLDR's POSIX yesstr / nostr forms; affirmative?/2 and negative?/2 match a response, folding case.
POSIX locale identifier conversionImplementedLocalize.Locale handles POSIX-style identifiers (e.g., en_US.UTF-8).

Part 3 — Numbers (tr35-numbers.html)

Number Systems

FeatureStatusNotes
Numeric systems (digit mapping)ImplementedLocalize.Number.System with 97 systems loaded from ETF.
Algorithmic systems (RBNF)ImplementedLocalize.Number.Rbnf for Roman numerals, CJK, spellout, etc.
Number system per localeImplemented:default, :native, :traditional, :finance types resolved per locale.

Number Formatting

FeatureStatusNotes
Decimal format patternsImplementedLocalize.Number.to_string/2 with full pattern support.
Percent formattingImplementedformat: :percent option.
Currency formattingImplementedformat: :currency with symbol placement, spacing.
Accounting formatImplementedformat: :accounting for parenthesized negatives.
Compact/short formats ("1.2M")Implementedformat: :decimal_short, :decimal_long, :currency_short, :currency_long.
Scientific notationImplementedExponent formatting with configurable digits.
Significant digitsImplemented@ pattern character for significant digit control.
Number paddingImplemented* pattern character for fixed-width padding.
Grouping separatorsImplementedPrimary and secondary grouping sizes.
RoundingImplementedPattern-specified increments, half-even default.
Special values (NaN, Infinity)Implemented
Number symbols per localeImplementedDecimal, grouping, percent, minus, plus, exponential, etc.

Number Parsing

FeatureStatusNotes
String to number parsingImplementedLocalize.Number.Parser with locale-aware digit transliteration.
Lenient parsingNot implemented

Number Ranges

FeatureStatusNotes
Number range formattingImplementedLocalize.Number.to_range_string/3 using locale-specific range patterns.
Approximate number formattingImplementedLocalize.Number.to_approximately_string/2, also to_at_least_string/2 and to_at_most_string/2.

Rational Numbers

FeatureStatusNotes
Fraction formattingImplementedLocalize.Number.to_ratio_string/2.

Currencies

FeatureStatusNotes
Currency codes and validationImplementedLocalize.Currency.validate_currency/1 with ISO 4217.
Currency display names (plural)ImplementedLocalize.Currency.display_name/2, pluralize/3.
Currency symbolsImplementedVia locale data.
Currency digits/roundingImplementedSupplemental currency data.
Territory currency historyImplementedLocalize.Currency.territory_currencies/1 with date ranges.
Current currency for territoryImplementedLocalize.Currency.current_currency_for_territory/1.

Plural Rules

FeatureStatusNotes
Cardinal plural rulesImplementedLocalize.Number.PluralRule.Cardinal with all CLDR operands (n, i, f, t, v, w, c, e).
Ordinal plural rulesImplementedLocalize.Number.PluralRule.Ordinal.
Plural rangesImplementedLocalize.Number.PluralRule.Range.
Minimal pairsImplementedLocalize.MinimalPairs exposes the short phrases that demonstrate a locale's plural, ordinal, case and gender forms; format/3 picks the one a number selects.
Explicit 0 and 1PartialStandard plural categories used; explicit 0/1 override not independently verified.

Rule-Based Number Formatting (RBNF)

FeatureStatusNotes
Spellout rulesImplementedLocalize.Number.Rbnf with locale-specific rule sets.
Ordinal rulesImplemented
Numbering system rulesImplementedRoman numerals, CJK, etc. via algorithmic number systems.

Part 4 — Dates (tr35-dates.html)

Calendar Elements

FeatureStatusNotes
Month names (format/standalone, wide/abbreviated/narrow)ImplementedLocalize.Calendar.months/2.
Day names (format/standalone, wide/abbreviated/narrow)ImplementedLocalize.Calendar.days/2.
Quarter namesImplementedLocalize.Calendar.quarters/2.
Era namesImplementedLocalize.Calendar.eras/2.
Day period names (AM/PM, flexible)ImplementedLocalize.Calendar.day_periods/2.
Cyclic name sets (Chinese/Dangi)ImplementedLocalize.Calendar.cyclic_years/2; U formats and parses the cyclic year name, y the year's place in the sixty-year cycle and G the cycle's number, which TR35 leaves open and ICU writes.
Month patterns (leap months)ImplementedLocalize.Calendar.month_patterns/2; a leap month formats and parses in the locale's pattern.

Date/Time Formatting

FeatureStatusNotes
Date format patterns (:short/:medium/:long/:full)ImplementedLocalize.Date.to_string/2.
Time format patterns (:short/:medium/:long/:full)ImplementedLocalize.Time.to_string/2.
DateTime combined patternsImplementedLocalize.DateTime.to_string/2.
All date format pattern symbols (y, M, d, E, G, etc.)ImplementedFull symbol set in Localize.DateTime.Formatter.
Invalid pattern fieldsImplementedA symbol at a width the Date Field Symbol Table does not list formats as U+FFFD; an undefined letter is an error.
Hour cycle (h, H, k, K)ImplementedIncluding territory and locale preferences (hi_IN allows hB), the -u-hc- override, and the skeleton symbols j, J and C.
Day periods (a, b, B)Implementeda renders AM/PM; b renders noon/midnight at the exact points and AM/PM otherwise; B selects flexible day periods ("in the morning", "mittags") from the CLDR day-period rules, falling back to AM/PM for languages without rules. Noon and midnight are judged at the precision the pattern shows, so "h B" renders 12:05 as "12 noon".
Available formats (skeletons)ImplementedLocalize.DateTime.Format.Match for skeleton matching.
Interval formatsImplementedLocalize.Interval.to_string/3 for date/time/datetime intervals, in the formats of the endpoints' calendar, with an era difference shown as ICU shows it.
Append items (missing fields)ImplementedLocalize.DateTime.Format.AppendItems matches the closest format that is a subset of the request and appends the fields it lacks, so en renders :yMMMdQ as "Jul 6, 2024 (quarter: 3)".

Date/Time Parsing

FeatureStatusNotes
String to date/time parsingImplementedLocalize.Date.parse/2, Localize.Time.parse/2, Localize.DateTime.parse/2 and Localize.Interval.parse/2 read the locale's patterns in any calendar module, and ISO 8601. A week 53 the year does not have is an error, where TR35's note on week data recommends reading it as week 1 of the next year; see ICU divergences.

Calendar Fields

FeatureStatusNotes
Relative date/time formattingImplementedLocalize.DateTime.Relative — "yesterday", "in 3 days", etc.
Calendar field display namesPartialData accessible via locale data; no dedicated public function for field names.

Supplemental Date Data

FeatureStatusNotes
Calendar preferences per territoryImplementedSupplemental data loaded from ETF.
Week data (firstDay, minDays)ImplementedLocalize.Calendar.first_day_for_locale/1 and Localize.Calendar.min_days_for_locale/1, by TR35's first day algorithm: -u-fw-, -u-rg-, -u-ca-iso8601, the region, -u-sd-, likely subtags, the world.
Weekend dataImplementedVia week data.
Time data (preferred hour cycle)ImplementedTime preferences data from ETF.
Day period rulesImplementedThe CLDR day-period rule sets (format and selection) are part of the supplemental data pipeline; the b and B format symbols select periods from them.

Time Zones

FeatureStatusNotes
Timezone format symbols (z, Z, O, v, V, X, x)ImplementedLocalize.DateTime.Formatter handles all timezone symbols.
GMT offset formattingImplementedgmtFormat with hourFormat for every known offset, zero included ("GMT+00:00", "GMT+0"), with a two-digit hour in the long format and the seconds of an offset that has them ("GMT-07:52:58"), and gmtUnknownFormat ("GMT+?") when the offset is unknown — the two styles TR35 defines. gmtZeroFormat is still in the data but no TR35 formatting rule uses it.
UTC designation (CLDR 49)ImplementedCLDR 49's gmtFormat and gmtUnknownFormat alt="utc" forms, which spell the unambiguous designation for Coordinated Universal Time where gmtFormat may spell the London zone's "GMT". designation: :utc on Localize.DateTime.Timezone.gmt_format/3 writes them — "UTC+01:00" and "UTC+?" in en, "التوقيت العالمي+1:00" in ar against its "غرينتش+1:00" — and non_location_format/3 passes it to its GMT fallback. Both spellings read back through parse_offset/2. The pattern symbols (O, OOOO, ZZZZ) write the locale's gmtFormat, which is the designation TR35 gives them.
Dual offset format (CLDR 49)ImplementedCLDR 49's dualOffsetFormat, joining the two offsets a zone keeps so the localized GMT format describes a zone that moves between them: offsets: :dual on Localize.DateTime.Timezone.gmt_format/3 writes Los Angeles as "GMT-8/-7" and Denver as "GMT-7/-6", where Phoenix keeps one offset and stays "GMT-7". The pair comes from the configured time zone database, sampled across the year around the value's time, so a value with no zone writes its single offset. It names a zone rather than a time, so it does not read back through parse_offset/2 and no pattern symbol writes it — TR35 defines none.
Metazone namesImplementedThe z and v symbols render the metazone's names — "Eastern Daylight Time" and "EDT", "Eastern Time" and "ET". Both formats qualify a metazone name with the zone's country or city unless the zone is the metazone's preferred zone for the locale's country, as TR35's steps for the non-location formats give it: "Pacific Time (Canada)" and "Pacific Standard Time (Canada)" for Vancouver in en. A zone's first metazone period that CLDR gives no beginning begins with 1970, as ICU begins it, and a zone is written by its offset and its location before it.
Exemplar citiesImplementedVVV renders the exemplar city ("New York") and VVVV the generic location format ("New York Time"), which names the country of a zone that is the only one, or the primary one, in its country ("Italy Time"): by its short name where the locale has one, and by its code where the locale does not name it ("CU").
Timezone fallback formattingImplementedThe generic format falls back from the zone's or metazone's name to the generic location format and then the localized GMT format, taking a standard name for a zone that keeps one offset for 184 days either side; the specific format falls back to the localized GMT format.
Time zone parsingImplementedLocalize.DateTime.Timezone.parse_zone/2 and resolve/3 read every form TR35's parsing lists, in the order of its sample process, with the GMT format matched as leniently as it asks. Two departures from the sample, which TR35 calls only a sample: a country or city in parentheses is read only after a name the locale writes, where the sample reads "xxx (Italy)" as Rome whatever xxx is, and a country with several zones stands for its primary zone, which the sample leaves out.

Semantic Skeletons

FeatureStatusNotes
Semantic skeleton supportPartialLocalize.DateTime.SemanticSkeleton builds a skeleton from meaning ("YMDE", "MDTZ") with :length, :year_style, :zone_style, :hour_cycle, :time_precision and :alignment, taking the widths from the locale's date formats. It matches CLDR on all 240 conformance cases and rejects the field sets, and the options without their fields, that TR35 rules out; TR35's Auto zone style, which its mapping table leaves undefined, is not offered.

Supported Calendars

FeatureStatusNotes
GregorianImplementedPrimary calendar.
JapaneseImplementedEra data and formatting.
ChineseImplementedCalendar data present.
PersianImplementedCalendar data present.
CopticImplementedCalendar data present.
EthiopicImplementedIncluding Amete Alem variant.
Dangi (Korean)ImplementedCalendar data present.
BuddhistImplementedEra (BE), month, and day data tested.
HebrewImplementedEra (AM), 13-month calendar with leap year variant tested.
Islamic variantsImplemented:islamic, :islamic_civil, :islamic_rgsa, :islamic_tbla, :islamic_umalqura — eras (AH) and month names (Muharram, Ramadan, etc.) tested.
ROC (Minguo)ImplementedEra names (B.R.O.C., Minguo) tested.
Indian (Saka)ImplementedCalendar data present and included in known_calendars/0.

Part 5 — Collation (tr35-collation.html)

Core Collation

FeatureStatusNotes
UCA (Unicode Collation Algorithm)ImplementedLocalize.Collation with DUCET-based sort key generation.
CLDR root collationImplementedUses allkeys_CLDR data.
Multi-level comparison (L1-L4)ImplementedPrimary through quaternary levels.
Variable weighting (shifted)Implementedalternate: :shifted option.
Normalization (NFD)ImplementedAutomatic NFD when tailoring requires it.
French secondary sortingImplementedbackwards: :level2 / [backwards 2] directive.

Collation Options (BCP 47 keys)

FeatureStatusNotes
Strength (ks)ImplementedLevels 1-4 and identical.
Alternate (ka)Implementednoignore and shifted.
Backwards (kb)ImplementedLevel 2 reversal.
Normalization (kk)Implemented
Case level (kc)Implemented
Case first (kf)Implementedupper and lower.
Numeric collation (kn)ImplementedNumber-aware sorting via the :numeric option to Localize.Collation.sort/3 and compare/3, or the -u-kn locale extension.
Reorder (kr)ImplementedScript reordering with weight remapping.
Max variable (kv)Implementedspace, punct, symbol, currency.
Hiragana quaternary (kh)Not implementedDeprecated in recent UCA.

Collation Tailoring

FeatureStatusNotes
Locale-specific tailoring rulesImplemented110 locale/type pairs covering 97 languages, extracted from CLDR XML.
Relation operators (<, <<, <<<, <<<<, =)Implemented
Contractions (multi-character)Implemented
Expansions (slash notation)Implementede.g., ccs/cs in Hungarian.
Star syntax (<*)ImplementedUsed for CJK and other large character sets.
Context before (|)Not implemented
[before N] positioningNot implemented
[suppressContractions]ImplementedUsed by cu, sr, mk.
[optimize]Not applicableAdvisory hint; intentionally ignored.
[import]ImplementedResolved at extraction time — imported rules are inlined into the ETF. Supports BCP47 tags (e.g., und-u-co-search, de-u-co-phonebk) and short locale tags (e.g., hr).
[strength] directiveNot implementedUsed by ja:private-kana only.

Collation Types

FeatureStatusNotes
Standard collationImplementedDefault type for all locales.
Search collationImplementedRoot search rules (Arabic form equivalences, Korean jamo decomposition, [suppressContractions]) extracted from CLDR XML. 20 locale-specific search types with resolved imports. Accessed via type: :search option.
Phonebook (de), Pinyin (zh), etc.PartialSome non-standard types extracted; not all verified.

Collation Features

FeatureStatusNotes
Alphabetic index charactersNot implementedNo UI bucketing support.
Collation type fallback chainPartialFalls back to standard; full 7-step chain not verified.

Part 6 — Supplemental (tr35-info.html)

Territory Data

FeatureStatusNotes
Territory containmentImplementedLocalize.Territory.territory_containers/0, territory_containment/0.
Subdivision containmentImplementedLocalize.Territory.territory_subdivision_containment/0.
Territory information (GDP, population)ImplementedLocalize.Territory.info/1.
Language population dataImplementedVia territory info.
Emoji flagsImplementedLocalize.Territory.unicode_flag/1.

Supplemental Language Data

FeatureStatusNotes
Scripts per languageNot implementedData not exposed as a public API.
Language grouping (families)Not implemented

Code Mappings

FeatureStatusNotes
Territory code mappings (alpha-2/3, FIPS, numeric)ImplementedLocalize.Territory.territory_codes/1.
Currency code mappingsImplementedISO 4217 via Localize.Currency.

Aliases

FeatureStatusNotes
Language aliasesImplementedSupplemental alias data loaded from ETF.
Territory aliasesImplemented
Script aliasesImplemented
Variant aliasesImplemented

Parent Locales

FeatureStatusNotes
CLDR parent locale dataImplementedLocalize.Locale.parent/1.

Unit Data (Supplemental)

FeatureStatusNotes
Unit conversion factorsImplementedExtracted from CLDR XML via scripts/extract_unit_data.exs.
Unit preferences per territoryImplemented
Unit quantities and base unitsImplemented
SI and binary prefixesImplementedLocalize.Unit.Parser handles all CLDR prefixes.

Coverage Levels

FeatureStatusNotes
Coverage level assessmentNot implemented

Part 9 — MessageFormat (tr35-messageFormat.html)

MF2 Syntax

FeatureStatusNotes
Simple messagesImplementedLocalize.Message.Parser with pre-compiled NimbleParsec grammar.
Complex messagesImplemented
Quoted patterns ({{...}})Implemented
Text and escape sequencesImplemented
Declarations (.input, .local)ImplementedAll declaration types are handled by Localize.Message.format/3.
Pattern selection (.match)ImplementedWith selector resolution and variant ranking.
Expressions (literal, variable, function)Implemented
Options on functionsImplemented
Markup (open, close, standalone)ImplementedParsed and emitted in interpreter output.
AttributesImplementedParsed; treated as metadata per spec.

MF2 Default Functions

FeatureStatusNotes
:stringImplemented
:numberImplementedDelegates to Localize.Number.to_string/2. All numeric functions support signDisplay, minimumIntegerDigits, the significant-digit options, trailingZeroDisplay and roundingPriority; an unannotated numeric operand formats with the locale-aware :number default.
:integerImplemented
:percentImplemented
:currencyImplemented
:unitImplementedDelegates to Localize.Unit.to_string/2.
:dateImplementedDraft. fields and length choose a semantic skeleton; the override options timeZone and calendar are supported, calendar through calendrical.
:timeImplementedDraft. precision and timeZoneStyle choose a semantic skeleton; the override options timeZone, hour12 and calendar are supported.
:datetimeImplementedDraft. dateFields, dateLength, timePrecision and timeZoneStyle choose a semantic skeleton; the override options are supported and inherited on re-annotation.
:offsetImplementedAdjusts a numeric operand with the required add or subtract option (a non-negative integer) for both formatting and selection, per the MF2 :offset function. Used for patterns like "you and N other people".

Localize-specific MF2 functions (not in the spec)

FunctionNotes
:listFormats a list operand by delegating to Localize.List.to_string/2. Each element is itself formatted via Localize.Chars, so a list of dates, numbers, units, etc. picks up the message's locale and forwarded options. Supports a style (or type) option whose values map to CLDR list styles: "and", "and-short", "and-narrow", "or", "or-short", "or-narrow", "unit", "unit-short", "unit-narrow". Default is "and".

MF2 Error Handling

FeatureStatusNotes
Syntax errorsImplementedParser returns {:error, reason}.
Resolution errors (unknown function, unresolved variable)ImplementedUnresolved variables error per spec; an unknown function is a Localize.FormatError with reason :unknown_function.
Data model errorsImplementedAll six rules are checked by Localize.Message.Validator.validate/1: duplicate declarations (including implicit-use-then-declare and self-reference), duplicate option names, duplicate variants (NFC-normalized keys), missing selector annotation, variant key mismatch, and missing fallback variant. Localize.Message.Parser.parse/1 checks syntax only; everything that formats or serializes a message runs both passes, reporting syntax errors first.
Function option and operand validationImplementedThe select option must be a literal set directly on the expression; digit size options must be non-negative integers; string operands of the numeric functions must match the number-literal production; :currency, :unit and the date/time functions are rejected as selectors.

MF2 Data Model

FeatureStatusNotes
JSON interchange formatImplementedLocalize.Message.JSON.to_json/2 and from_json/1 for round-trip serialization to the TR35 §8 data model.
Literal code points and key normalizationImplementedLiterals keep all their code points; keys and a :string selector's value are compared in NFC (TR35 NormalizeKey), and names are compared as if normalized.
Bidirectional text handlingPartial:bidi option (:none, :isolate, :auto) wraps placeholder output in Unicode isolate characters (FSI/PDI), and the @u:dir expression attribute overrides direction per expression. The u:dir / u:id expression options are not implemented, and the :isolate strategy isolates every placeholder where the WG default strategy leaves known-LTR placeholders unisolated.

MF2 known conformance gaps

The MessageFormat working group conformance suite — including the WG :test:function / :test:format / :test:select registry functions it uses to exercise selection mechanics — runs against both the parser and the formatter (test/localize/message/formatter_conformance_test.exs). The few cases the implementation cannot yet satisfy are excluded there, each with a documented reason:

  • The u:dir / u:id expression options are not implemented (the @u:dir attribute form is).

  • The :isolate bidi strategy isolates every placeholder where the WG default strategy leaves known-LTR placeholders unisolated (three cases).


Summary

Implemented (core functionality present and tested)

  • Language tag parsing and validation (BCP 47 / RFC 5646)
  • Locale management (get/put/default/with_locale)
  • Likely subtags and locale matching
  • Number formatting (decimal, percent, currency, accounting, compact, scientific, RBNF)
  • Number parsing
  • Date, time, and datetime formatting
  • Date, time, datetime and interval parsing
  • Interval formatting
  • Relative date/time formatting
  • Unit formatting, conversion, and preferences (also include basic math functions)
  • List formatting
  • Currency data and validation
  • Territory data and display names
  • Language display names
  • Locale display names
  • Plural rules (cardinal, ordinal, ranges)
  • Collation with locale tailoring (97 languages)
  • MessageFormat 2 parsing and interpretation
  • Quotation marks and ellipsis formatting

Separate libraries

Not implemented

  • Context-dependent capitalization
  • Collation alphabetic index (UI bucketing)
  • Coordinate unit formatting (N/S/E/W)
  • Layout direction data
  • Coverage level assessment

Not in scope for Localize

  • Emoji/character annotations and labels
  • Keyboards