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