Использование .toLocaleString() в Node.js

Итак, я писал небольшой вспомогательный метод для преобразования чисел в действительный формат денег ($xx,xxx.xx) с помощью .toLocaleString(). Все работает так, как ожидалось, при использовании его внутри Chrome, однако при использовании внутри Node.js, кажется, полностью нарушено.

Пример:

var n = 6000
console.log( n.toLocaleString('USD', {
  style: 'currency',
  currency: "USD",
  minimumFractionDigits : 2,
  maximumFractionDigits : 2
}) );

Если вы запустите это в браузере, он напечатает $6,000.00. Если вы запустите этот фрагмент внутри Node.js REPL или приложения, он возвращает 6000 как строку.

Угадайте, что это ошибка с Node.js? Есть ли здесь работа, которую вы могли бы сделать здесь?

Ответ 1

На основе этой проблемы выяснилось, что было решено, что отправка node.js с интернационализацией сделает ее слишком большой. Вы можете npm install intl и потребовать это, и он заменит toLocaleString на версию, которая работает.

Ответ 2

На всякий случай кто-то наткнется на это, вот как я отформатировал число в действительную строку доллара США в среде Node.js.

Number.prototype.toMoney = function() {
  var integer = this.toString().split('.')[0];
  var decimal = this.getDecimal();

  integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ",");

  if( !decimal || !decimal.length ) {
    decimal = "00";
  } else if ( decimal.length === 1) {
    decimal += '0';
  } else if ( decimal.length > 2 ) {
    decimal = decimal.substr(0, 2);
  }

  return '$' + integer + '.' + decimal;
};

Number.prototype.getDecimal = function() {
  var n = Math.abs(this);
  var dec = n - Math.floor(n);
  dec = ( Math.round( dec * 100 ) / 100 ).toString();

  if( dec.split('.').length ) {
    return dec.split('.')[1];
  } else return "";
};

Здесь есть несколько boo-boo, а именно расширение прототипа native Number. Вы захотите избежать этого в 90% случаев; это более конкретно для моей конкретной реализации.

Я откровенно украл регулярное выражение для форматирования запятых из этого вопроса и взломал десятичную поддержку моей собственной воли. Пробег может отличаться.

Ответ 3

Вот один из способов решения этой проблемы:

  1. Запустите npm install full-icu --save. Согласно site.icu-project.org:

    ICU является зрелым, широко используемым набором библиотек, обеспечивающих поддержку Unicode и Globalization для программных приложений. ICU широко переносим и дает приложениям одинаковые результаты на всех платформах -.

  2. При желании также можно запустить npm install cross-env --save для поддержки пользователей Windows.

  3. Обновите раздел scripts в package.json, например:

    {
      "scripts": {
        // Omit the "cross-env" part if you didn't install the package in step two
        "start": "cross-env NODE_ICU_DATA=node_modules/full-icu index.js"
      }
    }
    

Таким образом, когда вы запустите npm start, будут активированы полные данные ICU, и вы должны получить согласованные результаты между браузерной и серверной средами.

Отказ от ответственности: я не проверял, влияет ли это на производительность. В моем случае я сделал это, чтобы исправить Jest-тесты приложения, работающего в браузере, поэтому небольшой скачок производительности был бы приемлемым.

Слава Rndmax ответ здесь: Дата toLocaleDateString в узле

Ответ 4

Итак, чтобы обновить это для тех, кто сталкивается с той же проблемой...

Мы использовали intl для нашего решения локализации при рендеринге на стороне сервера, но недавно у нас было требование добавить {timeZoneName: 'short'} в наши параметры .toLocaleString(), и это поле не поддерживается.

Исходный код из intl.js:

case 'timeZoneName':
  fv = ''; // ###TODO
  break;

Кроме того, произошел сбой в последнем выпуске исправления, который заставил нас заблокировать нашу версию до версии 1.2.4.

В конечном итоге мы отказались от использования intl в пользу full-icu. Просто добавив его в нашу пряжу, мы решили решить все проблемы с локализацией даты на сервере Node.js. Не проверили локализацию валюты, но пока все хорошо. Я рекомендую попробовать.