Skip to content

Commit

Permalink
deps: backport ddb5c2d from V8's upstream
Browse files Browse the repository at this point in the history
Original commit message:

    Make NumberFormat use the ICU currency data, fix bug in NumberFormat

    NumberFormat previously just used a min of 0 digits after the decimal and a max of 3. This CL changes it so that we use the ICU currency data, and set the min and max to the number of numbers after the decimal point for each currency.

    This CL also fixes a small bug where if the minimum fraction digits is above 3 but the maximum fraction digits isn't set, then it returns with only three numbers after the decimal point.

    BUG=435465,473104,304722
    LOG=Y

    Review URL: https://codereview.chromium.org/1231613006

    Cr-Commit-Position: refs/heads/master@{#29734}

PR-URL: #6275
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
  • Loading branch information
targos authored and jasnell committed Apr 20, 2016
1 parent ff79a58 commit 43b2292
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 7 deletions.
1 change: 1 addition & 0 deletions deps/v8/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Bert Belder <[email protected]>
Burcu Dogan <[email protected]>
Caitlin Potter <[email protected]>
Craig Schlenter <[email protected]>
Chris Nardi <[email protected]>
Christopher A. Taylor <[email protected]>
Daniel Andersson <[email protected]>
Daniel James <[email protected]>
Expand Down
19 changes: 18 additions & 1 deletion deps/v8/src/i18n.cc
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,24 @@ icu::DecimalFormat* CreateICUNumberFormat(
#endif

number_format = static_cast<icu::DecimalFormat*>(
icu::NumberFormat::createInstance(icu_locale, format_style, status));
icu::NumberFormat::createInstance(icu_locale, format_style, status));

if (U_FAILURE(status)) {
delete number_format;
return NULL;
}

UErrorCode status_digits = U_ZERO_ERROR;
uint32_t fraction_digits = ucurr_getDefaultFractionDigits(
currency.getTerminatedBuffer(), &status_digits);
if (U_SUCCESS(status_digits)) {
number_format->setMinimumFractionDigits(fraction_digits);
number_format->setMaximumFractionDigits(fraction_digits);
} else {
// Set min & max to default values (previously in i18n.js)
number_format->setMinimumFractionDigits(0);
number_format->setMaximumFractionDigits(3);
}
} else if (style == UNICODE_STRING_SIMPLE("percent")) {
number_format = static_cast<icu::DecimalFormat*>(
icu::NumberFormat::createPercentInstance(icu_locale, status));
Expand Down
18 changes: 12 additions & 6 deletions deps/v8/src/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -1099,11 +1099,19 @@ function initializeNumberFormat(numberFormat, locales, options) {
var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1);
defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid);

var mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, 0);
defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd);
var mnfd = options['minimumFractionDigits'];
var mxfd = options['maximumFractionDigits'];
if (!IS_UNDEFINED(mnfd) || !internalOptions.style === 'currency') {
mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, 0);
defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd);
}

var mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20, 3);
defineWEProperty(internalOptions, 'maximumFractionDigits', mxfd);
if (!IS_UNDEFINED(mxfd) || !internalOptions.style === 'currency') {
mnfd = IS_UNDEFINED(mnfd) ? 0 : mnfd;
fallback_limit = (mnfd > 3) ? mnfd : 3;
mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20, fallback_limit);
defineWEProperty(internalOptions, 'maximumFractionDigits', mxfd);
}

var mnsd = options['minimumSignificantDigits'];
var mxsd = options['maximumSignificantDigits'];
Expand Down Expand Up @@ -1157,8 +1165,6 @@ function initializeNumberFormat(numberFormat, locales, options) {
internalOptions,
resolved);

// We can't get information about number or currency style from ICU, so we
// assume user request was fulfilled.
if (internalOptions.style === 'currency') {
ObjectDefineProperty(resolved, 'currencyDisplay', {value: currencyDisplay,
writable: true});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Make sure minimumFractionDigits is honored

var nf = new Intl.NumberFormat("en-us",{ useGrouping: false, minimumFractionDigits: 4});

assertEquals("12345.6789", nf.format(12345.6789));
18 changes: 18 additions & 0 deletions deps/v8/test/intl/number-format/format-currency.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Make sure currency formatting is correct (for USD only displays two decimal
// places, for JPY 0, and for EUR 2).

var nf_USD = new Intl.NumberFormat(['en'], {style: 'currency', currency: 'USD'});

assertEquals("$54,306.40", nf_USD.format(parseFloat(54306.4047970)));

var nf_JPY = new Intl.NumberFormat(['ja'], {style: 'currency', currency: 'JPY'});

assertEquals("¥54,306", nf_JPY.format(parseFloat(54306.4047970)));

var nf_EUR = new Intl.NumberFormat(['pt'], {style: 'currency', currency: 'EUR'});

assertEquals("€1.000,00", nf_EUR.format(1000.00));

0 comments on commit 43b2292

Please sign in to comment.