1--- 2layout: default 3title: Number Skeletons 4nav_order: 3 5grand_parent: Formatting 6parent: Formatting Numbers 7--- 8<!-- 9© 2019 and later: Unicode, Inc. and others. 10License & terms of use: http://www.unicode.org/copyright.html 11--> 12 13# Number Skeletons 14{: .no_toc } 15 16## Contents 17{: .no_toc .text-delta } 18 191. TOC 20{:toc} 21 22--- 23 24## Overview 25 26Number skeletons are a locale-agnostic way to configure a `NumberFormatter` in 27ICU. Number skeletons work in `MessageFormat`. 28 29Number skeletons consist of case-sensitive tokens that correspond to settings 30in ICU `NumberFormatter`. For example, to format a currency in compact notation 31with the sign always shown, you could use this skeleton: 32 33 sign-always compact-short currency/GBP 34 35***Since ICU 67***, you can also use more concise syntax: 36 37 +! K currency/GBP 38 39To use a skeleton in `MessageFormat`, use the "number" type and prefix the 40skeleton with `::` 41 42 {0, number, :: +! K currency/GBP} 43 44The ICU `toSkeleton()` API outputs the long-form skeletons, but all parts of 45ICU that read user-specified number skeletons accept both long-form and 46concise skeletons. 47 48## Syntax 49 50A token consists of a *stem* and zero or more *options*. The stem is what 51occurs before the first `"/"` character in a token, and the options are each of 52the subsequent `"/"`-delimited strings. For example, `"compact-short"` and 53"currency" are stems, and `"GBP"` is an option. 54 55Tokens are space-separated, with exceptions for concise skeletons listed at 56the end of this document. 57 58Stems might also be dynamic strings (not a fixed list); these are called 59*blueprint stems*. For example, to format a number with 2-3 significant 60digits, you could use the following stem: 61 62 @@# 63 64A few examples of number skeletons are shown below. The list of available 65stems and options can be found below in [Skeleton Stems and 66Options](#skeleton-stems-and-options). 67 68## Examples 69 70| Long Skeleton | Concise Skeleton | Input | en-US Output | Comments | 71|---|---|---|---|---| 72| `percent` | `%` | 25 | 25% | 73| `.00` | `.00` | 25 | 25.00 | Equivalent to `Precision::fixedFraction(2)` | 74| `percent .00` | `% .00` | 25 | 25.00% | 75| `scale/100` | `scale/100` | 0.3 | 30 | Multiply by 100 before formatting | 76| `percent scale/100` | `%x100` | 0.3 | 30% | 77| `measure-unit/length-meter` | `unit/meter` | 5 | 5 m | `UnitWidth` defaults to `Short` | 78| `measure-unit/length-meter` <br/> `unit-width-full-name` | `unit/meter` <br/> `unit-width-full-name` | 5 | 5 meters | 79| `currency/CAD` | `currency/CAD` | 10 | CA$10.00 | 80| `currency/CAD` <br/> `unit-width-narrow` | `currency/CAD` <br/> `unit-width-narrow` | 10 | $10.00 | Use the narrow symbol variant | 81| `compact-short` | `K` | 5000 | 5K | 82| `compact-long` | `KK` | 5000 | 5 thousand | 83| `compact-short` <br/> `currency/CAD` | `K currency/CAD` | 5000 | CA$5K | 84| - | - | 5000 | 5,000 | 85| `group-min2` | `,?` | 5000 | 5000 | Require 2 digits in group for separator | 86| `group-min2` | `,?` | 15000 | 15,000 | 87| `sign-always` | `+!` | 60 | +60 | Show sign on all numbers | 88| `sign-always` | `+!` | 0 | +0 | 89| `sign-except-zero` | `+?` | 60 | +60 | Show sign on all numbers except 0 | 90| `sign-except-zero` | `+?` | 0 | 0 | 91| `sign-accounting` <br/> `currency/CAD` | `() currency/CAD` | -40 | (CA$40.00) | 92 93## Skeleton Stems and Options 94 95The full set of features supported by number skeletons is listed by category below. 96 97### Notation 98 99Use one of the following stems to select compact or simple notation: 100 101- `compact-short` or `K` (concise) 102- `compact-long` or `KK` (concise) 103- `notation-simple` (or omit since this is default) 104 105There are two ways to select scientific or engineering notation: using long-form syntax or concise syntax. 106 107#### Scientific and Engineering Notation: Long Form 108 109Start with the stem `scientific` or `engineering`. Those stems take the following optional options: 110 111- `/sign-xxx` sets the sign display option for the exponent; see [Sign](#sign). 112- `/*ee` sets exponent digits to "at least 2"; use `/*eee` for at least 3 digits, etc. 113 - ***Prior to ICU 67***, use `/+ee` instead of `/*ee`. 114 115For example, all the following skeletons are valid: 116 117- `scientific` 118- `scientific/sign-always` 119- `scientific/*ee` 120- `scientific/*ee/sign-always` 121 122#### Scientific and Engineering Notation: Concise Form 123 124The following are examples of concise form: 125 126| Concise Skeleton | Equivalent Long-Form Skeleton | 127|---|---| 128| `E0` | `scientific` | 129| `E00` | `scientific/*ee` | 130| `EE+!0` | `engineering/sign-always` | 131| `E+?00` | `scientific/sign-except-zero/+ee` | 132 133More precisely: 134 1351. Start with `E` for scientific or `EE` for engineering. 1362. Allow either `+!` or `+?` as a concise sign display option. 1373. Expect one or more `0`s. If more than one, set minimum integer digits. 138 139### Unit 140 141The supported types of units are percent, currency, and measurement units. 142The following skeleton tokens are accepted: 143 144- `percent` or `%` (concise) 145- Special: `%x100` to scale the number by 100 and then format with percent 146- `permille` 147- `base-unit` 148- `currency/XXX` 149- `measure-unit/aaaa-bbbb` or `unit/bbb` (concise) 150 151The `percent`, `permille`, and `base-unit` stems do not take any options. 152 153The `currency` stem takes one required option: the three-letter ISO code of 154the currency to be formatted. 155 156The `measure-unit` stem takes one required option: the unit identifier of the 157unit to be formatted. The full unit identifier is required: both the type and 158the subtype (for example, `length-meter`). 159 160The `unit` stem is an alternative to `measure-unit` that accepts a core unit 161identifier with the subtype but not the type (for example, `meter` instead of 162`length-meter`). It also supports variations allowed by UTS 35, including the per unit with the `-per-` infix (for example, `unit/furlong-per-second`). 163 164### Per Unit 165 166To specify a unit to put in the denominator, use the following skeleton token. 167As with the `measure-unit` stem, pass the unit identifier as the option: 168 169- `per-measure-unit/aaaa-bbbb` 170 171Note that if the `unit` stem is used, the denominator can be placed in the same 172token as the numerator. 173 174### Unit Width 175 176The unit width can be specified by the following stems: 177 178- `unit-width-narrow` 179- `unit-width-short` 180- `unit-width-full-name` 181- `unit-width-iso-code` 182- `unit-width-hidden` 183 184For more details, see 185[`UNumberUnitWidth`](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/unumberformatter_8h.html). 186 187### Precision 188 189The precision category has more blueprint stems than most other categories; 190they are documented in detail below. The following non-blueprint stems are 191accepted: 192 193- `precision-integer` (round to the nearest integer) --- accepts fraction-precision options 194- `precision-unlimited` (do not perform rounding; display all digits) 195- `precision-increment/dddd` (round to *`dddd`*, a decimal number) --- see below 196- `precision-currency-standard` 197- `precision-currency-cash` 198 199To round to the nearest nickel, for example, use the skeleton 200`precision-increment/0.05`. For more information on the decimal number 201syntax, see [Scale](#scale). 202 203#### Fraction Precision 204 205The following are examples of fraction-precision stems: 206 207| Stem | Explanation | Equivalent C++ Code | 208|---|---|---| 209| `.00` | Exactly 2 fraction digits | `Precision::fixedFraction(2) ` | 210| `.00*` | At least 2 fraction digits | `Precision::minFraction(2)` | 211| `.##` | At most 2 fraction digits | `Precision::maxFraction(2) ` | 212| `.0#` | Between 1 and 2 fraction digits | `Precision::minMaxFraction(1, 2)` | 213 214More precisely, the fraction precision stem starts with `.`, then contains 215zero or more `0` symbols, which implies the minimum fraction digits. Then it 216contains either a `*`, for unlimited maximum fraction digits, or zero or more 217`#` symbols, which implies the minimum fraction digits when added to the `0` 218symbols. 219 220Note that the stem `.` is considered valid and is equivalent to `precision-integer`. 221 222Fraction-precision stems accept a single optional option: a number of significant digits. 223The options here correspond to the API functions on `FractionPrecision`. Some options 224require specifying `r` or `s` for relaxed mode or strict mode. For more information, see 225the API docs for UNumberRoundingPriority. 226 227| Skeleton | Explanation | Equivalent C++ Code | 228|---|---|---| 229| `.##/@@@*` | At most 2 fraction digits, but guarantee <br/> at least 3 significant digits | `Precision::maxFraction(2)` <br/> `.withMinDigits(3)` | 230| `.##/@##r` | Same as above | `Precision::maxFraction(2)` <br/> `.withSignificantDigits(1, 3, RELAXED)` | 231| `.##/@@@r` | Same as above, but pad trailing zeros <br/> to at least 3 significant digits | `Precision::maxFraction(2)` <br/> `.withSignificantDigits(3, 3, RELAXED)` | 232| `.00/@##` | Exactly 2 fraction digits, but do not <br/> display more than 3 significant digits | `Precision::fixedFraction(2)` <br/> `.withMaxDigits(3)` | 233| `.00/@##s` | Same as above | `Precision::fixedFraction(2)` <br/> `.withSignificantDigits(1, 3, STRICT)` | 234| `.00/@@@s` | Same as above, but pad trailing zeros <br/> to at least 3 significant digits | `Precision::fixedFraction(2)` <br/> `.withSignificantDigits(3, 3, STRICT)` | 235 236Precisely, the option follows the syntax of the significant digits stem (see below), 237but one of the following must be true: 238 239- Option has one or more `@`s followed by the wildcard character (`withMinDigits`) 240- Option has exactly one `@` followed by zero or more `#`s (`withMaxDigits`) 241- Option has one or more `@`s followed by zero or more `#`s and ends in `s` or `r` (`withSignificantDigits`) 242 243#### Significant Digits Precision 244 245The following are examples of stems for significant figures: 246 247| Stem | Explanation | Equivalent C++ Code| 248|---|---|---| 249| `@@@` | Exactly 3 significant digits | `Precision::fixedSignificantDigits(3)` | 250| `@@@*` | At least 3 significant digits | `Precision::minSignificantDigits(3)` | 251| `@##` | At most 3 significant digits | `Precision::maxSignificantDigits(3)` | 252| `@@#` | Between 2 and 3 significant digits | `...::minMaxSignificantDigits(2, 3)` | 253 254The precise syntax is very similar to fraction precision. The blueprint stem 255starts with one or more `@` symbols, which implies the minimum significant 256digits. Then it contains either a `*`, for unlimited maximum significant 257digits, or zero or more `#` symbols, which implies the minimum significant 258digits when added to the `@` symbols. 259 260#### Trailing Zero Display 261 262***Starting with ICU 69***, a new option called `trailingZeroDisplay` was added. 263To enable this in an ICU number skeleton, append `/w` to any precision token: 264 265| Skeleton | Explanation | Equivalent C++ Code | 266|---|---|---| 267| `.00/w` | Exactly 2 fraction digits, but hide <br/> them if they are all 0 | `Precision::fixedFraction(2)` <br/> `.trailingZeroDisplay(` <br/> `UNUM_TRAILING_ZERO_HIDE_IF_WHOLE)` | 268| `precision-curren` <br/> `cy-standard/w` | Currency rounding, but hide <br/> fraction digits if they are all 0 | `Precision::currency(UCURR_USAGE_STANDARD)` <br/> `.trailingZeroDisplay(` <br/> `UNUM_TRAILING_ZERO_HIDE_IF_WHOLE)` | 269 270#### Wildcard Character 271 272***Prior to ICU 67***, the symbol `+` was used for unlimited precision, instead 273of `*` (for example, `.00+`). For backwards compatibility, either `+` or `*` is 274accepted. This applies for both fraction digits and significant digits. 275 276### Rounding Mode 277 278The rounding mode can be specified by the following stems: 279 280- `rounding-mode-ceiling` 281- `rounding-mode-floor` 282- `rounding-mode-down` 283- `rounding-mode-up` 284- `rounding-mode-half-even` 285- `rounding-mode-half-down` 286- `rounding-mode-half-up` 287- `rounding-mode-unnecessary` 288 289For more details, see [Rounding Modes](rounding-modes.md). 290 291### Integer Width 292 293The following examples show how to specify integer width (minimum or maximum 294integer digits): 295 296| Long Form | Concise Form | Explanation | Equivalent C++ Code | 297|---|---|---|---| 298| `integer-width/*000` | `000` | At least 3 <br/> integer digits | `IntegerWidth::zeroFillTo(3)` | 299| `integer-width/##0` | - | Between 1 and 3 <br/> integer digits | `IntegerWidth::zeroFillTo(1)` <br/> `.truncateAt(3)` 300| `integer-width/00` | - | Exactly 2 <br/> integer digits | `IntegerWidth::zeroFillTo(2)` <br/> `.truncateAt(2)` | 301| `integer-width/*` | - | Zero or more <br/> integer digits | `IntegerWidth::zeroFillTo(0) ` 302| `integer-width-trunc` | - | Zero integer digits | `IntegerWidth::zeroFillTo(0)` <br/> `.truncateAt(0)` 303 304The long-form option starts with either a single `*` symbol, signaling no limit 305on the number of integer digits (no *`truncateAt`*), or zero or more `#` symbols. 306It should then be followed by zero or more `0` symbols, indicating the minimum 307integer digits (the argument to *`zeroFillTo`*). If there is no `*` symbol, the 308maximum integer digits (the argument to *`truncateAt`*) is the number of `#` 309symbols plus the number of `0` symbols. 310 311The concise skeleton is simply one or more `0` characters. This supports 312minimum integer digits but not maximum integer digits. 313 314The special stem `integer-width-trunc` covers the case when both *`truncateAt`* and *`zeroFillTo`* are zero. 315 316***Prior to ICU 67***, use the symbol `+` instead of `*`. 317 318### Scale 319 320To specify the scale, use the following stem and option: 321 322- `scale/dddd` 323 324where *`dddd`* is a decimal number. For example, the following are valid skeletons: 325 326- `scale/100` (multiply by 100) 327- `scale/1E2` (same as above) 328- `scale/0.5` (multiply by 0.5) 329 330The decimal number should conform to a standard decimal number syntax. In 331C++, it is parsed using the decimal number library described in 332[LocalizedNumberFormatter::formatDecimal](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1number_1_1LocalizedNumberFormatter.html). 333In Java, it is parsed using 334[BigDecimal](https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#BigDecimal%28java.lang.String%29). 335For maximum compatibility, it is highly recommended that your decimal number 336is able to be parsed by both engines. 337 338### Grouping 339 340The grouping strategy can be specified by the following stems: 341 342- `group-off` or `,_` (concise) 343- `group-min2` or `,?` (concise) 344- `group-auto` (or omit since this is the default) 345- `group-on-aligned` or `,!` (concise) 346- `group-thousands` (no concise equivalent) 347 348For more details, see 349[`UNumberGroupingStrategy`](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/unumberformatter_8h.html). 350 351### Symbols 352 353The following stems are allowed for specifying the number symbols: 354 355- `latin` (use Latin-script digits) 356- `numbering-system/nnnn` (use the `nnnn` numbering system) 357 358A custom `NDecimalFormatSymbols` instance is not supported at this time. 359 360### Sign Display 361 362The following stems specify sign display: 363 364- `sign-auto` (or omit since this is the default) 365- `sign-always` or `+!` (concise) 366- `sign-never` or `+_` (concise) 367- `sign-accounting` or `()` (concise) 368- `sign-accounting-always` or `()!` (concise) 369- `sign-except-zero` or `+?` (concise) 370- `sign-accounting-except-zero` or `()?` (concise) 371- `sign-negative` or `+-` (concise) 372- `sign-accounting-negative` or `()-` (concise) 373 374For more details, see 375[`UNumberSignDisplay`](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/unumberformatter_8h.html). 376 377### Decimal Separator Display 378 379The following stems specify decimal separator display: 380 381- `decimal-auto` 382- `decimal-always` 383 384For more details, see 385[`UNumberDecimalSeparatorDisplay`](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/unumberformatter_8h.html). 386