Mendapatkan offset zona waktu klien dalam JavaScript


615

Bagaimana saya bisa mengumpulkan informasi zona waktu pengunjung? Saya membutuhkan Zona Waktu, serta jam offset GMT.


3
Saya sedang memikirkan masalah yang sama sekarang. Ini pendekatan yang menarik.
Tamás Pap

31
Judul meminta zona waktu, sementara teks meminta offset GMT. Ini adalah 2 hal yang berbeda. Timezone menyertakan informasi tentang DST, sedangkan utc offset tidak. Timezone memiliki nama dan riwayat, offset tidak. Rekomendasikan untuk mengedit judul menjadi "Mendapatkan offset gmt klien di JS".
citykid

Saya butuh zona waktu. Offset GMT juga akan membantu.
DaveWalley

9
Jawaban di sini sebagian besar fokus pada offset . Untuk zona waktu lihat jawaban ini . Lihat "Zona Waktu! = Offset" di wiki tag zona waktu .
Matt Johnson-Pint

7
Anda mendapatkan Timezone dengan menggunakan Intl.DateTimeFormat (). ResolvedOptions (). TimeZone
Mangesh Mandavgane

Jawaban:


594

var offset = new Date().getTimezoneOffset();
console.log(offset);

Offset zona waktu adalah perbedaan, dalam menit, antara UTC dan waktu lokal. Perhatikan bahwa ini berarti bahwa offset positif jika zona waktu lokal di belakang UTC dan negatif jika berada di depan. Misalnya, jika zona waktu Anda UTC + 10 (Waktu Standar Australia Timur), -600 akan dikembalikan. Penghematan waktu siang hari mencegah nilai ini menjadi konstan bahkan untuk lokasi tertentu

Perhatikan bahwa tidak semua zona waktu diimbangi dengan seluruh jam: misalnya, Newfoundland adalah UTC minus 3j 30 m (meninggalkan Daylight Saving Time dari persamaan).


42
@abernier Apakah pernyataan tentang getTimezoneOffsetketidakakuratan berlaku? Artikel yang Anda maksud adalah tanggal Juni 2007 dan tidak memiliki rincian tentang bagaimana fungsi tersebut tidak akurat. Dan sebenarnya perpustakaan yang jsTimezoneDetectAnda tunjuk menggunakan getTimezoneOffsetdirinya sendiri.
Mike

5
@abernier Ini adalah standar sejak ES 1, jadi saya yakin setiap masalah implementasi mungkin sudah diperbaiki sekarang, maksud saya, itu adalah artikel yang berumur 7 tahun.
LasagnaAndroid

49
var hrs = -(new Date().getTimezoneOffset() / 60) untuk mendapatkan offset dalam jam yang biasanya digunakan
Edwin Daniels

6
Tampaknya tidak mempertimbangkan waktu
musim panas

21
timezone! =utc offset
bendytree

483

Menggunakan offset untuk menghitung Zona Waktu adalah pendekatan yang salah, dan Anda akan selalu menemui masalah. Zona waktu dan aturan penghematan siang hari dapat berubah pada beberapa kesempatan selama setahun, dan Sulit untuk mengikuti perubahan.

Untuk mendapatkan zona waktu IANA sistem dalam JavaScript, Anda harus menggunakan

console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)

Pada September 2019, ini berfungsi di 95% dari browser yang digunakan secara global .

Informasi kompatibilitas lama

ecma-402 / 1.0 mengatakan bahwa timeZonemungkin tidak terdefinisi jika tidak disediakan untuk konstruktor. Namun, konsep di masa depan (3.0) memperbaiki masalah itu dengan mengubah ke zona waktu default sistem.

Dalam versi Internasionalisasi API ECMAScript ini, timeZoneproperti akan tetap tidak terdefinisi jika tidak ada timeZoneproperti yang disediakan dalam objek opsi yang disediakan untuk Intl.DateTimeFormat konstruktor . Namun, aplikasi tidak boleh bergantung pada ini, karena versi masa depan dapat mengembalikan nilai String yang mengidentifikasi zona waktu lingkungan host saat ini sebagai gantinya.

