Intl.NumberFormat Parse: How to Reverse Intl Number Formatting
Intl.NumberFormat has format, formatToParts and formatRange. There is no parse.
What is missing
const nf = new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR" });
const text = nf.format(-1234.5); // "-1.234,50 €"
nf.parse(text); // TypeError: nf.parse is not a functionA parser built on the same data
numberparrot asks Intl.NumberFormat#formatToParts for the decimal, group, minus, percent and exponent symbols and the digits of the numbering system, then parses with them. Whatever Intl writes, numberparrot reads:
import { parse, parseCurrency } from "numberparrot";
parse(new Intl.NumberFormat("de-DE").format(1234.5), "de-DE"); // 1234.5
parse(new Intl.NumberFormat("en-US", { style: "percent" }).format(0.25), "en-US"); // 0.25
parse(new Intl.NumberFormat("sv-SE", { notation: "scientific" }).format(1500), "sv-SE"); // 1500
parse(new Intl.NumberFormat("ar-EG").format(-42.5), "ar-EG"); // -42.5
const usd = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", currencySign: "accounting" });
parseCurrency(usd.format(-1234.56), "en-US"); // { amount: -1234.56, currency: "USD", ... }Round trip guarantee
For values printed with enough significant digits (17), parsing gives back exactly the same JavaScript number. The test suite checks this for 17 locales in decimal, scientific, percent, currency and accounting styles:
const nf = new Intl.NumberFormat("fr-FR", { maximumSignificantDigits: 17 });
const value = 0.1 + 0.2;
parse(nf.format(value), "fr-FR") === value; // trueNumbering systems and extensions
parse(new Intl.NumberFormat("th-TH-u-nu-thai").format(1234.5), "th-TH-u-nu-thai"); // 1234.5
parse(new Intl.NumberFormat("hi-IN-u-nu-deva").format(1234.5), "hi-IN-u-nu-deva"); // 1234.5Install
npm install numberparrotZero dependencies, ESM and CommonJS, TypeScript types included. Works in Node.js 18+, Deno, Bun and browsers. Try it in the playground.