Ответ 1
На основе этой проблемы выяснилось, что было решено, что отправка node.js с интернационализацией сделает ее слишком большой. Вы можете npm install intl
и потребовать это, и он заменит toLocaleString
на версию, которая работает.
Итак, я писал небольшой вспомогательный метод для преобразования чисел в действительный формат денег ($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? Есть ли здесь работа, которую вы могли бы сделать здесь?
На основе этой проблемы выяснилось, что было решено, что отправка node.js с интернационализацией сделает ее слишком большой. Вы можете npm install intl
и потребовать это, и он заменит toLocaleString
на версию, которая работает.
На всякий случай кто-то наткнется на это, вот как я отформатировал число в действительную строку доллара США в среде 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% случаев; это более конкретно для моей конкретной реализации.
Я откровенно украл регулярное выражение для форматирования запятых из этого вопроса и взломал десятичную поддержку моей собственной воли. Пробег может отличаться.
Вот один из способов решения этой проблемы:
Запустите npm install full-icu --save
. Согласно site.icu-project.org:
ICU является зрелым, широко используемым набором библиотек, обеспечивающих поддержку Unicode и Globalization для программных приложений. ICU широко переносим и дает приложениям одинаковые результаты на всех платформах -.
При желании также можно запустить npm install cross-env --save
для поддержки пользователей Windows.
Обновите раздел 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 в узле
Итак, чтобы обновить это для тех, кто сталкивается с той же проблемой...
Мы использовали intl для нашего решения локализации при рендеринге на стороне сервера, но недавно у нас было требование добавить {timeZoneName: 'short'}
в наши параметры .toLocaleString()
, и это поле не поддерживается.
Исходный код из intl.js:
case 'timeZoneName':
fv = ''; // ###TODO
break;
Кроме того, произошел сбой в последнем выпуске исправления, который заставил нас заблокировать нашу версию до версии 1.2.4.
В конечном итоге мы отказались от использования intl в пользу full-icu. Просто добавив его в нашу пряжу, мы решили решить все проблемы с локализацией даты на сервере Node.js. Не проверили локализацию валюты, но пока все хорошо. Я рекомендую попробовать.