在Node.js中使用toLocaleString的完整指南

836 阅读9分钟

简介

世界各地使用的不同语言是非常多样化的。语言不仅在词汇上有差异,而且在句子和词汇结构上也有差异。这些差异引发了网络开发者以对语言敏感的格式呈现信息的需求。

toLocaleString 方法是一种方便的功能,用于对日期、数字、时间、货币以及数据结构(如JavaScript中的数组和类型化数组)进行语言敏感的格式化。toLocaleString 方法使用环境的默认区域设置进行格式化。然而,你可以用它来格式化一个不同于默认的语言。

这样做不仅是由于上面强调的不同语言之间的差异,而且是由于同一语言中存在的差异。同一种语言有几种方言和区域性变化的情况并不少见,就像英语一样,世界各地的口语都略有不同。

本文将向你介绍toLocaleString 方法,并解释你如何在Node中使用它。

内容

toLocaleString 方法的介绍

正如在介绍中已经提到的,toLocaleString 是用于将日期、数字、时间、货币以及一些数据类型和数据结构转换为语言敏感的字符串表示。

不管是哪种对象,你都可以使用toLocaleString 方法。它把localesoptions 对象作为参数。这两个参数都是可选的。如果你不传递它们,运行时将使用默认的。

toLocaleString(locales, options)

如果你想要一个不同于默认的语言,locales 参数应该是一个语言标签或一个语言标签的数组。一个语言标签,更好地称为BCP 47语言标签,通常是一个或多个子标签的序列,用连字符分隔。语言标签中唯一需要的子标签是主语言子标签。

然而,有些语言有额外的属性,你可以用这些属性从主语言副标签所确定的语言范围中缩小。一个典型的例子是英语,它在不同的地区都有差异。英语的主要语言子标签是en

由于地区差异,你可以使用地区子标签将其缩小到英语的特定变体。下表显示了一些英语语言标签以及相应的主要和区域副标签。

语言标签主要语言副标签区域子标签地区
zh-GBen英国联合王国
en-USen美国美国
en-AUenAU澳大利亚

您还可以为支持的语言添加变体和脚本副标记。IANA语言副标记注册表包含了一个副标记的列表。如果你传递了一个地方语言的数组,将它们从最高优先级到最低优先级排列;如果支持的话,运行时将使用第一个地方语言,然后在列表中向下移动。

options 参数是一个用于定制toLocaleString 方法行为的对象。它的属性主要取决于你要格式化的数据类型;格式化数字的选项与日期和时间对象的选项不同。

如何在数字中使用toLocaleString 方法

正如前几节所指出的,你可以使用toLocaleString 方法来生成数字的本地感知字符串表示。你可以用它来表示科学和工程符号中的普通数字,附加单位,显示百分比,以及格式化货币。

正如前几节所解释的,toLocaleString 需要两个可选参数。在使用它来格式化数字时也不例外。

如何格式化货币

使用toLocaleString 方法,你可以使用你作为第一个参数传递的语言的惯例将数字格式化为货币。要做到这一点,你需要将第二个参数的style 属性设置为currency

你还必须将currency 属性的值设置为ISO 4217货币代码之一,否则你会得到一个错误。下面的代码显示了如何使用toLocaleString 进行货币格式化。

console.log(
  (-15000).toLocaleString("en-US", {
    style: "currency",
    currency: "USD",
    currencySign: "accounting",
  })
); // => ($15,000.00)

console.log(
  (15000).toLocaleString("en-US", { style: "currency", currency: "JPY" })
); // => ¥15,000

console.log(
  (15000).toLocaleString("fr-FR", { style: "currency", currency: "JPY" })
); // => 15 000 JPY

console.log(
  (15000).toLocaleString("fr-FR", {
    style: "currency",
    currency: "JPY",
    currencyDisplay: "name",
  })
); // => 15 000 yens japonais

console.log(
  (15000).toLocaleString("en-GB", {
    style: "currency",
    currency: "USD",
    currencyDisplay: "narrowSymbol",
    currencySign: "accounting",
  })
); // => $15,000.00

