问题描述
在 Angular 应用程序中,我有一个表单,我希望用户能够在任何时区创建日期.用户输入:
In an Angular app, I have a form and I want the user to be able to create a Date in any timezone.The user inputs:
- 日期:
20/09/2021
- 小时:
10:30
- 时区(选择):
欧洲/马德里
我所做的是将时区与其偏移量(Europe/Madrid
-> +0200
)之间的关系保存在本地文件中,然后使用字符串,像这样:new Date("2021-09-20T10:30:00+0200")
.
What I did was saving in a local file the relationship between timezone and its offset (Europe/Madrid
-> +0200
) and then create the Date using a string, like this: new Date("2021-09-20T10:30:00+0200")
.
我的问题是计算夏令时,现在我使用静态时区,但这不现实,因为有些国家/地区每年更改两次时区.我需要一个自动解决方案.
My problem is calculating the summer hours, right now I use static timezones but that is not realistic because some countries change its timezones twice a year. I need an automatic solution.
我一直在阅读关于 moment 和 moment-timezone 但两者都是遗留项目,不鼓励使用它,所以我正在寻找一些东西不同的.谢谢.
I've been reading about moment and moment-timezone but both are legacy projects and its use is discouraged, so I am looking for something different. Thank you.
推荐答案
我终于找到了解决方案.
Finally I've found a solution.
我使用 IANA 代码(例如 Asia/Kabul
)代替静态时区偏移,以便我可以实时计算其值(GMT+4:30
-> +0430).
Instead of static timezone offsets I used the IANA code (e.g. Asia/Kabul
) so I can calculate its value live (GMT+4:30
-> +0430
).
我用过国际,用于格式化日期的本机浏览器类.示例:
I usedIntl, a native browser class to format dates. Example:
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");
有了这个我可以创建日期,但日期构造函数将使用本地时区偏移量并计算差异,因此所选时区中的最终时间将不是指定的时间.
With this I could create the Date, but Date constructor will use the local timezone offset and calculate the difference, so the final time in the selected timezone will not be the specified one.
从 Intl 返回的日期字符串("Thursday, 07/15/2021, 17:19:51 PM GMT+9"
)我得到了最后一部分(GMT+9
) 像这样:
From Intl returned date string ("Thursday, 07/15/2021, 17:19:51 PM GMT+9"
) I get the last part (GMT+9
) like this:
const dateSplit = dateStr.split(" ");
const timezoneAbbr = dateSplit[dateSplit.length - ONE];
3 - 将非标准时区缩写映射到其偏移量
现在,由于某些国家/地区没有标准的时区缩写(例如 AST),我们在创建 Date
对象之前,需要将 时区缩写 映射到 UTC(因为 Date
构造函数为某些时区缩写返回错误).我使用这样的枚举创建了这种关系:
3 - Map non standard timezone abbreviations to its offset
Now, because some countries have not-standard timezone abbreviations (like AST), we need to map time zone abbreviations to UTC before creating the Date
object (because Date
constructor returns error for some time zone abbreviations). I created this relationship using an enum like this:
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
构造函数.
4 - Create Date
Finally create date string with format yyyy/MM/dd hh:mm ZZ
(e.g.: 2021/05/10 10:30 UTC-1
) and call Date
constructor with it.
对时区缩写没有达成共识和可能会有所不同(他们使用 CLDR 格式).还有一些令人困惑的数据,如重复的缩写:
There's no consensus on timezone abbreviations and may vary (they use CLDR format). Also there is confusing data like duplicated abbreviations:
缩写 | 姓名 | UTC 偏移量 |
---|---|---|
AST | 阿拉伯标准时间 | UTC+03 |
AST | 大西洋标准时间 | UTC−04 |
SST | 萨摩亚标准时间 | UTC−11 |
SST | 新加坡标准时间 | UTC+08 |
这篇关于Angular 中的日期时区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!