di ecma-402 / 3.0 yang masih dalam konsep itu diubah menjadi

Dalam versi Internasionalisasi API ECMAScript 2015 ini, timeZoneproperti akan menjadi nama zona waktu default jika tidak ada timeZoneproperti yang disediakan dalam objek opsi yang disediakan untuk Intl.DateTimeFormatkonstruktor. Versi sebelumnya membuat timeZoneproperti tidak terdefinisi dalam kasus ini.


17
Ini adalah satu-satunya jawaban untuk mendapatkan zona waktu, yang mungkin dibutuhkan beberapa pengguna sebagai lawan dari offset saja. Jadi, sebagai pembaruan di 2016-09, Intl bekerja di sebagian besar browser modern tetapi tidak Safari. Untuk peramban itu, ada javascript fallback yang cukup akurat di sini - pellepim.bitbucket.org/jstz
user2085368

6
Diverifikasi bahwa ini sekarang tampaknya berfungsi di Safari. (Menggunakan versi 10.0)
BadPirate

2
Alangkah baiknya jika ini bekerja di semua browser modern. Namun IE11 dan Firefox terbaru keduanya kembali tidak ditentukan untuk properti timeZone.
Haprog

7
Saya telah menguji sekarang dengan Chrome 58, Edge 40 dan Firefox 53 - semuanya akan berhasil. Tidak bekerja dengan IE 11, saya tidak menguji Opera.
Suma

8
Butuh beberapa saat untuk menemukan daftar zona waktu yang dikembalikan oleh API ini. Ini dia: en.wikipedia.org/wiki/List_of_tz_database_time_zones
Xavier Poinas

123

Saya menyadari bahwa jawaban ini sedikit keluar dari topik, tetapi saya membayangkan banyak dari kita yang mencari jawaban juga ingin memformat zona waktu untuk tampilan dan mungkin mendapatkan singkatan zona juga. Jadi begini ...

Jika Anda ingin zona waktu klien diformat dengan baik, Anda dapat mengandalkan metode JavaScript Date.toString dan lakukan:

var split = new Date().toString().split(" ");
var timeZoneFormatted = split[split.length - 2] + " " + split[split.length - 1];

Ini akan memberi Anda "GMT-0400 (EST)" misalnya, termasuk menit zona waktu jika berlaku.

Atau, dengan regex Anda dapat mengekstrak bagian yang diinginkan:

Untuk "GMT-0400 (EDT)":

new Date().toString().match(/([A-Z]+[\+-][0-9]+.*)/)[1]

Untuk "GMT-0400":

new Date().toString().match(/([A-Z]+[\+-][0-9]+)/)[1]

Hanya untuk "EDT":

new Date().toString().match(/\(([A-Za-z\s].*)\)/)[1]

Hanya untuk "-0400":

new Date().toString().match(/([-\+][0-9]+)\s/)[1]

Referensi Date.toString: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/toString


4
Rusak dengan Chrome karena menambahkan nama zona waktu. Jangan gunakan split.length tetapi konstanta saja split[4] + " " + split[5]?!
Christophe Roussy

4
Ini juga tidak berfungsi di (kejutan, kejutan) IE. Saya baru saja melakukan dump konsol objek Date split. Sama di Chrome, Firefox dan Safari, tetapi berbeda di IE. Jadi, Anda juga tidak dapat mengandalkan indeks konstan. Senin 02 Des 2013 10:22:50 GMT-0500 (EST): Chrome, FF, Safari; Senin 2 Des 10:22:50 EST 2013: IE10
adimauro

1
Astaga, terima kasih! Saya telah melewati rintangan mencoba menampilkan zona waktu browser ..... ew Tanggal (). ToString (). Pertandingan (/ ([AZ] + [\ + -] [0-9] +. *) /) [ 1] persis apa yang saya butuhkan!
KiwiSunGoddess

1
Ini tidak berhasil. Bagi saya splitberisi: ["Mon", "Mar", "13", "2017", "14:05:22", "GMT-0400", "(Eastern", "Daylight", "Time)"]jadi hasilnyaDaylight Time)
DLeh

