最后我找到了解决方案。
我使用了 IANA 代码(例如)而不是静态时区偏移量,Asia/Kabul
因此我可以实时计算其值(GMT+4:30
-> +0430
)。
我使用
Intl,一个本地浏览器类来格式化日期。例子:
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),我们需要在创建对象之前将时区缩写映射到 UTC Date
(因为Date
构造函数对某些时区缩写返回错误)。我使用这样的枚举创建了这种关系:
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
构造函数。
警告
时区缩写没有共识,可能会有所不同(它们使用CLDR 格式)。还有一些令人困惑的数据,例如重复的缩写:
缩写 |
姓名 |
UTC 偏移量 |
AST |
阿拉伯标准时间 |
UTC+03 |
AST |
大西洋标准时间 |
UTC-04 |
SST |
萨摩亚标准时间 |
UTC-11 |
SST |
新加坡标准时间 |
UTC+08 |