Adakah cara yang dapat diandalkan untuk mendapatkan zona waktu dari browser klien? Saya melihat tautan berikut tetapi saya ingin solusi yang lebih kuat.
javascript
http
browser
timezone
confucius
sumber
sumber
Jawaban:
Lihatlah repositori ini pageloom akan sangat membantu
unduh jstz.min.js dan tambahkan fungsi ke halaman html Anda
<script language="javascript"> function getTimezoneName() { timezone = jstz.determine() return timezone.name(); } </script>
dan panggil fungsi ini dari tag tampilan Anda
sumber
Intl.DateTimeFormat().resolvedOptions().timeZone
(tanpa IE11) seperti yang disarankan oleh Wallace.Setengah dekade kemudian kami memiliki cara bawaan untuk itu! Untuk browser modern, saya akan menggunakan:
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone; console.log(tz);
Ini mengembalikan string zona waktu IANA, tetapi bukan offsetnya . Pelajari lebih lanjut di referensi MDN .
Tabel kompatibilitas - per Maret 2019, berfungsi untuk 90% browser yang digunakan secara global. Tidak berfungsi di Internet Explorer .
sumber
Intl.DateTimeFormat().resolvedOptions().timeZone
->undefined
Intl.DateTimeFormat().resolvedOptions().timeZone
akan mengembalikan nilai yang diharapkan mulai dari Firefox 52: kangax.github.io/compat-table/esintl/…Seringkali ketika orang mencari "zona waktu", yang cukup adalah "offset UTC". misalnya, server mereka dalam UTC + 5 dan mereka ingin tahu bahwa klien mereka berjalan pada UTC-8 .
Javascript lama biasa
(new Date()).getTimezoneOffset()/60
akan mengembalikan jumlah jam saat ini dari UTC.Perlu diperhatikan kemungkinan "gotcha" di tanda nilai yang
getTimezoneOffset()
dikembalikan (dari dokumen MDN) :Namun, saya sarankan Anda menggunakan day.js untuk kode Javascript terkait waktu / tanggal. Dalam hal ini Anda bisa mendapatkan offset UTC berformat ISO 8601 dengan menjalankan:
> dayjs().format("Z") "-08:00"
Mungkin perlu disebutkan bahwa klien dapat dengan mudah memalsukan informasi ini.
(Catatan: jawaban ini awalnya direkomendasikan https://momentjs.com/ , tetapi dayjs adalah alternatif yang lebih modern dan lebih kecil.)
sumber
Untuk saat ini, taruhan terbaik mungkin adalah jstz seperti yang disarankan dalam jawaban mbayloon .
Untuk kelengkapan perlu disebutkan bahwa ada standar dalam perjalanannya: Intl . Anda sudah dapat melihat ini di Chrome:
> Intl.DateTimeFormat().resolvedOptions().timeZone "America/Los_Angeles"
(Ini sebenarnya tidak mengikuti standar, yang merupakan satu lagi alasan untuk tetap menggunakan perpustakaan)
sumber
Intl
seharusnya kembaliundefined
untuktimeZone
properti jika Anda tidak secara manual menentukan zona waktu dalam membangunDateTimeFormat
. Chrome menyimpang dari standar dengan mengembalikan zona waktu sistem; itulah yang dieksploitasi oleh jawaban Yohanes, tetapi juga mengapa dia berkata "tidak benar-benar mengikuti standar".Anda dapat menggunakan zona waktu momen untuk menebak zona waktu:
> moment.tz.guess() "America/Asuncion"
sumber
Ini adalah jsfiddle
Ini memberikan singkatan dari zona waktu pengguna saat ini.
Ini contoh kodenya
var tz = jstz.determine(); console.log(tz.name()); console.log(moment.tz.zone(tz.name()).abbr(new Date().getTime()));
sumber
May 22 2015 03:45 PM CDT
saya gunakanconsole.log(moment(now).format('MMM DD YYYY hh:mm A') + ' ' + moment.tz.zone(tz.name()).abbr(now.getTime()));
Saya menggunakan pendekatan yang mirip dengan yang diambil oleh Josh Fraser , yang menentukan offset waktu browser dari UTC dan apakah itu mengenali DST atau tidak (tetapi agak disederhanakan dari kodenya):
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();
Saat memuat,
ClientTZ.getBrowserTZ()
fungsi dijalankan, yang menetapkan:ClientTZ.UTCoffset
untuk pengimbangan waktu browser dari UTC dalam menit (misalnya, CST adalah −360 menit, yaitu −6.0 jam dari UTC);ClientTZ.UTCoffsetT
untuk offset dalam bentuk'±hhmmD'
(misalnya,'-0600D'
), di mana sufiksD
untuk DST danS
untuk standar (non-DST);ClientTZ.hasDST
(menjadi benar atau salah).Ini
ClientTZ.UTCoffset
diberikan dalam hitungan menit, bukan jam, karena beberapa zona waktu memiliki offset per jam pecahan (mis., +0415).Maksud di baliknya
ClientTZ.UTCoffsetT
adalah menggunakannya sebagai kunci ke dalam tabel zona waktu (tidak disediakan di sini), seperti untuk daftar drop-down<select>
.sumber
7-1
untuk Juli, bukan Juni. Saya tidak yakin apakah itu benar-benar membuat perbedaan, karena saya ragu ada skema DST regional yang tidak menyertakan Juni.Ini adalah versi yang berfungsi dengan baik pada September 2020 menggunakan fetch dan https://worldtimeapi.org/api
fetch("https://worldtimeapi.org/api/ip") .then(response => response.json()) .then(data => console.log(data.timezone,data.datetime,data.dst));
sumber
Tidak. Tidak ada satu cara yang dapat diandalkan dan tidak akan pernah ada. Apakah Anda benar-benar berpikir Anda dapat mempercayai klien?
sumber