Temporal.PlainMonthDay.from()

可用性有限

此特性不是基线特性,因为它在一些最广泛使用的浏览器中不起作用。

实验性: 这是一项实验性技术
在生产中使用此技术之前,请仔细检查浏览器兼容性表格

Temporal.PlainMonthDay.from() 静态方法会从另一个 Temporal.PlainMonthDay 对象、一个具有月和日属性的对象或一个 RFC 9557 字符串创建一个新的 Temporal.PlainMonthDay 对象。

语法

js
Temporal.PlainMonthDay.from(info)
Temporal.PlainMonthDay.from(info, options)

参数

info

以下之一:

  • 一个 Temporal.PlainMonthDay 实例,这将创建该实例的一个副本。
  • 一个 RFC 9557 字符串,包含一个日期和可选的日历。如果日历不是 iso8601,则年份是必需的。
  • 一个包含以下属性的对象(按检索和验证的顺序)
    calendar 可选

    一个字符串,对应于 calendarId 属性。默认为 "iso8601"。所有其他属性都在此日历系统中解释(与 Temporal.PlainMonthDay() 构造函数不同,后者在 ISO 日历系统中解释值)。有关常用支持的日历类型列表,请参阅 Intl.supportedValuesOf()

    一个整数,对应于 day 属性。无论 overflow 选项如何,都必须为正数。

    eraeraYear

    一个字符串和一个整数,可以用来代替 year。请参阅 PlainDateeraeraYear。仅在日历系统有纪元时使用。eraeraYear 必须同时提供。如果指定了 month,则必须提供 eraYear(与 era 一起)或 year 中的至少一个。如果同时提供了 eraeraYearyear,它们必须一致。

    月份

    一个正整数,可以用来代替 monthCode。请参阅 PlainDatemonth。无论 overflow 选项如何,都必须为正数。如果提供了 month,并且日历不是 iso8601,那么还必须提供 year(或 eraYearera 作为替代),因为在不同年份中,同一个 month 可能会映射到多个可能的 monthCode 值。monthmonthCode 中至少要提供一个。如果同时提供了 monthmonthCode,它们必须一致。

    monthCode

    对应于 monthCode 属性。monthmonthCode 中至少要提供一个。如果同时提供了 monthmonthCode,它们必须一致。

    一个整数,如果提供了 month,则用于消除歧义,因为对于某些日历,同一个 month 在不同年份可能意味着不同的 monthCode。请参阅 PlainDateyear。如果提供了年份,那么 overflow 选项会在给定的年份中验证月-日,而不仅仅是任何一年。如果指定了 month,则必须提供 eraYear(与 era 一起)或 year 中的至少一个。如果同时提供了 eraeraYearyear,它们必须一致。

options 可选

包含以下属性的对象

overflow 可选

一个字符串,指定当日期组件超出范围时(使用对象 info 时)的行为。可能的值有:

"constrain"(默认)

日期组件被限制在有效范围内。

"reject"

如果日期组件超出范围,则抛出 RangeError

返回值

一个新的 Temporal.PlainMonthDay 对象,表示由 info 在指定的 calendar 中指定的月和日。

每个 PlainMonthDay 内部存储一个完整的 ISO 8601 日期,该日期在目标日历中具有与所公开的相同的月-日。参考年份在使用 toString() 进行字符串化时可见,它会输出一个 ISO 日期。参考年份是任意但一致地选择的(也就是说,每个 (monthCode, day) 对总是映射到同一个 ISO 参考年份)。它不使用输入中提供的年份。相反,参考年份是通过查找 1972 年 12 月 31 日之前在目标日历中具有相同月-日的最新日期来选择的,如果不存在这样的日期,则选择 1972 年 12 月 31 日之后的最早日期。

例如,对于源自公历的日历,参考年份是 1972 年。对于希伯来历,参考年份是公历的 1972 年,但如果月份是 Adar I (M05L),这是一个闰月,则参考年份是 1970 年(希伯来历的 5730 年),因为下一个闰年是 1973 年(希伯来历的 5733 年),它在 1972 年之后。

这种参考年份的规范化确保了 equals() 可以直接比较底层的 ISO 日期,而无需额外的计算。

异常

TypeError

