使用 Number.toLocaleString() 的货币格式差异
Differences in currency formatting using Number.toLocaleString()
我一直在研究 javascript 的区域设置感知数字格式,found that Number.toLocaleString
and by extension Intl.NumberFormat 似乎是解决此问题的好方法。
特别是我更喜欢在已经实现的语言环境特定格式抽象之上构建,而不是重新发明轮子并为已经解决的问题提出另一种解决方案。
所以我在一些不同的 javascript 环境中调用了 Number.toLocaleString
,发现货币格式似乎发生了变化:
(5).toLocaleString('fr-CH', {currency: 'CHF', style: 'currency'});
// Node v10.15.1: 'CHF 5.00'
// Node v12.1.0: '5.00 CHF'
// Firefox 66.0.2: '5.00 CHF'
// Chrome 73.0.…: '5.00 CHF'
// Safari 12.0.3: '5.00 CHF'
// IE 11: '5.00 fr.'
- IE 11 与其他版本不同,但考虑到它的年龄,我并不感到惊讶。
- 令我惊讶的是
fr-CH
中 CHF
的格式似乎在节点版本 10
和 12
之间发生了变化。
- 为了比较,我查看了 fr_CH 的 glibc LC_MONETARY 设置,发现它似乎将
CHF
放在至少 1997 年左右的数量之前。这使得它特别令人困惑的是 CHF
的位置似乎与大多数当前浏览器不同。
我想了解了解:
- 为什么
CHF
的位置在这些情况下不同?
- 我知道这可能取决于可用的系统区域设置或浏览器。但是节点版本之间的变化似乎表明对我来说是最近的自愿变化。
- 是否有放置
CHF
的正确方法,或者这两种选择都适合 CH,或者更具体地说 fr-CH
?
- 为此,最好有一个实际的来源,如论文或研究数据库,而不是道听途说或轶事。
更新(2019-05-16):
针对我的部分 我想说明:
fr_CH
的格式决定在提交 3bfe134 中作为 currencyFormat{"#,##0.00 ¤ ;-#,##0.00 ¤"}
给出,但我仍然缺少该决定的来源,我很想知道它。
所以我检查了 v8 source 看我是否能找到 Number.toLocaleString
行为的定义。
- 在
builtins-number.cc
中我找到了使用Intl::NumberToLocaleString(…)
的BUILTIN(NumberPrototypeToLocaleString){…}
。
- 这让我找到了
intl-objects.cc
,它使用 icu::number::LocalizedNumberFormatter
. 实现了 Intl::NumberToLocaleString
因为 v8 使用 icu I checked out the source 继续我的搜索。
- 我第一次尝试找到数字格式的来源时,我首先查看了
decimfmt
和 numfmt
,但不知何故,我总是找不到踪迹。
- 然后我突然意识到,将格式定义与其余代码分开可能是有意义的。通过查看网站和更多来源,我终于找到了
icu4c/source/data/locales/de_CH.txt
和 icu4c/source/data/locales/fr_CH.txt
。
de_CH.txt
有 currencyFormat{"¤ #,##0.00;¤-#,##0.00"}
.
fr_CH.txt
有 currencyFormat{"#,##0.00 ¤ ;-#,##0.00 ¤"}
.
- 现在使用
git
我找到了 19 个月前首次为 fr_CH
(3bfe134) 引入 currencyFormat
的提交。
- 这可能在节点
v10
和 v12
之间。
- 我还看到在
curreencyFormat
添加到 fr_CH
之前回退到 de_CH
是有意义的,因此看到格式会改变它的方式.
提交提到 CLDR 32 alpha,我找到了 CLDR charts version 32。
但是,我目前无法弄清楚为 fr_CH
.
定义 currencyFormat
的图表所在的位置
我觉得通过找到 fr_CH
currencyFormat
的变化,我发现并理解了导致不同节点版本之间行为变化的变化。
到目前为止我不明白为什么 glibc
和 icu
在这里有差异,但这是我可以在特定项目的上下文中询问的问题。
我的印象是我仍然缺少导致 currencyFormat
实施的具体决定或 data-point - 如果我找到它,我会把它添加到这里并感到满意。
2019-05-18 更新:
- CLDR 32数据可以在cldr.unicode.org下的下载区找到。
- 从 there 我可以下载
cldr-common-32.zip
,其中包含文件 common/main/fr_CH.xml
,其中货币格式定义如下:
<currencyFormats numberSystem="latn">
<currencyFormatLength>
<currencyFormat type="standard">
<pattern draft="contributed">#,##0.00 ¤ ;-#,##0.00 ¤</pattern>
</currencyFormat>
</currencyFormatLength>
</currencyFormats>
- 通过 cldr.unicode.org 我还找到了 survey-tool 用于决定这些事项并记录此类决定的结果。
- 在 Number Formatting section for fr_CH 中我可以看到决策来源:
2019-05-21更新:
出于好奇,我在 libc-locales list as well as on the closest ticket 上问了这个问题,我可以在 unicode-org 票务系统上找到。
这促使我进一步调查,在与朋友一起研究时,我们偶然发现了 Github 上的 cldr repo,它专注于 CLDR 数据,而不是像 icu 那样在其中包含 CLDR 相关数据.
我们发现提交 c5e7787 引入了第一个更改,导致 CHF
被放置在数字之后而不是之前,并且通过该提交更好地意识到两张票。
这些工单是 CLDR-9370 and CLDR-10755,其中第二个工单是清理一些格式的跟进。
虽然表面上 CLDR-9370 似乎主要讨论小数点分隔符,但也讨论了货币符号放置。
给出的来源之一是 CERN 发布的 typography guide (pdf),其中详细说明了如何书写数字。
对于 CHF
,指南指出:
使用 google 翻译这翻译成:
Writing sums of money
The number is written in three-digit increments separated by a
non-breaking space (no point or apostrophe of separation), and is
followed (and never preceded) by the indication of the currency is
long or abbreviated. For name abbreviations currency, we use the ISO
code.
我一直在研究 javascript 的区域设置感知数字格式,found that Number.toLocaleString
and by extension Intl.NumberFormat 似乎是解决此问题的好方法。
特别是我更喜欢在已经实现的语言环境特定格式抽象之上构建,而不是重新发明轮子并为已经解决的问题提出另一种解决方案。
所以我在一些不同的 javascript 环境中调用了 Number.toLocaleString
,发现货币格式似乎发生了变化:
(5).toLocaleString('fr-CH', {currency: 'CHF', style: 'currency'});
// Node v10.15.1: 'CHF 5.00'
// Node v12.1.0: '5.00 CHF'
// Firefox 66.0.2: '5.00 CHF'
// Chrome 73.0.…: '5.00 CHF'
// Safari 12.0.3: '5.00 CHF'
// IE 11: '5.00 fr.'
- IE 11 与其他版本不同,但考虑到它的年龄,我并不感到惊讶。
- 令我惊讶的是
fr-CH
中CHF
的格式似乎在节点版本10
和12
之间发生了变化。 - 为了比较,我查看了 fr_CH 的 glibc LC_MONETARY 设置,发现它似乎将
CHF
放在至少 1997 年左右的数量之前。这使得它特别令人困惑的是CHF
的位置似乎与大多数当前浏览器不同。
我想了解了解:
- 为什么
CHF
的位置在这些情况下不同?- 我知道这可能取决于可用的系统区域设置或浏览器。但是节点版本之间的变化似乎表明对我来说是最近的自愿变化。
- 是否有放置
CHF
的正确方法,或者这两种选择都适合 CH,或者更具体地说fr-CH
?- 为此,最好有一个实际的来源,如论文或研究数据库,而不是道听途说或轶事。
更新(2019-05-16):
针对我的部分
fr_CH
的格式决定在提交 3bfe134 中作为currencyFormat{"#,##0.00 ¤ ;-#,##0.00 ¤"}
给出,但我仍然缺少该决定的来源,我很想知道它。
所以我检查了 v8 source 看我是否能找到 Number.toLocaleString
行为的定义。
- 在
builtins-number.cc
中我找到了使用Intl::NumberToLocaleString(…)
的BUILTIN(NumberPrototypeToLocaleString){…}
。 - 这让我找到了
intl-objects.cc
,它使用icu::number::LocalizedNumberFormatter
. 实现了
Intl::NumberToLocaleString
因为 v8 使用 icu I checked out the source 继续我的搜索。
- 我第一次尝试找到数字格式的来源时,我首先查看了
decimfmt
和numfmt
,但不知何故,我总是找不到踪迹。 - 然后我突然意识到,将格式定义与其余代码分开可能是有意义的。通过查看网站和更多来源,我终于找到了
icu4c/source/data/locales/de_CH.txt
和icu4c/source/data/locales/fr_CH.txt
。de_CH.txt
有currencyFormat{"¤ #,##0.00;¤-#,##0.00"}
.fr_CH.txt
有currencyFormat{"#,##0.00 ¤ ;-#,##0.00 ¤"}
.
- 现在使用
git
我找到了 19 个月前首次为fr_CH
(3bfe134) 引入currencyFormat
的提交。- 这可能在节点
v10
和v12
之间。 - 我还看到在
curreencyFormat
添加到fr_CH
之前回退到de_CH
是有意义的,因此看到格式会改变它的方式.
- 这可能在节点
提交提到 CLDR 32 alpha,我找到了 CLDR charts version 32。
但是,我目前无法弄清楚为 fr_CH
.
currencyFormat
的图表所在的位置
我觉得通过找到 fr_CH
currencyFormat
的变化,我发现并理解了导致不同节点版本之间行为变化的变化。
到目前为止我不明白为什么 glibc
和 icu
在这里有差异,但这是我可以在特定项目的上下文中询问的问题。
我的印象是我仍然缺少导致 currencyFormat
实施的具体决定或 data-point - 如果我找到它,我会把它添加到这里并感到满意。
2019-05-18 更新:
- CLDR 32数据可以在cldr.unicode.org下的下载区找到。
- 从 there 我可以下载
cldr-common-32.zip
,其中包含文件common/main/fr_CH.xml
,其中货币格式定义如下:
- 从 there 我可以下载
<currencyFormats numberSystem="latn">
<currencyFormatLength>
<currencyFormat type="standard">
<pattern draft="contributed">#,##0.00 ¤ ;-#,##0.00 ¤</pattern>
</currencyFormat>
</currencyFormatLength>
</currencyFormats>
- 通过 cldr.unicode.org 我还找到了 survey-tool 用于决定这些事项并记录此类决定的结果。
- 在 Number Formatting section for fr_CH 中我可以看到决策来源:
2019-05-21更新:
出于好奇,我在 libc-locales list as well as on the closest ticket 上问了这个问题,我可以在 unicode-org 票务系统上找到。
这促使我进一步调查,在与朋友一起研究时,我们偶然发现了 Github 上的 cldr repo,它专注于 CLDR 数据,而不是像 icu 那样在其中包含 CLDR 相关数据.
我们发现提交 c5e7787 引入了第一个更改,导致 CHF
被放置在数字之后而不是之前,并且通过该提交更好地意识到两张票。
这些工单是 CLDR-9370 and CLDR-10755,其中第二个工单是清理一些格式的跟进。
虽然表面上 CLDR-9370 似乎主要讨论小数点分隔符,但也讨论了货币符号放置。
给出的来源之一是 CERN 发布的 typography guide (pdf),其中详细说明了如何书写数字。
对于 CHF
,指南指出:
使用 google 翻译这翻译成:
Writing sums of money
The number is written in three-digit increments separated by a non-breaking space (no point or apostrophe of separation), and is followed (and never preceded) by the indication of the currency is long or abbreviated. For name abbreviations currency, we use the ISO code.