如何将 JS 日期格式化为带有时区后缀的 RFC 9557 格式,以便我可以记录事件发生的确切时间以及事件发生的时区和本地时间?
java.time.ZonedDateTime
互操作或使用即将推出的 JavaScript API Temporal.ZonedDateTime
。
我想要这样的输出:
2024-12-18T08:32:23.95+00:00[Europe/London]
2024-12-18T03:38:58.765-05:00[America/New_York]
2024-12-18T05:43:12.150+09:00[Asia/Tokyo]
这是我编写的一个函数,用于使用时区格式化 JS
Date
对象。在此分享以帮助他人。
function formatRFC9557(date, timeZone, fractionalSecondDigits = 3) {
const formatter = new Intl.DateTimeFormat('en', {
timeZone,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: 'numeric',
fractionalSecondDigits: fractionalSecondDigits === 0 ? undefined : fractionalSecondDigits,
timeZoneName: 'longOffset'
});
// Extract each date/time component
const parts = formatter.formatToParts(date).filter(({ type }) => type !== 'literal');
const obj = Object.fromEntries(parts.map(({ type, value }) => [type, value]));
const { year, month, day, hour, minute, second, fractionalSecond, timeZoneName } = obj;
// Intl.DateTimeFormat returns 'GMT' for UTC, so we need to normalize it to '+00:00'
// For non-zero UTC offsets, it returns 'GMT+XX:XX' or 'GMT-XX:XX'
const offset = timeZoneName === 'GMT' ? '+00:00' : timeZoneName.replace('GMT', '');
const partialSeconds = fractionalSecond ? `.${fractionalSecond}` : '';
const dateAndTime = `${year}-${month}-${day}T${hour}:${minute}:${second}${partialSeconds}`;
return `${dateAndTime}${offset}[${timeZone}]`;
}
示例:
formatRFC9557(new Date(), 'Asia/Tokyo')
// => '2024-12-18T05:52:45.770+09:00[Asia/Tokyo]'
formatRFC9557(new Date(), 'America/Los_Angeles')
// => '2024-12-18T12:54:56.633-08:00[America/Los_Angeles]'
formatRFC9557(new Date(), 'America/Los_Angeles', 0)
// => '2024-12-18T12:59:16-08:00[America/Los_Angeles]'