例如,东部和中部的区别是 1.我下面的解决方案感觉很hacky.有没有更简单/更好的方法?
For example, the difference in Eastern and Central is 1. My solution below feels hacky. Is there a easier / better way?
var diff = (parseInt(moment().tz("America/New_York").format("ZZ")) - parseInt(moment().tz("America/Chicago").format("ZZ"))) / 100;
我的示例是使用 Momentjs 库.
My example is using the Momentjs library.
不可能计算两个任意时区之间的差异.您只能计算特定时刻的差异.
It's impossible to calculate the difference between two arbitrary time zones. You can only calculate a difference for a specific moment in time.
这在两个时区之间的一般情况下是正确的.然而一些时区要么完全同时切换,要么根本不切换.
This is true in the general case between two time zones. However some time zones either switch exactly at the same time, or don't switch at all.
请注意,在美国,使用 DST 的每个时区实际上会在不同的时间切换.它们都在其本地时间的凌晨 2:00 切换,但不是在同一时间通用.
Keep in mind that in the United States, each time zone that uses DST actually switches at a different moment in time. They all switch at 2:00 AM in their local time, but not at the same universal moment in time.
另请参阅时区标签wiki中的时区!=偏移".
See also "Time Zone != Offset" in the timezone tag wiki.
现在关于时刻时区,您在评论中说:
Now with regard to moment-timezone, you said in comments:
网络服务器位于东部时区;我们在中环.我需要用户时区和服务器的差异.
Web 服务器的时区无关紧要.您应该能够在世界任何地方进行托管,而不会影响您的应用程序.如果你不能,那么你做错了.
The time zone of the web server is irrelevant. You should be able to host from anywhere in the world without affecting your application. If you can't, then you're doing it wrong.
您可以获取您的时区(美国中部时间)与用户的时区之间的当前时差.如果代码在浏览器中运行,您甚至不需要知道用户的确切时区:
You can get the current time difference between your time zone (US Central time) and the user's. You don't even need to know the user's exact time zone for this, if the code is running in the browser:
var now = moment();
var localOffset = now.utcOffset();
now.tz("America/Chicago"); // your time zone, not necessarily the server's
var centralOffset = now.utcOffset();
var diffInMinutes = localOffset - centralOffset;
如果代码在服务器上运行(在 node.js 应用程序中),那么您将需要知道用户的时区.只需像这样更改第一行:
If instead the code was running on the server (in a node.js app), then you would need to know the user's time zone. Just change the first line like this:
var now = moment.tz("America/New_York"); // their time zone
这可以在支持 ECMAScript 国际化 API 并已完全实现 IANA 时区支持的环境中完成.这是当今大多数浏览器.
This can be done without Moment, in environments that support the ECMAScript Internationalization API and have fully implemented IANA time zone support. This is most browsers these days.
function getTimeZoneOffset(date, timeZone) {
// Abuse the Intl API to get a local ISO 8601 string for a given time zone.
let iso = date.toLocaleString('en-CA', { timeZone, hour12: false }).replace(', ', 'T');
// Include the milliseconds from the original timestamp
iso += '.' + date.getMilliseconds().toString().padStart(3, '0');
// Lie to the Date object constructor that it's a UTC time.
const lie = new Date(iso + 'Z');
// Return the difference in timestamps, as minutes
// Positive values are West of GMT, opposite of ISO 8601
// this matches the output of `Date.getTimeZoneOffset`
return -(lie - date) / 60 / 1000;
}
示例用法:
getTimeZoneOffset(new Date(2020, 3, 13), 'America/New_York') //=> 240
getTimeZoneOffset(new Date(2020, 3, 13), 'Asia/Shanghai') //=> -480
如果你想要它们之间的差异,你可以简单地减去结果.
If you want the difference between them, you can simply subtract the results.
上述函数在 full-icu
国际化 支持已安装(这是 Node 13 和更新版本的默认设置).如果您有带有 system-icu
或 small-icu
的旧版本,则可以使用此修改后的功能.它也可以在浏览器和 full-icu
环境中工作,但更大一些.(我在 Linux 上的 Node 8.17.0 和 Windows 上的 Node 12.13.1 上对此进行了测试.)
The above function works in Node.js where the full-icu
internationalization support is installed (which is the default for Node 13 and newer). If you have an older version with either system-icu
or small-icu
, you can use this modified function. It will work in browsers and full-icu
environments also, but is a bit larger. (I have tested this on Node 8.17.0 on Linux, and Node 12.13.1 on Windows.)
function getTimeZoneOffset(date, timeZone) {
// Abuse the Intl API to get a local ISO 8601 string for a given time zone.
const options = {timeZone, calendar: 'iso8601', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false};
const dateTimeFormat = new Intl.DateTimeFormat(undefined, options);
const parts = dateTimeFormat.formatToParts(date);
const map = new Map(parts.map(x => [x.type, x.value]));
const year = map.get('year');
const month = map.get('month');
const day = map.get('day');
const hour = map.get('hour');
const minute = map.get('minute');
const second = map.get('second');
const ms = date.getMilliseconds().toString().padStart(3, '0');
const iso = `${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}`;
// Lie to the Date object constructor that it's a UTC time.
const lie = new Date(iso + 'Z');
// Return the difference in timestamps, as minutes
// Positive values are West of GMT, opposite of ISO 8601
// this matches the output of `Date.getTimeZoneOffset`
return -(lie - date) / 60 / 1000;
}
请注意,无论哪种方式,我们必须通过 Intl
才能正确应用时区.
Note that either way, we must go through Intl
to have the time zone applied properly.
这篇关于如何在 JavaScript 中计算 2 个时区的差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!