7
Ini sebenarnya bukan ide yang baik representasi sebenarnya dari waktu JS setelah Anda lakukan new Date().toString()sepenuhnya tergantung pada pengaturan lokal Anda. Mengharapkan output klien lain menyerupai milik Anda adalah ide yang sangat buruk.
Octopus

71

Sudah dijawab bagaimana cara mendapatkan offset dalam hitungan menit sebagai integer, tetapi jika ada yang menginginkan offset GMT lokal sebagai string misalnya "+1130":

function pad(number, length){
    var str = "" + number
    while (str.length < length) {
        str = '0'+str
    }
    return str
}

var offset = new Date().getTimezoneOffset()
offset = ((offset<0? '+':'-')+ // Note the reversed sign!
          pad(parseInt(Math.abs(offset/60)), 2)+
          pad(Math.abs(offset%60), 2))

1
Anda perlu mengganti padding ke-1 dengan pad(parseInt(Math.abs(offset/60)), 2)untuk memperbaikinya ... kalau tidak Anda mungkin mendapatkan +5.530 seperti dalam kasus saya ... saya tidak yakin apakah lantai matematika dll akan menjadi hal yang lebih baik di sini atau tidak .... tapi ini atleast memberi saya +530 seperti yang diharapkan
Abhinav Singh

Persis seperti yang saya cari. Terima kasih!
codesnooker

ini akan memberikan hasil yang benar: this.pad (Math.floor ((Math.abs (offset / 60))), 2)
Vivek

Alih-alih menggunakan fungsi pad Anda, saya merasa lebih mudah untuk melakukan ini: offset = (offset <0? "+": "-") + ("0000" + parseInt ((Math.abs (offset / 60))))) .slice (-4)
flurbius

67

Kamu bisa menggunakan:

zona waktu saat

<script src="moment.js"></script>
<script src="moment-timezone-with-data.js"></script>

// retrieve timezone by name (i.e. "America/Chicago")
moment.tz.guess();

Deteksi zona waktu browser agak sulit untuk dilakukan dengan benar, karena ada sedikit informasi yang disediakan oleh browser.

Moment Timezone menggunakan Date.getTimezoneOffset()dan Date.toString()pada beberapa momen di sekitar tahun berjalan untuk mengumpulkan sebanyak mungkin informasi tentang lingkungan browser. Kemudian membandingkan informasi itu dengan semua data zona waktu yang dimuat dan mengembalikan kecocokan terdekat. Dalam hal ikatan, zona waktu dengan kota dengan populasi terbesar dikembalikan.

console.log(moment.tz.guess()); // America/Chicago

12
Ini harus menjadi jawaban yang diterima. Ini adalah satu-satunya yang memberikan nama zona waktu yang sebenarnya daripada offset. Ingat bahwa offset zona waktu dapat diturunkan dari namanya, yang terjadi adalah sebaliknya. Karena DST dan seluk-beluk lainnya, beberapa zona waktu dapat memiliki offset yang sama pada beberapa hari tertentu saja dalam setahun.
Romain G

1
Ada solusi asli untuk ini sekarang - API Intl . Sementara moment.js adalah perpustakaan yang bagus pada masa itu, ada alternatif yang jauh lebih kecil saat ini ( dayjs , date-fns ). Momen sangat besar ; tolong jangan rekomendasikan untuk aplikasi klien.
Dan Dascalescu

43

Saya menulis fungsi dalam proyek saya, yang mengembalikan zona waktu dalam hh:mmformat. Saya harap ini dapat membantu seseorang:

function getTimeZone() {
    var offset = new Date().getTimezoneOffset(), o = Math.abs(offset);
    return (offset < 0 ? "+" : "-") + ("00" + Math.floor(o / 60)).slice(-2) + ":" + ("00" + (o % 60)).slice(-2);
}

// Outputs: +5:00

Biola yang Bekerja


1
Terima kasih! Inilah yang saya butuhkan!
Jeremy Moritz

15

Satu-liner yang memberikan offset dan zona waktu adalah dengan memanggil toTimeString () pada objek Date yang baru. Dari MDN:

The toTimeString()Metode mengembalikan porsi waktu dari objek Tanggal dalam bentuk yang dapat dibaca manusia dalam bahasa Inggris Amerika.

