Adakah cara yang dapat diandalkan untuk mendapatkan zona waktu dari browser klien? Saya melihat tautan berikut tetapi saya ingin solusi yang lebih kuat.
Adakah cara yang dapat diandalkan untuk mendapatkan zona waktu dari browser klien? Saya melihat tautan berikut tetapi saya ingin solusi yang lebih kuat.
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
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 .
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) :
Pengimbangan zona waktu adalah perbedaan, dalam menit, antara UTC dan waktu lokal. Perhatikan bahwa ini berarti offsetnya positif jika zona waktu lokal berada di belakang UTC dan negatif jika lebih dulu. Misalnya, untuk zona waktu UTC + 10: 00 (Waktu Standar Timur Australia, Waktu Vladivostok, Waktu Standar Chamorro), -600 akan dikembalikan.
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.)
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)
Intl
seharusnya kembali undefined
untuk timeZone
properti jika Anda tidak secara manual menentukan zona waktu dalam membangun DateTimeFormat
. 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"
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()));
May 22 2015 03:45 PM CDT
saya gunakan console.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 sufiks D
untuk DST dan S
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>
.
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));
Tidak. Tidak ada satu cara yang dapat diandalkan dan tidak akan pernah ada. Apakah Anda benar-benar berpikir Anda dapat mempercayai klien?