如上面代码中的第一个例子所示,将currencySign 属性设置为accounting ,将格式化一个负数并将其包裹在一对小括号中。currencySign 属性的默认值是standard

如何用科学和工程符号格式化数字

你也可以使用toLocaleString 方法,用简单的科学和工程符号来表达数字。你可以通过将选项参数的notation 属性设置为scientificengineering 、或compact 。默认值是standard ,它用于普通数字格式化。

下面是一些例子,说明你如何在给定的区域内用简单的科学、工程和紧凑的符号表达数字。

console.log(
  Math.LOG10E.toLocaleString("fr-FR", {
    notation: "scientific",
    maximumSignificantDigits: 5,
  })
); // => 4,3429E-1

console.log(
  Math.PI.toLocaleString("en-US", {
    notation: "compact",
    compactDisplay: "short",
  })
); // => 3.1

console.log(
  Math.E.toLocaleString("de-DE", {
    notation: "standard",
    maximumFractionDigits: 5,
  })
); // => 2,71828

console.log(
  (0.0034595).toLocaleString("en-US", {
    notation: "engineering",
    minimumSignificantDigits: 2,
    maximumSignificantDigits: 3,
  })
); // => 3.46E-3

console.log((2000).toLocaleString("en-US", { notation: "scientific" })); // => 2E3

console.log((2000).toLocaleString("en-US", { notation: "standard" })); // => 2,000

查看文档以获得科学和工程格式化选项的完整列表。

如何格式化单位

你可以使用toLocaleString 方法,通过设置第二个参数的style 属性为unit ,来追加和格式化单位。这些单位可以是简单的,也可以是复合的。ECMAScript标准有一个目前支持的简单单位的完整列表,如英里、小时、秒、比特和字节。

另一方面,你可以通过使用-per- 分隔符将两个支持的简单单位连接起来,从而产生复合单位。例如,mile-per-hour 复合单位是milehour 简单单位的衍生物。

如果你传递一个简单单元或由不允许在ECMAScript中使用的简单单元组成的复合单元,Node将抛出一个错误。

console.log(
  (80).toLocaleString("en-GB", {
    style: "unit",
    unit: "mile-per-hour",
    unitDisplay: "long",
  })
); // => 80 miles per hour

console.log(
  (80).toLocaleString("en-GB", {
    style: "unit",
    unit: "mile-per-hour",
    unitDisplay: "narrow",
  })
); // => 80mph

console.log(
  (80).toLocaleString("en-GB", {
    style: "unit",
    unit: "mile-per-hour",
    unitDisplay: "short",
  })
); // => 80 mph

console.log(
  (40).toLocaleString("de-DE", {
    style: "unit",
    unit: "kilobyte-per-second",
    unitDisplay: "narrow",
  })
); // => 40 kB/s

console.log(
  (80).toLocaleString("en-US", {
    style: "unit",
    unit: "megabyte",
  })
); // => 80 MB

使用选项对象的unitDisplay 属性来控制单位的格式化。unitDisplay 属性取值为long,short, 和narrow

将一个数字表示为百分比与附加单位类似。然而,你需要将style 属性的值设置为percent

console.log(
  (0.56).toLocaleString("de-DE", {
    style: "percent",
  })
); // 56 %

console.log(
  (200).toLocaleString("en-US", {
    style: "percent",
  })
); // 20,000%

如何使用日期和时间的toLocaleString 方法

和数字一样,你也可以将toLocaleString 方法用于日期和时间的格式化。像往常一样,locales 参数是一个 BCP 47 语言标签的字符串或一个这样的字符串的数组。options 参数是一个对象,你可以用来定制toLocaleString 的行为。

它有几个用于日期和时间格式化的属性。我们不会在这里涵盖所有的属性。然而,下面是一些你可能使用的常见属性,以及它们在指定地区的预期输出。

