如何格式化带有时区的 RFC 9557 格式的 JavaScript 日期?

问题描述 投票:0回答:1

如何将 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]
javascript timezone ecmascript-temporal rfc-9557
1个回答
0
投票

这是我编写的一个函数,用于使用时区格式化 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]'
© www.soinside.com 2019 - 2024. All rights reserved.