@@ -192,6 +192,25 @@ The following options and their values are required to be available on the funct
192
192
- ([digit size option](#digit-size-options))
193
193
- `maximumSignificantDigits`
194
194
- ([digit size option](#digit-size-options))
195
+ - `trailingZeroDisplay`
196
+ - `auto` (default)
197
+ - `stripIfInteger`
198
+ - `roundingPriority`
199
+ - `auto` (default)
200
+ - `morePrecision`
201
+ - `lessPrecision`
202
+ - `roundingIncrement`
203
+ - 1 (default), 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, and 5000
204
+ - `roundingMode`
205
+ - `ceil`
206
+ - `floor`
207
+ - `expand`
208
+ - `trunc`
209
+ - `halfCeil`
210
+ - `halfFloor`
211
+ - `halfExpand` (default)
212
+ - `halfTrunc`
213
+ - `halfEven`
195
214
196
215
If the _operand_ of the _expression_ is an implementation-defined type,
197
216
such as the _resolved value_ of an _expression_ with a `:number` or `:integer` _annotation_,
@@ -207,37 +226,6 @@ with _options_ on the _expression_ taking priority over any option values of the
207
226
> would be formatted with the resolved options
208
227
> `{ notation: 'scientific', minimumFractionDigits: '1' }`.
209
228
210
- > [!NOTE]
211
- > The following options and option values are being developed during the Technical Preview
212
- > period.
213
-
214
- The following values for the option `style` are _not_ part of the default registry.
215
- Implementations SHOULD avoid creating options that conflict with these, but
216
- are encouraged to track development of these options during Tech Preview:
217
- - `currency`
218
- - `unit`
219
-
220
- The following options are _not_ part of the default registry.
221
- Implementations SHOULD avoid creating options that conflict with these, but
222
- are encouraged to track development of these options during Tech Preview:
223
- - `currency`
224
- - valid [Unicode Currency Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeCurrencyIdentifier)
225
- (no default)
226
- - `currencyDisplay`
227
- - `symbol` (default)
228
- - `narrowSymbol`
229
- - `code`
230
- - `name`
231
- - `currencySign`
232
- - `accounting`
233
- - `standard` (default)
234
- - `unit`
235
- - (anything not empty)
236
- - `unitDisplay`
237
- - `long`
238
- - `short` (default)
239
- - `narrow`
240
-
241
229
##### Default Value of `select` Option
242
230
243
231
The value `plural` is the default for the option `select`
@@ -343,37 +331,6 @@ Option values with the following names are however discarded if included in the
343
331
- `maximumFractionDigits`
344
332
- `minimumSignificantDigits`
345
333
346
- > [!NOTE]
347
- > The following options and option values are being developed during the Technical Preview
348
- > period.
349
-
350
- The following values for the option `style` are _not_ part of the default registry.
351
- Implementations SHOULD avoid creating options that conflict with these, but
352
- are encouraged to track development of these options during Tech Preview:
353
- - `currency`
354
- - `unit`
355
-
356
- The following options are _not_ part of the default registry.
357
- Implementations SHOULD avoid creating options that conflict with these, but
358
- are encouraged to track development of these options during Tech Preview:
359
- - `currency`
360
- - valid [Unicode Currency Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeCurrencyIdentifier)
361
- (no default)
362
- - `currencyDisplay`
363
- - `symbol` (default)
364
- - `narrowSymbol`
365
- - `code`
366
- - `name`
367
- - `currencySign`
368
- - `accounting`
369
- - `standard` (default)
370
- - `unit`
371
- - (anything not empty)
372
- - `unitDisplay`
373
- - `long`
374
- - `short` (default)
375
- - `narrow`
376
-
377
334
##### Default Value of `select` Option
378
335
379
336
The value `plural` is the default for the option `select`
@@ -418,6 +375,190 @@ together with the resolved options' values.
418
375
419
376
The _function_ `:integer` performs selection as described in [Number Selection](#number-selection) below.
420
377
378
+ ### The `:currency` function
379
+
380
+ The function `:currency` is a selector and formatter for currency values,
381
+ which are a specialized form of numeric selection and formatting.
382
+
383
+ #### Operands
384
+
385
+ The _operand_ of the `:currency` function can be one of any number of
386
+ implementation-defined types,
387
+ each of which contains a numerical `value` and a `currency`;
388
+ or it can be a [Number Operand](#number-operands), as long as the option
389
+ `currency` is provided.
390
+ The option `currency` MUST NOT be used to override the currency of an implementation-defined type.
391
+ Using this option in such a case results in a _Bad Option_ error.
392
+
393
+ The value of the _operand_'s `currency` MUST be either a string containing a
394
+ well-formed [Unicode Currency Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeCurrencyIdentifier)
395
+ or an implementation-defined currency type.
396
+ Although currency codes are expected to be uppercase,
397
+ implementations SHOULD treat them in a case-insensitive manner.
398
+ A well-formed Unicode Currency Identifier matches the production `currency_code` in this ABNF:
399
+ ```abnf
400
+ currency_code = 3ALPHA
401
+ ```
402
+
403
+ A [ Number Operand] ( #number-operands ) without a ` currency ` _ option_ results in a _ Bad Operand_ error.
404
+
405
+ > [ !NOTE]
406
+ > For example, in ICU4J, the type ` com.ibm.icu.util.CurrencyAmount ` can be used
407
+ > to set the amount and currency.
408
+
409
+ > [ !NOTE]
410
+ > The ` currency ` is only required to be well-formed rather than checked for validity.
411
+ > This allows new currency codes to be defined
412
+ > (there are many recent examples of this occuring).
413
+ > It also avoids requiring implementations to check currency codes for validity,
414
+ > although implementations are permitted to emit _ Bad Option_ or _ Bad Operand_ for invalid codes.
415
+
416
+ > [ !NOTE]
417
+ > For runtime environments that do not provide a ready-made data structure,
418
+ > class, or type for currency values, the implementation ought to provide
419
+ > a data structure, convenience function, or documentation on how to encode
420
+ > the value and currency code for formatting.
421
+ > For example, such an implementation might define a "currency operand"
422
+ > to include a key-value structure with specific keys to be the
423
+ > local currency operand, which might look like the following:
424
+ > ```
425
+ > {
426
+ > "value": 123.45,
427
+ > "currency": "EUR"
428
+ > }
429
+ > ```
430
+
431
+ #### Options
432
+
433
+ Some options do not have default values defined in this specification.
434
+ The defaults for these options are implementation-dependent.
435
+ In general, the default values for such options depend on the locale,
436
+ the currency,
437
+ the value of other options, or all of these.
438
+
439
+ Fraction digits for currency values behave differently than for other numeric formatters.
440
+ The number of fraction digits displayed is usually set by the currency used.
441
+ For example, USD uses 2 fraction digits, while JPY uses none.
442
+ Setting some other number of `fractionDigits` allows greater precision display
443
+ (such as when performing currency conversions or other specialized operations)
444
+ or disabling fraction digits if set to `0`.
445
+
446
+ The _option_ `trailingZeroDisplay` has a value `stripIfInteger` that is useful
447
+ for displaying currencies with their fraction digits removed when the fraction
448
+ part of the _operand_ is zero.
449
+ This is sometimes used in _messages_ to make the displayed value omit the fraction part
450
+ automatically.
451
+ > For example, this _message_:
452
+ > ```
453
+ > The special price is {$price :currency trailingZeroDisplay=stripIfInteger}.
454
+ > ```
455
+ > When used with the value `5.00 USD` in the `en-US` locale displays as:
456
+ > ```
457
+ > The special price is $5.
458
+ > ```
459
+ > But like this when when value is `5.01 USD`:
460
+ > ```
461
+ > The special price is $5.01.
462
+ > ```
463
+
464
+ Implementations MAY internally alias option values that they do not have data or a backing implementation for.
465
+ Notably, the `currencyDisplay` option has a rich set of values that mirrors developments in CLDR data.
466
+ Some implementations might not be able to produce all of these formats for every currency.
467
+
468
+ > [!NOTE]
469
+ > Except where noted otherwise, the names of _options_ and their _values_ were derived from the
470
+ > [options](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options)
471
+ > in JavaScript's `Intl.NumberFormat`.
472
+
473
+ > [!NOTE]
474
+ > The option `select` does not accept the value `ordinal` because selecting
475
+ > currency values using ordinal rules makes no sense.
476
+
477
+ The following options and their values are required to be available on the function `:currency`:
478
+ - `select`
479
+ - `plural` (default)
480
+ - `exact`
481
+ - `currency`
482
+ - well-formed [Unicode Currency Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeCurrencyIdentifier)
483
+ (no default)
484
+ - `compactDisplay` (this option only has meaning when combined with the option `notation=compact`)
485
+ - `short` (default)
486
+ - `long`
487
+ - `notation`
488
+ - `standard` (default)
489
+ - `compact`
490
+ - `numberingSystem`
491
+ - valid [Unicode Number System Identifier](https://cldr-smoke.unicode.org/spec/main/ldml/tr35.html#UnicodeNumberSystemIdentifier)
492
+ (default is locale-specific)
493
+ - `currencySign`
494
+ - `accounting`
495
+ - `standard` (default)
496
+ - `currencyDisplay`
497
+ - `narrowSymbol`
498
+ - `symbol` (default)
499
+ - `name`
500
+ - `code`
501
+ - `formalSymbol`
502
+ - `never` (this is called `hidden` in ICU)
503
+ - `useGrouping`
504
+ - `auto` (default)
505
+ - `always`
506
+ - `never`
507
+ - `min2`
508
+ - `minimumIntegerDigits`
509
+ - ([digit size option](#digit-size-options), default: `1`)
510
+ - `fractionDigits` (unlike number/integer formats, the fraction digits for currency formatting are fixed)
511
+ - `auto` (default) (the number of digits used by the currency)
512
+ - ([digit size option](#digit-size-options))
513
+ - `minimumSignificantDigits`
514
+ - ([digit size option](#digit-size-options))
515
+ - `maximumSignificantDigits`
516
+ - ([digit size option](#digit-size-options))
517
+ - `trailingZeroDisplay`
518
+ - `auto` (default)
519
+ - `stripIfInteger`
520
+ - `roundingPriority`
521
+ - `auto` (default)
522
+ - `morePrecision`
523
+ - `lessPrecision`
524
+ - `roundingIncrement`
525
+ - 1 (default), 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, and 5000
526
+ - `roundingMode`
527
+ - `ceil`
528
+ - `floor`
529
+ - `expand`
530
+ - `trunc`
531
+ - `halfCeil`
532
+ - `halfFloor`
533
+ - `halfExpand` (default)
534
+ - `halfTrunc`
535
+ - `halfEven`
536
+
537
+ If the _operand_ of the _expression_ is an implementation-defined type,
538
+ such as the _resolved value_ of an _expression_ with a `:currency` _annotation_,
539
+ it can include option values.
540
+ These are included in the resolved option values of the _expression_,
541
+ with _options_ on the _expression_ taking priority over any option values of the _operand_.
542
+
543
+ > For example, the _placeholder_ in this _message_:
544
+ > ```
545
+ > .input {$n :currency currency=USD trailingZeroDisplay=stripIfInteger}
546
+ > {{{$n :currency currencySign=accounting}}}
547
+ > ```
548
+ > would be formatted with the resolved options
549
+ > `{ currencySign: 'accounting', trailingZeroDisplay: 'stripIfInteger', currency: 'USD' }`.
550
+
551
+ #### Resolved Value
552
+
553
+ The _resolved value_ of an _expression_ with a `:currency` _function_
554
+ contains an implementation-defined currency value
555
+ of the _operand_ of the annotated _expression_,
556
+ together with the resolved options' values.
557
+
558
+ #### Selection
559
+
560
+ The _function_ `:currency` performs selection as described in [Number Selection](#number-selection) below.
561
+
421
562
### Number Operands
422
563
423
564
The _operand_ of a number function is either an implementation-defined type or
0 commit comments