Tangkapannya adalah bahwa zona waktu tidak dalam format IANA standar; itu agak lebih ramah pengguna, daripada format IANA "benua / kota" . Cobalah:

console.log(new Date().toTimeString().slice(9));
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone);
console.log(new Date().getTimezoneOffset() / -60);

Di California sekarang, toTimeString()kembali Pacific Daylight Timesementara API Intl kembali America/Los_Angeles. Di Kolombia, Anda akan mendapatkan Colombia Standard Time, vs America/Bogota.

Perhatikan bahwa banyak jawaban lain untuk pertanyaan ini mencoba memperoleh informasi yang sama dengan memanggil Date.toString (). Pendekatan itu tidak dapat diandalkan, seperti yang dijelaskan MDN :

Contoh tanggal merujuk ke titik waktu tertentu. Memanggil toString () akan mengembalikan tanggal yang diformat dalam bentuk yang dapat dibaca manusia dalam bahasa Inggris Amerika. [...] Terkadang diinginkan untuk mendapatkan string dari porsi waktu; hal seperti itu dapat dicapai dengan toTimeString()metode ini.

The toTimeString()Metode ini sangat berguna karena mesin compliant menerapkan ECMA-262 mungkin berbeda dalam string yang diperoleh dari toString()untuk Datebenda-benda, seperti format adalah tergantung dari implementasi; pendekatan slicing string sederhana mungkin tidak menghasilkan hasil yang konsisten di banyak engine.


13

mencoba getTimezoneOffset()dari Dateobjek:

var curdate = new Date()
var offset = curdate.getTimezoneOffset()

Metode ini mengembalikan offset zona waktu dalam menit yang merupakan perbedaan antara GMT dan waktu lokal dalam menit.


9

JavaScript:

var d = new Date();
var n = d.getTimezoneOffset();
var timezone = n / -60;
console.log(timezone);


3
Apa yang dijawab oleh jawaban ini yang sebelumnya tidak dijawab?
Dan Dascalescu

7

Dengan moment.js :

moment().format('zz');

6
zdan zztelah ditinggalkan pada 1.6.0 lihat momentjs.com/docs/#/displaying/format
MrUpsidown

3
@ MrUpsidown sekarang ZdanZZ
brauliobo

4
@ Brauliobo Parameter ini tidak mengembalikan hal yang sama. z dan zz mengembalikan zona waktu, mis. CST, tetapi Z dan ZZ mengembalikan offset, misalnya -0600.
Luca Spiller

Acara dokumen terbaru .zoneAbbr()telah diganti zdan zz. Lihat dokumentasi di sini
tabish89

1
Sementara moment.js adalah perpustakaan yang bagus pada masa itu, ada alternatif yang jauh lebih kecil saat ini ( dayjs , date-fns ). Momen sangat besar ; tolong jangan rekomendasikan untuk aplikasi klien.
Dan Dascalescu

6

Dengan , Anda dapat menemukan zona waktu saat ini sebagai

console.log(moment().utcOffset()); // (-240, -120, -60, 0, 60, 120, 240, etc.)
<script src="https://cdn.jsdelivr.net/momentjs/2.13.0/moment.min.js"></script>


Dengan , Anda dapat menemukan zona waktu saat ini sebagai

console.log(dayjs().utcOffset()); // (-240, -120, -60, 0, 60, 120, 240, etc.)
<script src="https://unpkg.com/dayjs@1.8.10/dayjs.min.js"></script>

Kedua API mengembalikan utc offset dalam hitungan menit.


Sementara moment.js adalah perpustakaan yang bagus pada masa itu, ada alternatif yang jauh lebih kecil saat ini ( dayjs , date-fns ). Momen sangat besar ; tolong jangan rekomendasikan untuk aplikasi klien.
Dan Dascalescu

1
"Dengan dayjs, Anda dapat menemukan zona waktu saat ini sebagai" tidak sepenuhnya akurat - Anda hanya akan menemukan offset, bukan zona waktu . Juga, Dayjs tidak memiliki dukungan zona waktu . Its .utcOffset () metode adalah pembungkus sederhana atas asli getTimezoneOffset().
Dan Dascalescu

