クライアントブラウザからタイムゾーンを取得する信頼できる方法はありますか?次のリンクを見ましたが、より堅牢なソリューションが必要です。
クライアントブラウザからタイムゾーンを取得する信頼できる方法はありますか?次のリンクを見ましたが、より堅牢なソリューションが必要です。
回答:
このリポジトリを見てpageloomそれは便利です
jstz.min.jsをダウンロードして、htmlページに関数を追加します
<script language="javascript">
function getTimezoneName() {
timezone = jstz.determine()
return timezone.name();
}
</script>
ディスプレイタグからこの関数を呼び出します
Intl.DateTimeFormat().resolvedOptions().timeZone
、Wallaceの提案どおり(IE11 は使用できません)を使用できます。
5年後、組み込みの方法があります。最近のブラウザでは、次を使用します。
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tz);
これはIANAタイムゾーン文字列を返しますが、オフセットは返しません。MDNリファレンスで詳細をご覧ください。
互換性テーブル -2019年3月現在、世界的に使用されているブラウザの90%で機能します。Internet Explorerでは機能しません。
Intl.DateTimeFormat().resolvedOptions().timeZone
->undefined
Intl.DateTimeFormat().resolvedOptions().timeZone
Firefoxの52から始まる期待値を返します。kangax.github.io/compat-table/esintl/...
多くの場合、人々が「タイムゾーン」を探しているときは、「UTCオフセット」で十分です。たとえば、サーバーがUTC + 5にあり、クライアントがUTC-8で実行されていることを知りたいとします。
昔ながらのjavascriptでは(new Date()).getTimezoneOffset()/60
、UTCからの現在のオフセット時間を返します。
(MDN docsからの)getTimezoneOffset()
戻り値の符号にある「問題」に注意する価値があります。
タイムゾーンオフセットは、UTCと現地時間の差(分単位)です。これは、ローカルタイムゾーンがUTCより遅れている場合はオフセットが正であり、進んでいる場合は負であることを意味します。たとえば、タイムゾーンUTC + 10:00(オーストラリア東部標準時、ウラジオストク時間、チャモロ標準時)の場合、-600が返されます。
ただし、日時に関連するJavaScriptコードにはday.jsを使用することをお勧めします。この場合、次のコマンドを実行すると、ISO 8601形式のUTCオフセットを取得できます。
> dayjs().format("Z")
"-08:00"
おそらく、クライアントがこの情報を簡単に改ざんできることについて言及しておきます。
(注:この回答はもともとhttps://momentjs.com/を推奨していましたが、dayjsはよりモダンで小さな代替手段です。)
現時点では、mbayloonの回答で提案されているように、おそらく最善の策はjstzです。
完全を期すために、その方法に標準があることを言及する必要があります:Intl。これはすでにChromeで確認できます。
> Intl.DateTimeFormat().resolvedOptions().timeZone
"America/Los_Angeles"
(これは実際には標準に準拠していません。これがライブラリに固執するもう1つの理由です)
Intl
に戻ることになっています。Chromeは、代わりにシステムのタイムゾーンを返すことにより、標準から逸脱しています。それがヨハネスの答えが悪用する理由ですが、彼が「実際には標準に従っていない」と言った理由もです。undefined
timeZone
DateTimeFormat
現在のユーザーのタイムゾーンの略称を提供します。
ここにコードサンプルがあります
var tz = jstz.determine();
console.log(tz.name());
console.log(moment.tz.zone(tz.name()).abbr(new Date().getTime()));
May 22 2015 03:45 PM CDT
私が使用 console.log(moment(now).format('MMM DD YYYY hh:mm A') + ' ' + moment.tz.zone(tz.name()).abbr(now.getTime()));
私は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'
サフィックスはD
DSTおよびS
標準(非DST)用です。ClientTZ.hasDST
(真または偽に)。ClientTZ.UTCoffset
いくつかのタイムゾーンは、分数の時間ごとのオフセット(例えば、0415)を持っているので、代わりに時間の数分で提供されています。
背後にClientTZ.UTCoffsetT
ある意図は、それをドロップダウン<select>
リストなどのタイムゾーンのテーブル(ここでは提供されていません)へのキーとして使用することです。
7-1
6月ではなく7月に使用できます。6月を含まない地域のDSTスキームがあるのではないかと思うので、それが本当に違いがあるかどうかはわかりません。
いいえ。信頼できる方法は1つではなく、決してありません。クライアントを信頼できると本当に思いましたか?