在以下情况之一中抛出

  • info 不是对象或字符串。
  • options 不是对象或 undefined
  • 所提供的属性不足以明确确定一个日期。你通常需要提供一个 year(或 eraeraYear)、一个 month 和一个 day,或者一个 monthCode 和一个 day
RangeError

在以下情况之一中抛出

  • 指定相同组件的提供的属性不一致。
  • 提供的非数字属性无效;例如,如果 monthCode 在此日历中从未是有效的月份代码。
  • 提供的数字属性超出范围,并且 options.overflow 设置为 "reject"
  • 该信息不在 可表示范围 内,该范围是距 Unix 纪元 ±(108 + 1) 天,或大约 ±273,972.6 年。

示例

从对象创建 PlainMonthDay

js
// Month code + day
const md = Temporal.PlainMonthDay.from({ monthCode: "M05", day: 2 });
console.log(md.toString()); // 05-02

// Month + day (only for ISO calendar)
const md2 = Temporal.PlainMonthDay.from({ month: 7, day: 1 });
console.log(md2.toString()); // 07-01

// Year + month + day
const md3 = Temporal.PlainMonthDay.from({ year: 2021, month: 7, day: 1 });
console.log(md3.toString()); // 07-01

// Year + month + day in a different calendar (where year is required)
const md4 = Temporal.PlainMonthDay.from({
  year: 2021,
  month: 7,
  day: 1,
  calendar: "hebrew",
});
console.log(md4.toString()); // 1972-03-16[u-ca=hebrew]

// Month code + day in a different calendar
const md5 = Temporal.PlainMonthDay.from({
  monthCode: "M05L",
  day: 1,
  calendar: "hebrew",
});
console.log(md5.toString()); // 1970-02-07[u-ca=hebrew]

控制溢出行为

默认情况下,超出范围的值会被约束到有效范围内。一个没有明确参考年份的月-日只要存在某一年份中它是有效的,它就是有效的,即使它不是每年都出现。如果年、月、日都给出,那么映射到有效月-日的规则可能会很复杂且特定于每个日历,但通常的行为是这样的:

  • 如果 year/month 组合无效,month 会被约束以在该年份中获得一个有效的 monthCode
  • 如果 year/monthCode 组合无效,则会选择一个不同的年份以保持 monthCode 不变。
  • day 在给定的年月中被约束以获得一个有效的月-日。

这与通常的日期约束略有不同,后者更倾向于年份而不是月份代码。

js
// Month always out of range
const md1 = Temporal.PlainMonthDay.from({ month: 13, day: 1 });
console.log(md1.toString()); // 12-01

// Month out of range for the specific year: 5732 is not a Hebrew leap year,
// so month is clamped to 12 to resolve to a valid monthCode
const md2 = Temporal.PlainMonthDay.from({
  year: 5732,
  month: 13,
  day: 1,
  calendar: "hebrew",
});
console.log(md2.toLocaleString("en-US", { calendar: "hebrew" })); // 1 Elul
const underlyingDate = Temporal.PlainDate.from(md2.toString());
console.log(underlyingDate.year, underlyingDate.month); // 5732 12

// Month code exists but not for the specific year: 5731 is not a Hebrew leap year,
// so a different year is chosen to keep the monthCode as M05L
const md3 = Temporal.PlainMonthDay.from({
  year: 5731,
  monthCode: "M05L",
  day: 1,
  calendar: "hebrew",
});
console.log(md3.toLocaleString("en-US", { calendar: "hebrew" })); // 1 Adar I
const underlyingDate2 = Temporal.PlainDate.from(md3.toString());
console.log(underlyingDate2.year, underlyingDate2.monthCode); // 5730 M05L

// Day always out of range
const md4 = Temporal.PlainMonthDay.from({ month: 2, day: 30 });
console.log(md4.toString()); // 02-29

// Day out of range for the specific year-month
const md5 = Temporal.PlainMonthDay.from({ year: 2021, month: 2, day: 29 });
console.log(md5.toString()); // 02-28

你可以将此行为更改为抛出错误

js
Temporal.PlainMonthDay.from(
  { year: 2021, month: 13, day: 1 },
  { overflow: "reject" },
);
// RangeError: date value "month" not in 1..12: 13

规范

规范
Temporal
# sec-temporal.plainmonthday.from

浏览器兼容性

另见