4

Zona waktu dalam jam-

var offset = new Date().getTimezoneOffset();
if(offset<0)
    console.log( "Your timezone is- GMT+" + (offset/-60));
else
    console.log( "Your timezone is- GMT-" + offset/60);

Jika Anda ingin tepat seperti yang Anda sebutkan dalam komentar, maka Anda harus mencoba seperti ini-

var offset = new Date().getTimezoneOffset();

if(offset<0)
{
    var extraZero = "";
    if(-offset%60<10)
      extraZero="0";

    console.log( "Your timezone is- GMT+" + Math.ceil(offset/-60)+":"+extraZero+(-offset%60));
}
else
{
    var extraZero = "";
    if(offset%60<10)
      extraZero="0";

    console.log( "Your timezone is- GMT-" + Math.floor(offset/60)+":"+extraZero+(offset%60));
}


Tidak berfungsi untuk zona waktu ketika itu bukan satu jam penuh, seperti Venezuela, di mana ia kembali GMT-4.5
Mirko

Ya itu benar. 0,5 berarti 0,5 * 30 menit. Saya pikir Anda mengerti mengapa ini memberi 0,5?
Abrar Jahin

ya, jadi GMT-4.5 bukan zona waktu yang valid, perlu sedikit penguraian tambahan untuk menjadi GMT-4: 30
Mirko

@Mirko sekarang bagian kedua dari jawabannya adalah untuk Anda
Abrar Jahin

Jika Anda ingin lebih tepatnya, gunakan UTC dan bukan GMT, [Hilton dan McCarthy 2013, hlm. 231–2. ], lihat juga di wikipedia GMT - ( en.wikipedia.org/wiki/Greenwich_Mean_Time )
Tom Kuschel

3

Jika yang Anda butuhkan adalah singkatan zona waktu "MST" atau "EST":

function getTimeZone(){
    var now = new Date().toString();
    var timeZone = now.replace(/.*[(](.*)[)].*/,'$1');//extracts the content between parenthesis
    return timeZone;
}

Penggunaan Date.toString()tidak dapat diandalkan, dan MDN menjelaskan alasannya. Saya telah menempel bagian yang relevan dari dokumen mereka dalam jawaban saya .
Dan Dascalescu

3

Lihat operator yang dihasilkan ini berseberangan dengan Zona Waktu. Jadi, terapkan beberapa fungsi matematika lalu validasikan num lebih sedikit atau lebih.

masukkan deskripsi gambar di sini

Lihat dokumen MDN

var a = new Date().getTimezoneOffset();

var res = -Math.round(a/60)+':'+-(a%60);
res = res < 0 ?res : '+'+res;

console.log(res)


1
memetikan nilai negatif, beberapa masalah
Arun Prasad ES

1
Mengapa round? Seharusnya begitu floor, bukan?
Qwertiy

3
function getLocalTimeZone() {
    var dd = new Date();
    var ddStr = dd.toString();
    var ddArr = ddStr.split(' ');
    var tmznSTr = ddArr[5];
    tmznSTr = tmznSTr.substring(3, tmznSTr.length);
    return tmznSTr;
}

Contoh: Kamis 21 Juni 2018 18:12:50 GMT + 0530 (Waktu Standar India)

O / P: +0530


Penggunaan Date.toString()tidak dapat diandalkan, dan MDN menjelaskan alasannya. Saya telah menempel bagian yang relevan dari dokumen mereka dalam jawaban saya .
Dan Dascalescu


2

Nilai ini dari mesin pengguna dan dapat diubah kapan saja jadi saya pikir itu tidak masalah, saya hanya ingin mendapatkan nilai perkiraan dan kemudian mengubahnya ke GMT di server saya.

Misalnya, saya dari Taiwan dan mengembalikan "+8" untuk saya.

Contoh kerja

JS

function timezone() {
    var offset = new Date().getTimezoneOffset();
    var minutes = Math.abs(offset);
    var hours = Math.floor(minutes / 60);
    var prefix = offset < 0 ? "+" : "-";
    return prefix+hours;
}


