在Node中,给定特定时间点,如何将时区(例如Europe/Stockholm
(转换为UTC偏移量(例如+1
或+2
(?Temporal
似乎会在未来解决这个问题,但在那之前?这可能是天生的吗?还是我需要tzdb
之类的东西?
我建议不要直接使用tzdb
,而是使用一个能很好地处理时区的日期库。特别是,我发现Luxon在这方面做得很好,请参阅他们关于时区处理的文档。要获得偏移量,只需创建一个具有所需时区的DateTime
,然后获得其.offset
:
const dateInZone = DateTime.fromISO("2022-10-23T21:10:56Z", {
zone: "Europe/Stockholm"
});
console.log(dateInZone.offset)
或者,创建一个Zone
实例,并在特定的时间戳获取其.offset()
:
const zone = new IANAZone("Europe/Stockholm");
console.log(zone.offset(Date.parse("2022-10-23T21:10:56Z")));
我不知道你的具体用例,但一般来说,这应该是工作流程:
-
在将日期发送到服务器之前,请以ISO格式(独立于时区(发送日期。您可以使用本机
new Date().toISOString()
方法来完成此操作。 -
将ISO日期保存在数据库中。
-
一旦它返回到客户端,您就可以解析ISO日期,该日期将自动解析到用户的本地时区。
是的,还没有本地可用
这个列表是众所周知的,很容易放在一个标签图中
https://github.com/vvo/tzdb/blob/main/raw-time-zones.json
或者使用提到的库
我们可以使用Date.toLocaleString()
使用ia
语言获得以小时和分钟为单位的偏移量,这将导致UTC偏移量的格式为GMT+HMM,例如GMT+5:30
。
我们可以使用正则表达式来获得HHMM偏移量,例如+5:30,-8:00,这可以很容易地转换为UTC偏移量(分钟(。
我认为一般来说,最好使用luxon这样的库来获得UTC偏移量(如另一个答案所示(,但可以在VanillaJS中完成。
function getUTCOffsetHHMM(date, timeZone) {
const fmt = date.toLocaleString('ia', { timeZoneName: 'longOffset', timeZone });
return fmt.replace(/^.*? GMT/, '');
}
function getUTCOffsetMinutes(date, timeZone) {
const hhmm = getUTCOffsetHHMM(date, timeZone);
return parseHHMM(hhmm);
}
function parseHHMM(hhmm) {
const [h, m] = hhmm.split(':').map(Number);
return h * 60 + (m || 0) * (h < 0 ? -1: +1);
}
const now = new Date();
const timeZones = ['America/Los_Angeles', 'America/St_Johns', 'Europe/Berlin', 'Asia/Kolkata', 'Asia/Tokyo'];
console.log('Timezone'.padEnd(22), 'UTC Offset (hh:mm)', 'UTC Offset (minutes)');
for(let timeZone of timeZones) {
console.log(timeZone.padEnd(22), getUTCOffsetHHMM(now, timeZone).padEnd(18), getUTCOffsetMinutes(now, timeZone));
}
.as-console-wrapper { max-height: 100% !important; }