web-dev-qa-db-ja.com

ブラウザからクライアントのタイムゾーンを取得

クライアントブラウザからタイムゾーンを取得する信頼できる方法はありますか?次のリンクを見ましたが、より堅牢なソリューションが必要です。

JavaScriptでタイムゾーンを自動検出

JavaScriptでのタイムゾーン検出

114
confucius

このリポジトリを見てください pageloom 役に立つ

jstz.min.jsをダウンロードし、HTMLページに関数を追加します

<script language="javascript">
    function getTimezoneName() {
        timezone = jstz.determine()
        return timezone.name();
    }
</script>

表示タグからこの関数を呼び出します

78

半年後、そのための組み込みの方法があります!最新のブラウザでは、次を使用します。

const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tz);

これは、IANAタイムゾーン文字列を返しますが、 オフセット は返しません。詳細については、 MDNリファレンス をご覧ください。

互換性テーブル -2019年3月現在、世界中で使用されているブラウザの90%で機能します。 Internet Explorerでは機能しません

116
Wallace

多くの場合、人々が「タイムゾーン」を探しているとき、十分なのは「UTCオフセット」だけです。 例えば、彼らのサーバーはUTC + 5にあり、彼らは彼らのクライアントがUTC-8で実行されていることを知りたいです。


単純な古いjavascriptでは、(new Date()).getTimezoneOffset()/60はUTCからの現在の時間オフセットを返します。

getTimezoneOffset()の戻り値の記号に「落とし穴」があることに注意する価値があります (MDN docs)

タイムゾーンオフセットは、UTCと現地時間の差(分単位)です。これは、ローカルタイムゾーンがUTCより遅れている場合はオフセットが正であり、進んでいる場合は負であることを意味することに注意してください。たとえば、タイムゾーンUTC + 10:00(オーストラリア東部標準時、ウラジオストク時間、チャモロ標準時)の場合、-600が返されます。


ただし、時間と日付に関連するJavascriptコードには day.js を使用することをお勧めします。その場合、次を実行してISO 8601形式のUTCオフセットを取得できます。

> dayjs().format("Z")
"-08:00"

おそらく、クライアントがこの情報を簡単に改ざんできることに言及する必要があります。

(注:元々この回答は https://momentjs.com/ を推奨していましたが、dayjsはより現代的で小さな代替手段です。)

64
Chris W.

今のところ、 mbayloon's answer で提案されているように、おそらく最善の策はjstzです。

完全を期すために、その方法には標準があります: Intl 。これは既にChromeで見ることができます:

> Intl.DateTimeFormat().resolved.timeZone
"America/Los_Angeles"

(これは実際には標準に従っていないため、ライブラリに固執するもう1つの理由です)

41
Johannes Hoff

jsfiddle

現在のユーザーのタイムゾーンの略語を提供します。

ここにコードサンプルがあります

var tz = jstz.determine();
console.log(tz.name());
console.log(moment.tz.zone(tz.name()).abbr(new Date().getTime()));
5

Josh Fraserが取ったもの に似たアプローチを使用しました。これは、UTCからのブラウザーの時間オフセットと、DSTを認識するかどうかを決定します(ただし、コードは多少簡略化されています)。

var ClientTZ = {
    UTCoffset:  0,          // Browser time offset from UTC in minutes
    UTCoffsetT: '+0000S',   // Browser time offset from UTC in '±hhmmD' form
    hasDST:     false,      // Browser time observes DST

    // Determine browser's timezone and DST
    getBrowserTZ: function () {
        var self = ClientTZ;

        // Determine UTC time offset
        var now = new Date();
        var date1 = new Date(now.getFullYear(), 1-1, 1, 0, 0, 0, 0);    // Jan
        var diff1 = -date1.getTimezoneOffset();
        self.UTCoffset = diff1;

        // Determine DST use
        var date2 = new Date(now.getFullYear(), 6-1, 1, 0, 0, 0, 0);    // Jun
        var diff2 = -date2.getTimezoneOffset();
        if (diff1 != diff2) {
            self.hasDST = true;
            if (diff1 - diff2 >= 0)
                self.UTCoffset = diff2;     // East of GMT
        }

        // Convert UTC offset to ±hhmmD form
        diff2 = (diff1 < 0 ? -diff1 : diff1) / 60;
        var hr = Math.floor(diff2);
        var min = diff2 - hr;
        diff2 = hr * 100 + min * 60;
        self.UTCoffsetT = (diff1 < 0 ? '-' : '+') + (hr < 10 ? '0' : '') + diff2.toString() + (self.hasDST ? 'D' : 'S');

        return self.UTCoffset;
    }
};

// Onload
ClientTZ.getBrowserTZ();

ロード時に、ClientTZ.getBrowserTZ()関数が実行され、以下が設定されます。

  • ClientTZ.UTCoffsetをブラウザのUTCからのオフセット(分)(たとえば、CSTは-360分、UTCから-6.0時間)。
  • ClientTZ.UTCoffsetT'±hhmmD'形式のオフセット(例:'-0600D')、ここでサフィックスはDSTの場合はD、標準(非DST)の場合はSです。
  • ClientTZ.hasDST(trueまたはfalse)。

ClientTZ.UTCoffsetは、時間単位ではなく分単位で提供されます。これは、一部のタイムゾーンには時間単位の小数オフセット(+0415など)があるためです。

ClientTZ.UTCoffsetTの背後にある目的は、ドロップダウン<select>リストなどのために、タイムゾーンのテーブル(ここでは提供されません)のキーとして使用することです。

2
David R Tribble

moment-timezone を使用してタイムゾーンを推測できます。

> moment.tz.guess()
"America/Asuncion"
2
SummerBreeze