const date = new Date(2011, 3, 10, 10, 30, 10);

console.log(
  date.toLocaleString("en-US", {
    dateStyle: "long",
    timeStyle: "long",
  })
); // => April 10, 2011 at 10:30:10 AM GMT+3

console.log(
  date.toLocaleString("en-US", {
    dateStyle: "long",
    timeStyle: "long",
    calendar: "ethiopic",
  })
); // => Miazia 2, 2003 ERA1 at 10:30:10 AM GMT+3

console.log(
  date.toLocaleString("en-US", {
    timeZone: "America/Chicago",
    dayPeriod: "short",
    year: "numeric",
    month: "long",
    day: "numeric",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit",
    timeZoneName: "long",
  })
); // => April 10, 2011 at 02:30:10 at night Central Daylight Time

请注意,对于选项对象的哪些属性你可以同时使用是有限制的。例如,你可以同时使用dateStyletimeStyle 属性,但不能与hour,month, 和weekday 等属性一起使用。你需要查看文档以了解选项对象的哪些属性不能同时使用。

除了通常的日期和时间格式化之外,你还可以在特定的日历中格式化日期。下面的代码显示了我在埃塞俄比亚日历中的本地日期。如果你不熟悉,埃塞俄比亚日历比广泛使用的公历晚了大约8年。

在写这篇文章的时候,公历是2022年,而埃塞俄比亚历是2014年。有几种支持的历法,你可以在文档中查找。

console.log(
  new Date().toLocaleString("en-US", {
    calendar: "ethiopic",
    dateStyle: 'full'
  })
); // Thursday, Sene 2, 2014 ERA1

如何在数组中使用toLocaleString 方法

当你对一个数组使用toLocaleString ,你会得到一个代表数组元素的字符串。你可以传入前面章节中描述的localesoptions 参数。如果数组中的元素是数字,你可以使用数字格式化选项,如果是日期对象,可以使用日期和时间格式化选项。

const nums = [1200, 3000, 4500];
console.log(
  nums.toLocaleString("de-DE", {
    style: "unit",
    unit: "liter",
    unitDisplay: "narrow",
  })
); // 1.200 l,3.000 l,4.500 l

在上面的例子中,我们使用toLocaleString 方法在de-DE 地方设置中格式化一个数字数组。

Intl 界面的介绍

虽然本文的重点是toLocaleString 方法,但Intl 是另一个强大的接口,用于数字、日期和时间的语言敏感的字符串表示。它的用法与toLocaleString 方法非常相似。

Intl 接口有一些构造函数,如Intl.NumberFormatIntl.DateTimeFormat ,你可以用来格式化数字和字符串,而不是使用toLocaleString 方法。在使用toLocaleString 方法进行格式化之前,你要创建一个构造器的实例。构造函数将locale和选项作为参数,如toLocaleString

const numberFormat = new Intl.NumberFormat(locale, options);
const dateTimeFormat = new Intl.DateTimeFormat(locale, options);

下面的代码说明了你如何使用Intl.NumberFormat 构造函数来格式化数字。

console.log(new Intl.NumberFormat('en-GB', { style: 'unit', unit: 'kilobyte-per-second'}).format(20)) // 20 kB/s

toLocaleString 方法不同,你将locale和options参数传递给构造函数,并调用format 实例方法。与toLocaleString 一样,这两个参数都是可选参数。

结论

toLocaleString 方法是你可以在JavaScript中用于语言敏感的数字、货币、日期和时间格式化的功能之一。尽管不太常见,你也可以用它来格式化数组和类型化数组。

它的用法是将locale或locale数组作为第一个参数,将options对象作为第二个参数,用于定制toLocaleString 方法的行为。然而,这些参数是可选的。如果你不传递它们,Node将使用默认值。

日期和数字toLocaleString 方法与Intl 接口的相应构造函数有很多共同之处。由于它们被用于相同的目的并接受相同的参数,你需要阅读Intl 接口构造函数的文档,以获得对toLocaleString 的更多了解。