Intl.DateTimeFormat.prototype.formatToParts()

Baseline 已广泛支持

此特性已成熟稳定,适用于多种设备和浏览器版本。自 2018 年 10 月起,它已在各浏览器中可用。

formatToParts() 方法是 Intl.DateTimeFormat 实例的一个方法,它返回一个对象数组,表示通过 format() 方法格式化后的字符串的每个部分。这对于构建由区域设置特定的标记组成的自定义字符串非常有用。

试一试

const date = new Date(2012, 5);
const options = {
  weekday: "long",
  year: "numeric",
  month: "long",
  day: "numeric",
};
const dateTimeFormat = new Intl.DateTimeFormat("en-US", options);

const parts = dateTimeFormat.formatToParts(date);
const partValues = parts.map((p) => p.value);

console.log(partValues);
// Expected output: "["Friday", ", ", "June", " ", "1", ", ", "2012"]"

语法

js
formatToParts(date)

参数

date 可选

要格式化的日期。可以是 DateTemporal.PlainDateTime 对象。如果 DateTimeFormat 对象被配置为打印至少一个相关的日期部分,它还可以是 Temporal.PlainTimeTemporal.PlainDateTemporal.PlainYearMonthTemporal.PlainMonthDay 对象。

注意: Temporal.ZonedDateTime 对象总是会抛出 TypeError;请使用 Temporal.ZonedDateTime.prototype.toLocaleString() 或将其转换为 Temporal.PlainDateTime 对象。

省略该参数将格式化当前日期(由 Date.now() 返回),这可能会有些令人困惑,因此建议始终明确传递日期。

返回值

一个包含格式化日期部分的 Array。每个对象都有两个属性:typevalue,都包含一个字符串。按提供的顺序连接 value 字符串将得到与 format() 相同的字符串。type 可以是 日期时间组件 之一。

weekday

例如 "M""Monday""Montag"

era

例如 "BC""AD"

例如 "2012""96"

月份

例如 "12""January"

例如 "17"

dayPeriod

例如 "AM""PM""in the morning""noon"

小时

例如 "3""03"

minute

例如 "00"

例如 "07""42"

fractionalSecond

例如 "0""00""000"

timeZoneName

例如 "UTC""CET""Central European Time"

type 还可以是以下之一:

literal

格式模式中的任何字符串,并且不受 date 影响;例如 "/"", ""o'clock""de"" " 等。

relatedYear

一个 4 位数的公历年份,以防日历的表示是 yearName 而不是年份;例如 "2019"。有关更多详细信息,请参阅 命名年份

yearName

赋予年份的名称,通常在没有连续年份概念的日历中;例如 "geng-zi"

unknown

保留给任何未被识别为以上任何一种的标记;这种情况应很少见。

示例

使用 formatToParts()

format() 方法输出本地化的、不透明的字符串,无法直接操作。

js
const date = Date.UTC(2012, 11, 17, 3, 0, 42);

const formatter = new Intl.DateTimeFormat("en-us", {
  weekday: "long",
  year: "numeric",
  month: "numeric",
  day: "numeric",
  hour: "numeric",
  minute: "numeric",
  second: "numeric",
  fractionalSecondDigits: 3,
  hour12: true,
  timeZone: "UTC",
});

formatter.format(date);
// "Monday, 12/17/2012, 3:00:42.000 AM"

然而,在许多用户界面中,您可能希望自定义此字符串的格式,或将其与其他文本交错。formatToParts() 方法以部分形式提供相同的信息。

js
formatter.formatToParts(date);

// return value:
[
  { type: "weekday", value: "Monday" },
  { type: "literal", value: ", " },
  { type: "month", value: "12" },
  { type: "literal", value: "/" },
  { type: "day", value: "17" },
  { type: "literal", value: "/" },
  { type: "year", value: "2012" },
  { type: "literal", value: ", " },
  { type: "hour", value: "3" },
  { type: "literal", value: ":" },
  { type: "minute", value: "00" },
  { type: "literal", value: ":" },
  { type: "second", value: "42" },
  { type: "fractionalSecond", value: "000" },
  { type: "literal", value: " " },
  { type: "dayPeriod", value: "AM" },
];

现在信息可以单独获取,并可以以自定义方式重新格式化和连接。例如,可以使用 Array.prototype.map()箭头函数switch 语句模板字面量Array.prototype.join(),为特定组件插入额外的标记。

js
const dateString = formatter
  .formatToParts(date)
  .map(({ type, value }) => {
    switch (type) {
      case "dayPeriod":
        return `<em>${value}</em>`;
      default:
        return value;
    }
  })
  .join("");

console.log(dateString);
// "Monday, 12/17/2012, 3:00:42.000 <em>AM</em>"

命名年份

有些日历使用命名年份;例如,中国和藏历使用 60 年的 六十甲子 命名年份周期。这些日历没有通用的方法来明确地编号每一年的年份,因此年份是通过与公历中对应的年份相关联来区分的。在这种情况下,当 DateTimeFormat 配置为输出年份组件时,会输出一个 relatedYear 标记而不是 year

js
const df = new Intl.DateTimeFormat("zh-u-ca-chinese");
df.formatToParts(Date.UTC(2012, 11, 17, 3, 0, 42));

// return value:
[
  { type: "relatedYear", value: "2012" },
  { type: "literal", value: "年" },
  { type: "month", value: "十一月" },
  { type: "day", value: "4" },
];

有时,日期时间组件选项的组合会映射到也包含 yearName 的格式。没有单独的选项可以控制是否显示 yearName。例如,以下选项将 month 设置为 "long",并导致出现 yearName 标记,尽管 year 仍然是 "numeric"

js
const opts = { year: "numeric", month: "long", day: "numeric" };
const df = new Intl.DateTimeFormat("zh-u-ca-chinese", opts);
df.formatToParts(Date.UTC(2012, 11, 17, 3, 0, 42));

// return value:
[
  { type: "relatedYear", value: "2012" },
  { type: "yearName", value: "壬辰" },
  { type: "literal", value: "年" },
  { type: "month", value: "十一月" },
  { type: "day", value: "4" },
];

由于 format() 只是将所有 value 字符串连接在一起,因此在这种情况下,您将在输出中同时看到公历年份和年份名称。

规范

规范
ECMAScript® 2026 国际化 API 规范
# sec-Intl.DateTimeFormat.prototype.formatToParts

浏览器兼容性

另见