Angular 中的日期时区
Dates timezones in Angular
在 Angular 应用程序中,我有一个表单,我希望用户能够在任何时区创建日期。
用户输入:
- 日期:
20/09/2021
- 小时:
10:30
- 时区 (select):
Europe/Madrid
我所做的是在本地文件中保存时区与其偏移量之间的关系 (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
在 Angular 应用程序中,我有一个表单,我希望用户能够在任何时区创建日期。 用户输入:
- 日期:
20/09/2021
- 小时:
10:30
- 时区 (select):
Europe/Madrid
我所做的是在本地文件中保存时区与其偏移量之间的关系 (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
构造函数。
警告
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 |