$('#result').html(timezone());

HTML

<div id="result"></div>

Hasil

+8

2

Pada new Date() Anda bisa mendapatkan offset, untuk mendapatkan nama zona waktu yang dapat Anda lakukan:

new Date().toString().replace(/(.*\((.*)\).*)/, '$2');

Anda mendapatkan nilai ()di antara di akhir tanggal, itu adalah nama zona waktu.


Penggunaan Date.toString()tidak dapat diandalkan, dan MDN menjelaskan alasannya. Saya telah menempel bagian yang relevan dari dokumen mereka dalam jawaban saya . Juga, jawaban ini sudah diberikan setidaknya 3 kali.
Dan Dascalescu

2

Ini akan menjadi solusi saya:


    // For time zone:
    const timeZone = /\((.*)\)/.exec(new Date().toString())[1];
    
    // Offset hours:
    const offsetHours = new Date().getTimezoneOffset() / 60;
    
    console.log(`${timeZone}, ${offsetHours}hrs`);

1

Sebagai alternatif new Date().getTimezoneOffset()dan moment().format('zz'), Anda juga bisa menggunakan:

var offset = moment.parseZone(Date.now()).utcOffset() / 60
console.log(offset);
<script src="https://cdn.jsdelivr.net/momentjs/2.13.0/moment.min.js"></script>

jstimezone juga cukup bermasalah dan tidak terawat ( https://bitbucket.org/pellepim/jstimezonedetect/issues?status=new&status=open )


Sementara moment.js adalah perpustakaan yang bagus pada masa itu, ada alternatif yang jauh lebih kecil saat ini ( dayjs , date-fns ). Momen sangat besar ; tolong jangan rekomendasikan untuk aplikasi klien.
Dan Dascalescu

1

Gunakan ini untuk mengonversi OffSet ke postive:

var offset = new Date().getTimezoneOffset();
console.log(offset);
this.timeOffSet = offset + (-2*offset);
console.log(this.timeOffSet);

-2

Saya hanya mencari string 3 huruf (seperti "PDT") dan mencoba jawaban Marquez tetapi harus sedikit men-tweak untuk dukungan lintas browser. Untungnya, string adalah pertandingan potensial terakhir :)

Inilah yang saya lakukan, di CoffeeScript:

browserTimezone = ->
  userDate = new Date()
  zoneMatches = userDate.toString().match(/([A-Z][A-Z][A-Z])/g)
  userZone = zoneMatches[zoneMatches.length - 1]

Bekerja di IE8, IE9, Safari 9, Firefox 44, dan Chrome 48


2
Ada zona waktu dengan 4 huruf - hati-hati: CEST misalnya (Waktu Musim Panas Eropa Tengah)
jbrosi

Penggunaan Date.toString()tidak dapat diandalkan, dan MDN menjelaskan alasannya. Saya telah menempel bagian yang relevan dari dokumen mereka dalam jawaban saya .
Dan Dascalescu

-3

Anda hanya perlu memasukkan moment.js dan jstz.js

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.6/jstz.min.js"></script>

dan setelah itu

<script>
$(function(){
 var currentTimezone = jstz.determine();
 var timezone = currentTimezone.name();
 alert(timezone);
});

</script>

-3

Ini pekerjaan yang sangat baik untuk saya:

// Translation to offset in Unix Timestamp
let timeZoneOffset = ((new Date().getTimezoneOffset())/60)*3600;

1
Ada penjelasan?

-4

Anda bisa mencoba ini. itu akan mengembalikan Anda waktu mesin saat ini

var _d = new Date(), t = 0, d = new Date(t*1000 + _d.getTime())


Ini adalah bagaimana harus dilakukan saya pikir: new Date(new Date().getTime()); itu akan menampilkan: "Jumat 28 Des 2018 10:15:23 GMT + 0100 (Waktu Standar Eropa Tengah) {}"
darmis

-4

Ini akan melakukan pekerjaan.


var time = new Date(),
timestamp = Date(1000 + time.getTime());
console.log(timestamp);

Thu May 25 2017 21:35:14 GMT+0300 (IDT)

tidak terdefinisi

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.