Johnson Doe
Johnson Doe

Reputation: 59

toLocaleString thousand separator doesn't appear for Ewe below 100,000 for Firefox

I'm on Firefox, and if I set the locale to "ee" to toLocaleString. The thousand separator won't appear below 100,000.

(1111).toLocaleString("ee-gh")
"1111"
(10000).toLocaleString("ee-gh")
"10000"
(123456).toLocaleString("ee-gh")
"123,456"

console.log((1111).toLocaleString("ee-gh"));
console.log((10000).toLocaleString("ee-gh"));
console.log((123456).toLocaleString("ee-gh"));

Even with useGrouping set to true

(1234).toLocaleString("ee-gh", {useGrouping: true})
"1234"

Why does this happen for Ewe? If I set the locale to English, it'll work fine

(1234).toLocaleString("en-us")
"1,234"

console.log((1234).toLocaleString("ee-gh", {useGrouping: true}));

Upvotes: 1

Views: 373

Answers (1)

Blockzez
Blockzez

Reputation: 31

Locale ee has a minimum grouping digits set to 3 as seen on the CLDR survey tool. You get the grouping separator if it has at least 3 digits on the left side of the first grouping separator.. This is a rare thing and ee is the only locale as of CLDR 38 which a such value. This applies to both Chrome and Firefox.

I have something to solve this. Taking advantage of formatting to parts. Grouping separator is recieved by formatting it by million, 4 digit on the left side of the first grouping separator, because 4 is the highest value I can find for the minimum grouping digits, then it groups the non-grouped integer using that symbol every 3 digits.

function format_no_minimum_grouping_digits(value_to_format, locale, options) {
    // Create a number formatter
    const formatter = new Intl.NumberFormat(locale, options);
    const formatter_options = formatter.resolvedOptions();
    // Check if grouping is disabled 
    if (!formatter_options.useGrouping
        // The POSIX locale have grouping disabled
        || formatter_options.locale === "en-US-u-va-posix"
        // Bulgarian currency have grouping disabled
        || (new Intl.Locale(formatter_options.locale).language === "bg") && formatter_options.style === "currency") {
        // If yes format as normal
        return formatter.format(value_to_format);
    };
    // Otherwise format it to parts
    const parts = formatter.formatToParts(value_to_format);
    // Check if the grouping separator isn't applied
    const groupSym = parts.find(part => part.type === "group") === undefined ? new Intl.NumberFormat(locale, options).formatToParts(10 ** 6)[1].value : undefined;
    // If the grouping separator isn't applied, group them
    return parts.map(({type, value}) => (type === "integer" && groupSym) ? value.replace(/\B(?=(\d{3})+$)/g, groupSym) : value).join('');
}

Upvotes: 3

Related Questions