簡體   English   中英

在Javascript中從時區獲取UTC偏移量

[英]Get utc offset from timezone in Javascript

我需要一個給定時區的 Javascript 函數,返回當前的 utc 偏移量。

例如,theFuncIneed('US/Eastern') -> 240

有什么想法嗎?

謝謝

一般來說,這是不可能的。

  • US/Eastern時區的標識符。 (它實際上是America/New_York的別名,它是真正的標識符。)

  • 240是時區偏移量 它更常寫為-04:00 (反轉符號,除以 60)。

  • 美國東部時區由偏移量為-05:00東部標准時間和偏移量為-04:00東部夏令時組成。

所以說US/Eastern = 240 一點也不准確。請閱讀時區標簽 wiki ,尤其是標題為“時區!= 偏移”的部分。

現在您確實要求了當前偏移量,這可能的。 如果您提供日期+時間參考,則可以解決此問題。

  • 對於正在執行 javascript 代碼的計算機的本地時區,這是通過Date對象的任何實例的.getTimeZoneOffset()內置的。

  • 但是,如果您希望在特定時區使用它,則需要使用我在此處列出的庫之一

以下函數可用於返回給定時區的 UTC 偏移量:

const getTimezoneOffset = (timeZone, date = new Date()) => {
  const tz = date.toLocaleString("en", {timeZone, timeStyle: "long"}).split(" ").slice(-1)[0];
  const dateString = date.toString();
  const offset = Date.parse(`${dateString} UTC`) - Date.parse(`${dateString} ${tz}`);
  
  // return UTC offset in millis
  return offset;
}

它可以像這樣使用:

const offset = getTimezoneOffset("Europe/London");
console.log(offset);
// expected output => 3600000

你可以使用moment.js來做到這一點

moment.tz('時區名稱').utcOffset()

雖然這涉及使用 moment-timezone.js

現在使用Intl API已經成為可能:

Intl的實現基於icu4c 如果您挖掘源代碼,您會發現時區名稱因地區而異,例如:

 for (const locale of ["ja", "en", "fr"]) { const timeZoneName = Intl.DateTimeFormat(locale, { timeZoneName: "short", timeZone: "Asia/Tokyo", }) .formatToParts() .find((i) => i.type === "timeZoneName").value; console.log(timeZoneName); }

幸運的是,有一個語言環境Interlingua (語言標簽是ia ),它使用相同的模式(例如GMT+11:00 )作為時區名稱。

下面的代碼段可以滿足您的需求:

 const getOffset = (timeZone) => { const timeZoneName = Intl.DateTimeFormat("ia", { timeZoneName: "short", timeZone, }) .formatToParts() .find((i) => i.type === "timeZoneName").value; const offset = timeZoneName.slice(3); if (!offset) return 0; const matchData = offset.match(/([+-])(\\d+)(?::(\\d+))?/); if (!matchData) throw `cannot parse timezone name: ${timeZoneName}`; const [, sign, hour, minute] = matchData; let result = parseInt(hour) * 60; if (sign === "+") result *= -1; if (minute) result += parseInt(minute); return result; }; console.log(getOffset("US/Eastern")); // 240 console.log(getOffset("Atlantic/Reykjavik")); // 0 console.log(getOffset("Asia/Tokyo")); // -540

這種方式可能有點棘手,但它在我的生產項目中運行良好。 我希望它也能幫助你:)

更新

非常感謝 Bort 指出錯別字。 我已經更正了片段。

@ranjan_purbey 的答案對我來說是NaN ,@Weihang Jian 的答案在 Chrome 中引發異常(但在 Firefox 中有效)。

因此,基於所有的答案,我想出了以下功能,它基本上是兩個答案的組合,為我成功地工作:

const getTimeZoneOffset(timeZone) {
    const date = new Date().toLocaleString('en', {timeZone, timeZoneName: 'short'}).split(' ');
    const timeZoneName = date[date.length - 1];
    const offset = timeZoneName.slice(3);
    if (!offset) {
      return 0;
    }
    const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
    if (!matchData) {
      throw new Error(`Cannot parse timezone name: ${timeZoneName}`);
    }
    const [, sign, hour, minute] = matchData;
    let result = parseInt(hour, 10) * 60;
    if (sign === '+') {
      result *= -1;
    }
    if (minute) {
      result += parseInt(minute, 10);
    }
    return result;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM