javascript - 使用 Number.toLocaleString() 的货币格式差异

标签 javascript unicode localization currency icu

我一直在研究 javascript 和 found 的语言环境感知数字格式那个Number.toLocaleString来自 extension Intl.NumberFormat似乎是解决这个问题的好方法。

特别是我更喜欢在已经实现的特定于语言环境的格式的抽象之上进行构建,而不是重新发明轮子并为已经解决的问题提出另一种解决方案。

所以我调用 Number.toLocaleString在一些不同的 javascript 环境中,发现货币格式似乎发生了变化:

(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 与其他版本不同,但考虑到它的年龄,我并不感到惊讶。
  • 令我惊讶的是 CHF 的格式在 fr-CH似乎在节点版本之间发生了变化 1012 .
  • 为了比较,我查看了 fr_CH 的 glibc LC_MONETARY 设置并发现它似乎放置了CHF之前的金额至少在 1997 年左右。这使得 CHF 的位置变得特别困惑。对于大多数当前浏览器似乎有所不同。


  • 我想知道和理解:
  • 为什么CHF的位置在这些情况下不同?
  • 我知道这取决于可用的系统区域设置或浏览器。但是节点版本之间的变化对我来说似乎表明了更新和自愿的变化。
  • 有没有正确的方法放置CHF或者这两种选择都可以被 CH 接受,或者更具体地说 fr-CH ?
  • 为此,拥有像论文或研究数据库这样的实际来源而不是传闻或轶事会很好。


  • 更新(2019-05-16):

    回应我的部分 answer我想说明:
  • fr_CH 的格式决定给出为 currencyFormat{"#,##0.00 ¤ ;-#,##0.00 ¤"}在提交 3bfe134但我仍然缺少决定的来源,并且很想知道它。
  • 最佳答案

    所以我查看了 v8 source看看我能不能找到Number.toLocaleString的行为在哪里被定义为。

  • builtins-number.cc我找到了 BUILTIN(NumberPrototypeToLocaleString){…}使用 Intl::NumberToLocaleString(…) .
  • 这让我找到了 intl-objects.cc它实现了 Intl::NumberToLocaleString使用 icu::number::LocalizedNumberFormatter .

  • 由于 v8 使用 icu我查看了 source继续我的搜索。
  • 我第一次尝试找到数字格式的来源,这让我查看了 decimfmtnumfmt首先,但我不知何故一直失去踪迹。
  • 然后我突然意识到,将格式定义与代码的其余部分分开可能是有意义的。通过查看网站和来源更多我终于找到了icu4c/source/data/locales/de_CH.txticu4c/source/data/locales/fr_CH.txt .
  • de_CH.txtcurrencyFormat{"¤ #,##0.00;¤-#,##0.00"} .
  • fr_CH.txtcurrencyFormat{"#,##0.00 ¤ ;-#,##0.00 ¤"} .
  • 正在使用 git我找到了第一个引入 currencyFormat 的提交为 fr_CH ( 3bfe134 ) 19 个月前。
  • 这可能在节点 v10 之间和 v12 .
  • 我还可以看到回退到 de_CH 是有意义的。之前curreencyFormat已添加到 fr_CH因此看到格式会改变它的方式。

  • 提交提到了 CLDR 32 alpha,我发现了 CLDR charts version 32 .
    但是,我目前无法弄清楚定义 currencyFormat 的图表所在的位置。为 fr_CH .

    我觉得通过找到对 fr_CH 的更改currencyFormat我发现并理解导致不同节点版本之间行为变化的变化。

    截至目前我不明白为什么 glibcicu这里有差异,但这是我可以在特定项目的背景下询问的东西。

    我的印象是我仍然缺少导致 currencyFormat 的具体决定或数据点。实现 - 如果我找到它,我会在这里添加它并感到满意。

    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我还发现了用于决定这些问题并记录这些决定的结果的调查工具。
  • Number Formatting section for fr_CH然后我可以看到决策来源:

  • Screenshot of number formatting decisions for fr_CH

    2019-05-21 更新:

    出于好奇,我在 libc-locales 上询问了这个问题。列表以及 closest ticket我可以在 unicode-org 票务系统上找到。

    这促使我进一步调查,在与 friend 一起研究时,我们偶然发现了 cldr repo在 Github 上,它专注于 CLDR 数据,而不是像 icu 那样在其中包含 CLDR 相关数据。

    我们发现提交 c5e7787引入了导致 CHF 的第一个变化被放置在数字之后而不是之前,并且通过该提交变得更好地意识到两张票。
    这些门票是CLDR-9370CLDR-10755 ,其中第二个是清除某些格式的后续操作。

    虽然从表面上看 CLDR-9370 似乎主要讨论小数点分隔符,但也讨论了货币符号的位置。

    给出的来源之一是 typography guide (pdf)由欧洲核子研究中心出版,它给出了写数字方法的详细说明。

    对于 CHF该指南指出:
    Screenshot from the CERNs typography guide, the section on writing sums of money

    使用谷歌翻译这转化为:

    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 - 使用 Number.toLocaleString() 的货币格式差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56057751/

    相关文章:

    java - 如何使 JTextField 呈现增补字符

    iphone - UILabel + IRR、KRW 和 KHR 货币符号错误

    c# - 如何创建多语言网站

    python - 将货币金额四舍五入为传统上用于货币的小数位数

    javascript - 加载时将 Google map 信息窗口居中

    javascript - 如何在 maquettejs 中的映射组件中使用函数

    Python: latex 符号到unicode?

    java - 谷歌应用程序引擎java的本地化和国际化代码?

    javascript - Angular 和 Leaflet 在点击时添加标记并获取 Coord

    javascript - 无法在 ECMA6 中使用 'class' 关键字