Angular 中的日期时区

Dates timezones in Angular

在 Angular 应用程序中,我有一个表单,我希望用户能够在任何时区创建日期。 用户输入:

我所做的是在本地文件中保存时区与其偏移量之间的关系 (Europe/Madrid -> +0200),然后使用字符串创建日期,如下所示:new Date("2021-09-20T10:30:00+0200").

我的问题是计算夏令时,现在我使用静态时区,但这不现实,因为有些国家/地区每年更改两次时区。我需要一个自动解决方案。

我一直在阅读有关 moment and moment-timezone 的内容,但两者都是 遗留 项目并且不鼓励使用它,所以我正在寻找不同的东西。谢谢。

我终于找到了解决办法。

我使用了 IANA 代码(例如 Asia/Kabul)而不是静态时区偏移量,因此我可以实时计算它的值(GMT+4:30 -> +0430)。

1 - 从 IANA 时区标识符

获取时区偏移量

我用过 Intl,用于格式化日期的本机浏览器 class。示例:

new Intl.DateTimeFormat("en", {
  timeZone: "Pacific/Palau",
  day: "2-digit",
  month: "2-digit",
  year: "numeric",
  weekday: "long",
  hour: "2-digit",
  minute: "2-digit",
  hour12: false,
  second: "2-digit",
  timeZoneName: "short",
}).format(new Date());

("Thursday, 07/15/2021, 17:19:51 PM GMT+9");

有了这个我可以创建日期,但是日期构造函数将使用本地时区偏移量并计算差异,因此所选时区的最终时间将不是指定时间。

2 - 从字符串中获取时区

从 Intl 返回的日期字符串 ("Thursday, 07/15/2021, 17:19:51 PM GMT+9") 我得到最后一部分 (GMT+9),如下所示:

const dateSplit = dateStr.split(" ");
const timezoneAbbr = dateSplit[dateSplit.length - ONE];

3 - 将非标准时区缩写映射到其偏移量

现在,因为某些国家/地区有不标准的时区缩写(例如 AST), we need to map time zone abbreviations 在创建 Date 对象之前为 UTC(因为 Date 构造函数 returns 一些错误时区缩写)。我使用这样的枚举创建了这种关系:

export enum TimezoneAbbreviation {
  ACDT = '+1030',
  ACST = '+0930',
  ACT = '-0500',
  ADT = '-0300',

4 - 创建日期

最后创建格式为 yyyy/MM/dd hh:mm ZZ 的日期字符串(例如:2021/05/10 10:30 UTC-1)并用它调用 Date 构造函数。

警告

and may vary (they use CLDR format)。还有一些令人困惑的数据,比如重复的缩写:

Abbr Name UTC offset
AST Arabia Standard Time UTC+03
AST Atlantic Standard Time UTC−04
SST Samoa Standard Time UTC−11
SST Singapore Standard Time UTC+08