如何使用“时间”用于在不同日历日期之间转换的 API

发布于 2025-01-09 23:02:52 字数 3097 浏览 2 评论 0 原文

使用 Temporal.Calendar https://github.com/tc39/proposal-temporal" rel="nofollow noreferrer">Temporal 全局对象,以下短函数在日历日期之间进行转换(在中识别的 18 个日历) JavaScript)。

目前,Temporal.Calendar 对于其他日历返回的输出日期的格式为(示例):'2022-02-25[u-ca=persian]'

如何避免使用< code>toString().split("[")[0]) 获取不带后缀 [u-ca=CalendarName] 的日历日期Intl.DateTimeFormat() 无法识别后缀?

<script type='module'>
// ====== load Temporary polyfill (not needed after full Temporal implementation) ========
import * as TemporalModule from 'https://cdn.jsdelivr.net/npm/@js-temporal/[email protected]/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> 

Using the Temporal.Calendar of the upcoming proposal of the Temporal global Object, the following short function converts between calendar dates (the 18 Calendars recognized in Javascript).

Currently, the output date returned by Temporal.Calendar for other Calendars is in the format (example): '2022-02-25[u-ca=persian]'

How to avoid usingtoString().split("[")[0]) to get the calendar date without the suffix [u-ca=CalendarName] as the Intl.DateTimeFormat() does not recognize the suffix?

<script type='module'>
// ====== load Temporary polyfill (not needed after full Temporal implementation) ========
import * as TemporalModule from 'https://cdn.jsdelivr.net/npm/@js-temporal/[email protected]/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> 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

¢好甜 2025-01-16 23:02:52

您可以将 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 });
}

You can pass the Temporal.PlainDateTime object directly to Intl.DateTimeFormat, or indirectly by using Temporal.Calendar.prototype.toLocaleString(). This should save you from having to split the string to remove the brackets.

(A good rule of thumb is that if you find yourself doing string manipulation with the output of toString() from any Temporal object, or using new Date() for that matter, it's probably a sign that there's a Temporal method you should be using instead.)

One caveat is that you have to make sure that the calendar of the locale matches the calendar of the date you are formatting. You can't use toLocaleString() or Intl.DateTimeFormat to do calendar conversion (unless it is from the ISO 8601 calendar).
So you should use the withCalendar() method to convert the date to the calendar you want to output it in, as well as making sure the calendar in the Intl options matches it.

Here's my attempt at such a function:

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 });
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文