問題描述
例如,東部和中部的區別是 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.
- 目前倫敦和紐約之間的時差為 4 小時(寫于 2015 年 3 月 25 日).
- 但幾周前相差 5 小時,而幾周后將是 5 小時.
- 每個時區在不同時間點切換夏令時偏移量.
- It's currently 4 hours difference between London and New York (writing this on Mar 25, 2015).
- But it was 5 hours difference a few weeks ago, and it will be 5 a few weeks from now.
- Each time zone switches offsets for daylight saving time at a different point 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.
- 倫敦和巴黎之間總是一小時,因為它們在同一時間切換.
- 亞利桑那州和夏威夷之間總是 3 小時,因為兩者都沒有夏令時.
- There is always one hour between London and Paris, because they switch at the same moment in time.
- There are always 3 hours between Arizona and Hawaii, because neither have DST.
請注意,在美國,使用 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.
- 所以在芝加哥和紐約之間,通常相隔 1 小時
- 但每年有兩個短暫的時期,它們要么相隔 2 小時,要么具有相同的確切時間.
- So between Chicago and New York, there is usually 1 hour apart
- But for two brief periods each year they are either 2 hours apart, or have the same exact 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 時區支持的環境中完成.這是當今大多數瀏覽器.
Updated answer:
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 個時區的差異?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!