Skip to content

Add GetAmountConvertToUnit definitions to both ECMA-262 and ECMA-402#110

Open
eemeli wants to merge 9 commits into
mainfrom
convert-options
Open

Add GetAmountConvertToUnit definitions to both ECMA-262 and ECMA-402#110
eemeli wants to merge 9 commits into
mainfrom
convert-options

Conversation

@eemeli
Copy link
Copy Markdown
Member

@eemeli eemeli commented May 16, 2026

Fixes #109 by adding an AO to ECMA-262 that's superseded by a redefinition in ECMA-402.

The actual extraction of preferred units from the CLDR units.xml is left as a TODO. Edit: now included.

The preferences depend on unit category, usage, region, and value thresholds. The categories we get from validity/unit.xml, the region is calculated from the first-choice locale, and the preferences themselves are in supplemental/units.xml.

As the data always includes 001 ("the world") as one of the regions for each supported category + usage combination, no locale fallback is ever done during .convertTo(), as all well-formed locales are supported.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 16, 2026

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://tc39.github.io/proposal-amount/pr-preview/pr-110/

Built to branch gh-pages at 2026-05-18 15:16 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@eemeli eemeli force-pushed the convert-options branch from 46f7cdf to 3c8bebf Compare May 17, 2026 19:45
@eemeli eemeli requested a review from jessealama May 17, 2026 19:50
@jessealama
Copy link
Copy Markdown
Collaborator

This looks good. Thanks!

Comment thread spec.emu
Comment thread spec.emu
Copy link
Copy Markdown
Member

@gibson042 gibson042 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I have many suggestions, but this is an excellent starting point.

