如何使用 'Temporal' API 在不同的日历日期之间进行转换
How to use 'Temporal' API to Convert between Different Calendar Dates
使用 Temporal.Calendar of the upcoming proposal of the Temporal 全局对象,以下短函数在日历日期(Javascript 中识别的 18 个日历)之间进行转换。
目前,Temporal.Calendar 为其他日历返回的输出日期格式为(示例):'2022-02-25[u-ca=persian]'
如何避免使用toString().split("[")[0])
获取不带后缀[u-ca=CalendarName]
的日历日期,因为Intl.DateTimeFormat()
无法识别后缀?
<script type='module'>
// ====== load Temporray polyfill (not needed after full Temporal implementation) ========
import * as TemporalModule from 'https://cdn.jsdelivr.net/npm/@js-temporal/polyfill@0.3.0/dist/index.umd.js'
//=====================================================================
// Y,M,D are the date to convert from
// options as in Intl.DateTimeFormat() with additional 'from' and 'locale'
// 'from': calendar name to convert from
// 'locale' the locale to use (default 'en')
// 'calendar': calendar to convert to
// All other options as in Intl.DateTimeFormat()
//---------------------------------------
function dateToCalendars(Y, M, D, op={}) {
return new Intl.DateTimeFormat(op.locale??="en",op).format(new Date(temporal.Temporal.PlainDateTime.from({year:Y,month:M,day:D,calendar:op.from??= "gregory"}).toString().split("[")[0]));
}
//---------------------------------------
//===============================
// Example Test Cases
//===============================
console.log(dateToCalendars(2022,2,25)); // default Gregory
// full format Gregory
console.log(dateToCalendars(2022,2,25, {dateStyle: "full"}));
// from Persian to Gregory in full format
console.log(dateToCalendars(1400,12,6,{from: 'persian', dateStyle: "full"}));
// from Persian to Gregory in full format in 'fa' locale
console.log(dateToCalendars(1400,12,6,{from: 'persian', dateStyle: "full", locale: "fa"}));
// from Persian to Islamic in full format in 'fa' locale
console.log(dateToCalendars(1400,12,6,{from: 'persian', calendar: 'islamic', dateStyle:"full", locale: "fa"}));
// from Islamic to Gregory full format (default 'en' locale)
console.log(dateToCalendars(1443,7,24,{from:"islamic", dateStyle:"full"}));
// from Hebrew to Islamic in full format
console.log(dateToCalendars(5782,6,24,{from: 'hebrew', calendar:"islamic", dateStyle:"full"}));
// from Hebrew to Islamic in full format in 'ar' locale
console.log(dateToCalendars(5782,6,24,{from: 'hebrew', calendar:"islamic", dateStyle:"full", locale: 'ar'}));
// from Hebrew to Persian in full format
console.log(dateToCalendars(5782,6,24,{from: 'hebrew', calendar:"persian", dateStyle:"full"}));
// from Hebrew to Gregory in full format in 'he' locale
console.log(dateToCalendars(5782,6,24,{from: 'hebrew', dateStyle:"full", locale: 'he'}));
</script>
您可以将 Temporal.PlainDateTime 对象直接传递给 Intl.DateTimeFormat,或使用 Temporal.Calendar.prototype.toLocaleString() 间接传递。这应该使您不必拆分字符串以删除括号。
(一个好的经验法则是,如果您发现自己使用任何 Temporal 对象的 toString() 的输出进行字符串操作,或者就此使用 new Date()
,这可能表明存在您应该改用时间方法。)
需要注意的是,您必须确保区域设置的日历与您正在设置格式的日期的日历相匹配。您不能使用 toLocaleString() 或 Intl.DateTimeFormat 进行日历转换(除非它来自 ISO 8601 日历)。
因此,您应该使用 withCalendar() 方法将日期转换为您想要输出的日历,并确保 Intl 选项中的日历与其匹配。
这是我对这样一个功能的尝试:
function dateToCalendars(year, month, day, op = {}) {
const fromCalendar = op.from ?? 'gregory';
const toCalendar = op.calendar ?? fromCalendar;
const date = Temporal.PlainDate.from({ year, month, day, calendar: fromCalendar })
.withCalendar(toCalendar);
return date.toLocaleString(op.locale ?? 'en', { ...op, calendar: toCalendar });
}
使用 Temporal.Calendar of the upcoming proposal of the Temporal 全局对象,以下短函数在日历日期(Javascript 中识别的 18 个日历)之间进行转换。
目前,Temporal.Calendar 为其他日历返回的输出日期格式为(示例):'2022-02-25[u-ca=persian]'
如何避免使用toString().split("[")[0])
获取不带后缀[u-ca=CalendarName]
的日历日期,因为Intl.DateTimeFormat()
无法识别后缀?
<script type='module'>
// ====== load Temporray polyfill (not needed after full Temporal implementation) ========
import * as TemporalModule from 'https://cdn.jsdelivr.net/npm/@js-temporal/polyfill@0.3.0/dist/index.umd.js'
//=====================================================================
// Y,M,D are the date to convert from
// options as in Intl.DateTimeFormat() with additional 'from' and 'locale'
// 'from': calendar name to convert from
// 'locale' the locale to use (default 'en')
// 'calendar': calendar to convert to
// All other options as in Intl.DateTimeFormat()
//---------------------------------------
function dateToCalendars(Y, M, D, op={}) {
return new Intl.DateTimeFormat(op.locale??="en",op).format(new Date(temporal.Temporal.PlainDateTime.from({year:Y,month:M,day:D,calendar:op.from??= "gregory"}).toString().split("[")[0]));
}
//---------------------------------------
//===============================
// Example Test Cases
//===============================
console.log(dateToCalendars(2022,2,25)); // default Gregory
// full format Gregory
console.log(dateToCalendars(2022,2,25, {dateStyle: "full"}));
// from Persian to Gregory in full format
console.log(dateToCalendars(1400,12,6,{from: 'persian', dateStyle: "full"}));
// from Persian to Gregory in full format in 'fa' locale
console.log(dateToCalendars(1400,12,6,{from: 'persian', dateStyle: "full", locale: "fa"}));
// from Persian to Islamic in full format in 'fa' locale
console.log(dateToCalendars(1400,12,6,{from: 'persian', calendar: 'islamic', dateStyle:"full", locale: "fa"}));
// from Islamic to Gregory full format (default 'en' locale)
console.log(dateToCalendars(1443,7,24,{from:"islamic", dateStyle:"full"}));
// from Hebrew to Islamic in full format
console.log(dateToCalendars(5782,6,24,{from: 'hebrew', calendar:"islamic", dateStyle:"full"}));
// from Hebrew to Islamic in full format in 'ar' locale
console.log(dateToCalendars(5782,6,24,{from: 'hebrew', calendar:"islamic", dateStyle:"full", locale: 'ar'}));
// from Hebrew to Persian in full format
console.log(dateToCalendars(5782,6,24,{from: 'hebrew', calendar:"persian", dateStyle:"full"}));
// from Hebrew to Gregory in full format in 'he' locale
console.log(dateToCalendars(5782,6,24,{from: 'hebrew', dateStyle:"full", locale: 'he'}));
</script>
您可以将 Temporal.PlainDateTime 对象直接传递给 Intl.DateTimeFormat,或使用 Temporal.Calendar.prototype.toLocaleString() 间接传递。这应该使您不必拆分字符串以删除括号。
(一个好的经验法则是,如果您发现自己使用任何 Temporal 对象的 toString() 的输出进行字符串操作,或者就此使用 new Date()
,这可能表明存在您应该改用时间方法。)
需要注意的是,您必须确保区域设置的日历与您正在设置格式的日期的日历相匹配。您不能使用 toLocaleString() 或 Intl.DateTimeFormat 进行日历转换(除非它来自 ISO 8601 日历)。 因此,您应该使用 withCalendar() 方法将日期转换为您想要输出的日历,并确保 Intl 选项中的日历与其匹配。
这是我对这样一个功能的尝试:
function dateToCalendars(year, month, day, op = {}) {
const fromCalendar = op.from ?? 'gregory';
const toCalendar = op.calendar ?? fromCalendar;
const date = Temporal.PlainDate.from({ year, month, day, calendar: fromCalendar })
.withCalendar(toCalendar);
return date.toLocaleString(op.locale ?? 'en', { ...op, calendar: toCalendar });
}