Comment thread spec.emu Outdated
1. Let _roundingMode_ be ? GetOption(_opts_, *"roundingMode"*, ~string~, « *"ceil"*, *"floor"*, *"expand"*, *"trunc"*, *"halfCeil"*, *"halfFloor"*, *"halfExpand"*, *"halfTrunc"*, *"halfEven"* », *"halfEven"*).
1. Let _significantDigits_ be ? GetOption(_opts_, *"significantDigits"*, ~number~, ~empty~, *undefined*).
1. Let _unit_ be ? GetOption(_opts_, *"unit"*, ~string~, ~empty~, *undefined*).
1. Let _unit_ be ? GetAmountConvertToUnit(_sourceValue_, _sourceUnit_, _opts_).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes amount.convertTo({ fractionDigits: 1.5, unit: "" }) throw because of unit while new Amount(0, { fractionDigits: 1.5, unit: "" }) throws because of fractionDigits. I think the new behavior is better (#92), but more importantly, the algorithms should be kept in sync. Ideally, they just get combined into a single operation for Amount to call like ? GetAmountOptions(_opts_) and Amount.prototype.convertTo to call like ? GetAmountOptions(_opts_, _sourceValue_, _sourceUnit_), with steps like

           1. Let _significantDigits_ be ? GetOption(_opts_, *"significantDigits"*, ~number~, ~empty~, *undefined*).
-          1. Let _unit_ be ? GetAmountConvertToUnit(_sourceValue_, _sourceUnit_, _opts_).
+          1. Let _unit_ be ? GetOption(_opts_, *"unit"*, ~string~, ~empty~, *undefined*).
+          1. If _unit_ is the empty String, throw a *RangeError* exception.
+          1. If _sourceValue_ is present or _sourceUnit_ is present, then
+            1. Assert: _sourceValue_ is present and _sourceUnit_ is present.
+            1. Set _unit_ to ? SelectUnitConversionTarget(_sourceValue_, _sourceUnit_, _unit_, _opts_).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In b853e19 I made it so that the handling of the options shared between the constructor and unit conversion is always done via GetAmountOptions.

Comment thread intl.emu Outdated
Comment thread intl.emu Outdated
Comment thread intl.emu Outdated
Comment thread intl.emu Outdated
Comment thread intl.emu Outdated
Comment thread intl.emu Outdated
Comment on lines +118 to +121
1. If _category_ is the <code>category</code> and _usage_ is the <code>usage</code> of a <code>&lt;unitPreferences&gt;</code> element in the <emu-xref href="#sec-amount-unit-preference-data">unit preference data</emu-xref>, then
1. Let _unitPreferencesParent_ be that element.
1. Else,
1. Throw a *RangeError* exception.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These steps seem to be missing some important functionality from Compute the preferred output unit, e.g. "land-agriculture-grain ⊂ land-agriculture ⊂ land ⊂ default" and "CH (Switzerland) ⊂ 155 (Western Europe) ⊂ 150 (Europe) ⊂ 001 (World)".

Copy link
Copy Markdown
Member Author

@eemeli eemeli May 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd missed that, thanks. I'll add the category usage fallback.

On region fallback, I'd prefer to follow the LDML note

This loop can be optimized to only include containing regions that occur in the data (eg, only 001 in LDML 45).

as the unit data continues not to include any numeric codes other than 001. With that in mind, I'd prefer not introducing this chain of region fallbacks unless that actually becomes necessary.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's necessary to match the algorithm defined in UTS #35 now, otherwise if such data does get introduced then implementations using ICU will become nonconformant upon upgrade and implementations not using ICU will provide inferior user experience. We want to align with that upstream standard.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usage fallbacking is added in 64a9f69.

I'll add a TODO about the region containment fallbacking.

Comment thread intl.emu
1. Let _unitPreferencesParent_ be that element.
1. Else,
1. Throw a *RangeError* exception.
1. Assert: _region_ can be matched by the <code>unicode_region_id</code> Unicode locale nonterminal.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it should be covered by a more specific type for the parameter.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean something like this?

region: a String matching the unicode_region_id Unicode locale nonterminal

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but I see now that even GetLocaleRegion is documented to return just a String, so I'm comfortable with deferring this to a later cleanup.

Comment thread intl.emu Outdated
Comment thread intl.emu
@eemeli eemeli requested a review from gibson042 May 18, 2026 15:16
Copy link
Copy Markdown
Member

@gibson042 gibson042 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to name the Records that are passed between operations, but won't insist on it being part of this PR. The rest of this review is a large handful of non-blocking suggestions.

Comment thread spec.emu
Comment on lines +119 to +121
1. Let _resolvedOpts_ be ? GetAmountOptions(_options_).
1. Let _unitOption_ be _resolvedOpts_.[[Unit]].
1. Let _unit_ be ? GetAmountConvertToUnit(_sourceValue_, _sourceUnit_, _options_, _unitOption_).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems incorrect w.r.t. #92 (specifically in rejecting an undefined unit too late), but that can be sorted out later. To reïterate, though, I do expect it to end up something like GetAmountOptions ( options [ , sourceValue, sourceUnit ] ), with the operation switching into an optional mode where it ensures that the resolved [[Unit]] is not undefined (via logic that differs between base ECMA-262 and ECMA-402).

And per #95, I also expect that mode to observably read all options in alphabetical order, including locale and usage iff the implementation includes ECMA-402.

Comment thread spec.emu

<emu-clause id="sec-amount-getamountconverttounit" type="abstract operation">
<h1>
GetAmountConvertToUnit (
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: rename (both here and in intl.emu).

Suggested change
GetAmountConvertToUnit (
SelectTargetUnit (

Comment thread spec.emu
<dl class="header">
<dt>description</dt>
<dd>It validates the given _options_ (an ECMAScript object) for converting an Amount to another Amount and returns a Record with slots set to appropriate marthematical values (or *undefined*).</dd>
<dd>It validates the given _options_ for converting an Amount to another Amount and returns a Record with slots set to appropriate marthematical values (or *undefined*).</dd>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<dd>It validates the given _options_ for converting an Amount to another Amount and returns a Record with slots set to appropriate marthematical values (or *undefined*).</dd>
<dd>It validates the given _options_ for translating an Amount's value to a new unit and returns their resolved values.</dd>

Comment thread spec.emu
<dl class="header">
<dt>description</dt>
<dd>It validates the given _options_ (an ECMAScript object) for creating an Amount and returns a Record with slots set to appropriate marthematical values (or *undefined*).</dd>
<dd>It validates the given _options_ for creating an Amount and returns a Record with slots set to appropriate marthematical values (or *undefined*).</dd>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This operation is no longer unique to Amount creation.

Suggested change
<dd>It validates the given _options_ for creating an Amount and returns a Record with slots set to appropriate marthematical values (or *undefined*).</dd>
<dd>It validates the given _options_ and returns their resolved values.</dd>

Comment thread intl.emu
1. If _usage_ is *undefined*, then
1. If _locale_ is *undefined*, throw a *TypeError* exception.
1. Set _usage_ to *"default"*.
1. Let _category_ be ? GetUnitCategory(_sourceUnit_).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this depends upon the convertTo receiver rather than invocation arguments, I think it should be performed before interacting with options at all. But again, such a fix can be deferred beyond this PR.

Comment thread intl.emu
Comment on lines +66 to +75
1. Let _entry_ be the first element of _preferredUnits_.
1. Let _unit_ be _entry_.[[Unit]].
1. Repeat, while _preferredUnits_ has more than one element,
1. Let _threshold_ be _entry_.[[Threshold]].
1. Let _convertedValue_ be ? ConvertUnitValue(_sourceValue_, _sourceUnit_, _unit_).
1. If _convertedValue_ is not finite or abs(ℝ(_convertedValue_)) ≥ _threshold_, return _unit_.
1. Remove the first element of _preferredUnits_.
1. Set _entry_ to the first element of _preferredUnits_.
1. Set _unit_ to _entry_.[[Unit]].
1. Return _unit_.
Copy link
Copy Markdown
Member

@gibson042 gibson042 May 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These steps can be greatly simplified.

Suggested change
1. Let _entry_ be the first element of _preferredUnits_.
1. Let _unit_ be _entry_.[[Unit]].
1. Repeat, while _preferredUnits_ has more than one element,
1. Let _threshold_ be _entry_.[[Threshold]].
1. Let _convertedValue_ be ? ConvertUnitValue(_sourceValue_, _sourceUnit_, _unit_).
1. If _convertedValue_ is not finite or abs(ℝ(_convertedValue_)) ≥ _threshold_, return _unit_.
1. Remove the first element of _preferredUnits_.
1. Set _entry_ to the first element of _preferredUnits_.
1. Set _unit_ to _entry_.[[Unit]].
1. Return _unit_.
1. Let _unit_ be ~unset~.
1. For each element _entry_ of _preferredUnits_, do
1. Set _unit_ to _entry_.[[Unit]].
1. Let _convertedValue_ be ? ConvertUnitValue(_sourceValue_, _sourceUnit_, _unit_).
1. If _convertedValue_ is not finite or abs(ℝ(_convertedValue_)) ≥ _entry_.[[Threshold]], return _unit_.
1. Assert: _unit_ is a String.
1. Return _unit_.

Comment thread intl.emu
Comment on lines +102 to +177
<emu-clause id="sec-amount-getpreferredunits" type="abstract operation">
<h1>
GetPreferredUnits (
_category_: a String,
_usage_: a String,
_region_: a String,
): either a normal completion containing a List of Records or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It determines the preferred units to use for the given category, usage, and region, and returns them ordered by descending threshold.</dd>
</dl>
<emu-alg>
1. Let _unitPreferenceElements_ be ? GetPreferredUnitElements(_category_, _usage_).
1. Assert: _region_ can be matched by the <code>unicode_region_id</code> Unicode locale nonterminal.
1. Set _region_ to the ASCII-uppercase of _region_.
1. Let _fallback_ be an empty List.
1. Let _match_ be an empty List.
1. For each element _unitPreference_ of _unitPreferenceElements_, do
1. Assert: _unitPreference_ has an attribute <code>regions</code>.
1. Let _regionsAttr_ be the String value of the <code>regions</code> attribute of _unitPreference_.
1. Let _regions_ be StringSplitToList(_regionsAttr_, *" "*).
1. Let _geq_ be the mathematical value of the <code>geq</code> attribute of _unitPreference_ if present, or 1 otherwise.
1. Let _unit_ be the String value of the body of the _unitPreference_ element.
1. If _regions_ contains _region_, append the Record { [[Unit]]: _unit_, [[Threshold]]: _geq_ } to _match_.
1. Else if _regions_ contains *"001"*, append the Record { [[Unit]]: _unit_, [[Threshold]]: _geq_ } to _fallback_.
1. If _match_ is not empty, return _match_.
1. Assert: _fallback_ is not empty.
1. Return _fallback_.
</emu-alg>
<emu-note>
<p><a href="https://unicode.org/reports/tr35/tr35-info.html#constraints">Unicode Technical Standard #35 Part 1, Unit Preferences Constraints</a> specifies that the <emu-xref href="#sec-amount-unit-preference-data">unit preference data</emu-xref> for a given category, usage, and region-set is already in descending order [by threshold].</p>
</emu-note>
</emu-clause>

<emu-clause id="sec-amount-getpreferredunitelements" type="abstract operation">
<h1>
GetPreferredUnitElements (
_category_: a String,
_usage_: a String,
): either a normal completion containing a List or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It determines the <code>&lt;unitPreference&gt;</code> elements in the <emu-xref href="#sec-amount-unit-preference-data">unit preference data</emu-xref> that match the given category and usage.</dd>
</dl>
<emu-alg>
1. Repeat,
1. If _category_ is the <code>category</code> and _usage_ is the <code>usage</code> of a <code>&lt;unitPreferences&gt;</code> element in the <emu-xref href="#sec-amount-unit-preference-data">unit preference data</emu-xref>, then
1. Let _unitPreferencesParent_ be that element.
1. Let _unitPreferenceElements_ be the List of <code>&lt;unitPreference&gt;</code> elements in _unitPreferencesParent_.
1. Return _unitPreferenceElements_.
1. Else if _usage_ is not *"default"*, then
1. Let _len_ be the length of _usage_.
1. Let _idx_ be StringLastIndexOf(_usage_, *"-"*, _len_ - 1).
1. If _idx_ is ~not-found~ or _idx_ = 0, set _usage_ to *"default"*; else set _usage_ to the substring of _usage_ from 0 to _idx_.
1. Else,
1. Throw a *RangeError* exception.
</emu-alg>
<emu-note>
<p>
This abstract operation implements the first two steps of the
<a href="https://unicode.org/reports/tr35/tr35-info.html#compute-the-preferred-output-unit">Compute the preferred output unit</a>
algorithm specified in
<a href="https://unicode.org/reports/tr35/tr35-info.html#Unit_Preferences">Unicode Technical Standard #35 Part 6, Supplemental, Unit Preferences</a>.
</p>
</emu-note>
<emu-note type="editor">
<p>
TODO: The UTS #35 algorithm includes fallbacking for regions based on
<a href="https://www.unicode.org/cldr/charts/latest/supplemental/territory_containment_un_m_49.html">UN M.49 territory containment</a>,
but the unit preference data does not (yet) include any other numeric regions than 001.
We'll probably need to implement that in order to be compatible with possible future CLDR updates.
</p>
</emu-note>
</emu-clause>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just looking ahead, I think we want a single operation to correspond with Compute the preferred output unit.

Suggested change
<emu-clause id="sec-amount-getpreferredunits" type="abstract operation">
<h1>
GetPreferredUnits (
_category_: a String,
_usage_: a String,
_region_: a String,
): either a normal completion containing a List of Records or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It determines the preferred units to use for the given category, usage, and region, and returns them ordered by descending threshold.</dd>
</dl>
<emu-alg>
1. Let _unitPreferenceElements_ be ? GetPreferredUnitElements(_category_, _usage_).
1. Assert: _region_ can be matched by the <code>unicode_region_id</code> Unicode locale nonterminal.
1. Set _region_ to the ASCII-uppercase of _region_.
1. Let _fallback_ be an empty List.
1. Let _match_ be an empty List.
1. For each element _unitPreference_ of _unitPreferenceElements_, do
1. Assert: _unitPreference_ has an attribute <code>regions</code>.
1. Let _regionsAttr_ be the String value of the <code>regions</code> attribute of _unitPreference_.
1. Let _regions_ be StringSplitToList(_regionsAttr_, *" "*).
1. Let _geq_ be the mathematical value of the <code>geq</code> attribute of _unitPreference_ if present, or 1 otherwise.
1. Let _unit_ be the String value of the body of the _unitPreference_ element.
1. If _regions_ contains _region_, append the Record { [[Unit]]: _unit_, [[Threshold]]: _geq_ } to _match_.
1. Else if _regions_ contains *"001"*, append the Record { [[Unit]]: _unit_, [[Threshold]]: _geq_ } to _fallback_.
1. If _match_ is not empty, return _match_.
1. Assert: _fallback_ is not empty.
1. Return _fallback_.
</emu-alg>
<emu-note>
<p><a href="https://unicode.org/reports/tr35/tr35-info.html#constraints">Unicode Technical Standard #35 Part 1, Unit Preferences Constraints</a> specifies that the <emu-xref href="#sec-amount-unit-preference-data">unit preference data</emu-xref> for a given category, usage, and region-set is already in descending order [by threshold].</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-amount-getpreferredunitelements" type="abstract operation">
<h1>
GetPreferredUnitElements (
_category_: a String,
_usage_: a String,
): either a normal completion containing a List or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It determines the <code>&lt;unitPreference&gt;</code> elements in the <emu-xref href="#sec-amount-unit-preference-data">unit preference data</emu-xref> that match the given category and usage.</dd>
</dl>
<emu-alg>
1. Repeat,
1. If _category_ is the <code>category</code> and _usage_ is the <code>usage</code> of a <code>&lt;unitPreferences&gt;</code> element in the <emu-xref href="#sec-amount-unit-preference-data">unit preference data</emu-xref>, then
1. Let _unitPreferencesParent_ be that element.
1. Let _unitPreferenceElements_ be the List of <code>&lt;unitPreference&gt;</code> elements in _unitPreferencesParent_.
1. Return _unitPreferenceElements_.
1. Else if _usage_ is not *"default"*, then
1. Let _len_ be the length of _usage_.
1. Let _idx_ be StringLastIndexOf(_usage_, *"-"*, _len_ - 1).
1. If _idx_ is ~not-found~ or _idx_ = 0, set _usage_ to *"default"*; else set _usage_ to the substring of _usage_ from 0 to _idx_.
1. Else,
1. Throw a *RangeError* exception.
</emu-alg>
<emu-note>
<p>
This abstract operation implements the first two steps of the
<a href="https://unicode.org/reports/tr35/tr35-info.html#compute-the-preferred-output-unit">Compute the preferred output unit</a>
algorithm specified in
<a href="https://unicode.org/reports/tr35/tr35-info.html#Unit_Preferences">Unicode Technical Standard #35 Part 6, Supplemental, Unit Preferences</a>.
</p>
</emu-note>
<emu-note type="editor">
<p>
TODO: The UTS #35 algorithm includes fallbacking for regions based on
<a href="https://www.unicode.org/cldr/charts/latest/supplemental/territory_containment_un_m_49.html">UN M.49 territory containment</a>,
but the unit preference data does not (yet) include any other numeric regions than 001.
We'll probably need to implement that in order to be compatible with possible future CLDR updates.
</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-amount-getpreferredunits" type="abstract operation">
<h1>
GetPreferredUnits (
_category_: a String,
_usage_: a String,
_region_: a String,
): either a normal completion containing a List of Records or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It determines the preferred units to use for the given category, usage, and region according to the <a href="https://unicode.org/reports/tr35/tr35-info.html#compute-the-preferred-output-unit">Compute the preferred output unit</a> algorithm specified in <a href="https://unicode.org/reports/tr35/tr35-info.html#Unit_Preferences">Unicode Technical Standard #35 Part 6 Supplemental, Unit Preferences</a>, and returns them ordered by descending threshold.</dd>
</dl>
<emu-alg>
1. Assert: _region_ can be matched by the <code>unicode_region_id</code> Unicode locale nonterminal and the ASCII-uppercase of _region_ is _region_.
1. Let _candidateElements_ be ~unset~.
1. Repeat, while _candidateElements_ is ~unset~,
1. If _category_ is the <code>category</code> and _usage_ is the <code>usage</code> of a <code>&lt;unitPreferences&gt;</code> element in the <emu-xref href="#sec-amount-unit-preference-data">unit preference data</emu-xref>, then
1. Let _unitPreferencesElement_ be that element.
1. Set _candidateElements_ to the List of <code>&lt;unitPreference&gt;</code> elements in _unitPreferencesElement_.
1. Else,
1. Assert: _usage_ is not *"default"*.
1. Let _len_ be the length of _usage_.
1. Let _idx_ be StringLastIndexOf(_usage_, *"-"*, _len_ - 1).
1. If _idx_ is ~not-found~ or _idx_ = 0, set _usage_ to *"default"*; else set _usage_ to the substring of _usage_ from 0 to _idx_.
1. Let _matchingUnits_ be a new empty List.
1. Repeat, while _matchingElements_ is empty,
1. For each element _unitPreference_ of _candidateElements_, do
1. Assert: _unitPreference_ has an attribute <code>regions</code>.
1. Let _regionsAttr_ be the String value of the <code>regions</code> attribute of _unitPreference_.
1. Let _regions_ be StringSplitToList(_regionsAttr_, *" "*).
1. Let _geq_ be the mathematical value of the <code>geq</code> attribute of _unitPreference_ if present, or 1 otherwise.
1. Let _unit_ be the String value of the body of the _unitPreference_.
1. If _regions_ contains _region_, append the Record { [[Unit]]: _unit_, [[Threshold]]: _geq_ } to _matchingUnits_.
1. If _matchingElements_ is empty, then
1. Assert: _region_ is not *"001"*.
1. Set _region_ to *"001".
1. Return _matchingUnits_.
</emu-alg>
<emu-note>
<p><a href="https://unicode.org/reports/tr35/tr35-info.html#constraints">Unicode Technical Standard #35 Part 1, Unit Preferences Constraints</a> specifies that the <emu-xref href="#sec-amount-unit-preference-data">unit preference data</emu-xref> for a given _category_, _usage_, and _region_ is non-empty and already in descending order [by threshold].</p>
</emu-note>
<emu-note type="editor">
<p>
TODO: The UTS #35 algorithm includes region fallback based on
<a href="https://www.unicode.org/cldr/charts/latest/supplemental/territory_containment_un_m_49.html">UN M.49 territory containment</a>,
but this algorithm currently only falls back to region <code>001</code>.
The unit preference data does not (yet) include any other numeric regions, but we'll probably need revision in order to be compatible with possible future CLDR updates.
</p>
</emu-note>
</emu-clause>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add spec text for handling for locale and usage conversion options

3 participants