Ottenere l'offset del fuso orario del cliente in JavaScript


616

Come posso raccogliere le informazioni sul fuso orario del visitatore? Ho bisogno del fuso orario e delle ore di offset GMT.


3
Sto riscontrando lo stesso problema ora. Ecco un approccio interessante.
Tamás Pap,

31
Il titolo richiede il fuso orario, mentre il testo richiede la differenza GMT. Queste sono 2 cose diverse. Un fuso orario include informazioni sull'ora legale, mentre l'offset utc no. Un fuso orario ha un nome e una cronologia, l'offset no. Consiglia di modificare il titolo in "Ottenere l'offset gmt del client in JS".
citykid,

Ho bisogno del fuso orario. Anche l'offset GMT sarebbe utile.
DaveWalley,

9
Le risposte qui si concentrano principalmente sull'offset . Per il fuso orario vedi questa risposta . Vedi "Fuso orario! = Offset" nel wiki del fuso orario .
Matt Johnson-Pint,

7
Ottieni il fuso orario esatto usando questo Intl.DateTimeFormat (). ResolvedOptions (). TimeZone
Mangesh Mandavgane

Risposte:


594

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

La differenza di fuso orario è la differenza, in minuti, tra l'ora UTC e l'ora locale. Si noti che ciò significa che l'offset è positivo se il fuso orario locale è dietro UTC e negativo se è avanti. Ad esempio, se il fuso orario è UTC + 10 (Australian Eastern Standard Time), verrà restituito -600. L'ora legale impedisce a questo valore di essere una costante anche per una determinata locale

Si noti che non tutti i fusi orari sono sfalsati di ore intere: ad esempio, Terranova è UTC meno 3h 30m (lasciando l'ora legale fuori dall'equazione).


42
@abernier La dichiarazione sull'inesattezza è getTimezoneOffsetin vigore? L'articolo a cui ti riferisci è datato giugno 2007 e non contiene dettagli su come la funzione non è precisa. E in effetti la libreria che jsTimezoneDetecthai indicato si utilizza da getTimezoneOffsetsola.
Mike,

5
@abernier È uno standard dall'ES 1, quindi sono sicuro che qualsiasi problema di implementazione potrebbe essere risolto ormai, voglio dire, è un articolo di 7 anni.
Lasagna Android

49
var hrs = -(new Date().getTimezoneOffset() / 60) per compensare le ore normalmente utilizzate
Edwin Daniels,

6
Sembra che non consideri l'ora legale
Shahdat

21
timezone! =utc offset
bendytree il

484

L'uso di un offset per calcolare il fuso orario è un approccio sbagliato e incontrerai sempre dei problemi. I fusi orari e le regole sull'ora legale possono cambiare in diverse occasioni durante l'anno, ed è difficile tenere il passo con i cambiamenti.

Per ottenere il fuso orario IANA del sistema in JavaScript, è necessario utilizzare

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

A partire da settembre 2019, funziona nel 95% dei browser utilizzati a livello globale .

Informazioni sulla vecchia compatibilità

ecma-402 / 1.0 dice che timeZonepotrebbe essere indefinito se non fornito al costruttore. Tuttavia, la bozza futura (3.0) ha risolto il problema modificando il fuso orario predefinito del sistema.

In questa versione dell'API di internazionalizzazione ECMAScript, la timeZoneproprietà rimarrà indefinita se non è timeZonestata fornita alcuna proprietà nell'oggetto opzioni fornito al Intl.DateTimeFormat costruttore . Tuttavia, le applicazioni non dovrebbero fare affidamento su questo, poiché le versioni future potrebbero restituire un valore String che identifica invece il fuso orario corrente dell'ambiente host.

in ecma-402 / 3.0 che è ancora in una bozza in cui è cambiato

In questa versione dell'API di internazionalizzazione di ECMAScript 2015, la timeZoneproprietà sarà il nome del fuso orario predefinito se non è timeZonestata fornita alcuna proprietà nell'oggetto opzioni fornito al Intl.DateTimeFormatcostruttore. La versione precedente ha lasciato la timeZoneproprietà non definita in questo caso.


17
Questa è l'unica risposta per ottenere il fuso orario, di cui alcuni utenti potrebbero aver bisogno in contrapposizione al solo offset. Quindi, come aggiornamento del 2016-09, Intl funziona sulla maggior parte dei browser moderni ma non su Safari. Per quel browser, c'è un fallback javascript ragionevolmente accurato qui - pellepim.bitbucket.org/jstz
user2085368

6
Ho verificato che ora sembra funzionare in Safari. (Usando la versione 10.0)
BadPirate

2
Sarebbe bello se funzionasse in tutti i browser moderni. Tuttavia, IE11 e Firefox più recenti restituiscono entrambi non definiti per la proprietà timeZone.
Haprog,

7
Ho testato ora con Chrome 58, Edge 40 e Firefox 53 - funziona tutti quanti. Non funziona con IE 11, non ho testato Opera.
Suma,

8
Mi ci è voluto un po 'per trovare l'elenco dei fusi orari restituiti da questa API. Eccolo: en.wikipedia.org/wiki/List_of_tz_database_time_zones
Xavier Poinas

123

Mi rendo conto che questa risposta è un po 'fuori tema, ma immagino che molti di noi in cerca di una risposta volessero anche formattare il fuso orario per la visualizzazione e forse ottenere anche l'abbreviazione di zona. Quindi eccolo qui ...

Se desideri che il fuso orario del client sia formattato correttamente, puoi fare affidamento sul metodo JavaScript Date.toString ed eseguire:

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

Questo ti darà "GMT-0400 (EST)" per esempio, inclusi i minuti del fuso orario quando applicabile.

In alternativa, con regex è possibile estrarre qualsiasi parte desiderata:

Per "GMT-0400 (EDT)":

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

Per "GMT-0400":

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

Solo per "EDT":

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

Per solo "-0400":

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

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


4
Rotto con Chrome in quanto aggiunge il nome del fuso orario. Non usare split.length ma una costante invece split[4] + " " + split[5]?!
Christophe Roussy,

4
Anche questo non funziona in IE (sorpresa, sorpresa). Ho appena fatto un dump della console dell'oggetto Date diviso. È lo stesso in Chrome, Firefox e Safari, ma diverso in IE. Quindi, non puoi contare nemmeno sugli indici costanti. Lun 02 Dic 2013 10:22:50 GMT-0500 (EST): Chrome, FF, Safari; Lun 2 dicembre 10:22:50 EST 2013: IE10
adimauro

1
Accidenti grazie! Ho saltato attraverso i cerchi cercando di visualizzare il fuso orario del browser ..... ew Date (). ToString (). Match (/ ([AZ] + [\ + -] [0-9] +. *) /) [ 1] era esattamente quello di cui avevo bisogno!
KiwiSunGoddess

1
Questo non funziona Per me splitcontiene: ["Mon", "Mar", "13", "2017", "14:05:22", "GMT-0400", "(Eastern", "Daylight", "Time)"]quindi il risultato èDaylight Time)
DLeh

7
Questa non è in realtà una buona idea della rappresentazione effettiva del tempo JS dopo averlo fatto new Date().toString()dipende completamente dalle impostazioni locali. Aspettarsi che gli output degli altri clienti assomiglino ai tuoi è una pessima idea.
Polpo,

71

È già stato risposto come ottenere l'offset in minuti come numero intero, ma nel caso in cui qualcuno desideri l'offset GMT locale come stringa, ad esempio "+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
Devi sostituire la prima imbottitura con pad(parseInt(Math.abs(offset/60)), 2)per farlo bene ... altrimenti potresti finire per ottenere +5.530 come nel mio caso ... non sono sicuro che il pavimento di matematica ecc sarà una cosa migliore qui o no .... ma questo atleast mi dà +0530 come previsto
Abhinav Singh

Esattamente quello che stavo cercando. Grazie !
codici

questo darà il risultato corretto: this.pad (Math.floor ((Math.abs (offset / 60))), 2)
Vivek

Invece di usare la funzione pad, trovo più facile farlo: offset = (offset <0? "+": "-") + ("0000" + parseInt ((Math.abs (offset / 60))) .slice (-4)
flurbius,

67

Puoi usare:

momento-fuso orario

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

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

Il rilevamento del fuso orario del browser è piuttosto complicato da ottenere, poiché ci sono poche informazioni fornite dal browser.

Momento Timezone utilizza Date.getTimezoneOffset()e Date.toString()una manciata di momenti attorno all'anno in corso per raccogliere quante più informazioni possibili sull'ambiente del browser. Quindi confronta tali informazioni con tutti i dati di fuso orario caricati e restituisce la corrispondenza più vicina. In caso di vincoli, viene restituito il fuso orario con la città con la più grande popolazione.

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

12
Questa dovrebbe essere la risposta accettata. Questo è l'unico che fornisce il nome del fuso orario effettivo piuttosto che l'offset. Ricorda che l'offset del fuso orario può essere derivato dal nome, il contrario non è vero. A causa dell'ora legale e di altre sottigliezze, più fusi orari possono avere lo stesso offset solo in alcuni giorni specifici dell'anno.
Romain G,

1
Ora esiste una soluzione nativa per questo: l' API Intl . Mentre moment.js era una grande biblioteca nel passato, al momento ci sono alternative molto più piccole ( dayjs , date-fns ). Il momento è enorme ; per favore non lo consiglio per le applicazioni client.
Dan Dascalescu,

43

Ho scritto una funzione nel mio progetto, che restituisce il fuso orario in hh:mmformato. Spero che questo possa aiutare qualcuno:

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

Fiddle di lavoro


1
Grazie! Questo è quello di cui avevo bisogno!
Jeremy Moritz,

15

Un one-liner che fornisce sia l'offset sia il fuso orario è semplicemente chiamare toTimeString () su un nuovo oggetto Date. Da MDN:

Il toTimeString()metodo restituisce la parte temporale di un oggetto Date in forma leggibile in inglese americano.

Il problema è che il fuso orario non è nel formato IANA standard; è un po 'più intuitivo rispetto al formato IANA "continente / città" . Provalo:

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

In California in questo momento, toTimeString()ritorna Pacific Daylight Timementre l'API Intl ritorna America/Los_Angeles. In Colombia, otterresti Colombia Standard Time, controAmerica/Bogota .

Si noti che molte altre risposte a questa domanda tentano di ottenere le stesse informazioni chiamando Date.toString (). Tale approccio non è così affidabile, come spiega MDN :

Le istanze di data si riferiscono a un momento specifico. Chiamare toString () restituirà la data formattata in una forma leggibile dall'inglese americano. [...] A volte è desiderabile ottenere una stringa della porzione di tempo; una cosa del genere può essere realizzata con il toTimeString()metodo.

Il toTimeString()metodo è particolarmente utile perché i motori conformi che implementano ECMA-262 possono differire nella stringa ottenuta toString()per gli Dateoggetti, poiché il formato dipende dall'implementazione; semplici approcci di affettatura delle stringhe potrebbero non produrre risultati coerenti su più motori.


13

provare getTimezoneOffset()di Dateoggetto:

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

Questo metodo restituisce la differenza di fuso orario in minuti che è la differenza tra GMT e l'ora locale in minuti.


9

JavaScript:

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


3
Cosa fornisce questa risposta che le risposte precedenti non hanno?
Dan Dascalescu,

7

Con moment.js :

moment().format('zz');

6
ze zzsono stati deprecati a partire dalla 1.6.0 vedi momentjs.com/docs/#/displaying/format
MrUpsidown

3
@MrUpsidown è adesso ZeZZ
brauliobo il

4
@brauliobo Questi parametri non restituiscono la stessa cosa. z e zz hanno restituito il fuso orario, ad esempio CST, ma Z e ZZ restituiscono l'offset, ad esempio -0600.
Luca Spiller,

Il più recente show di documenti .zoneAbbr()è stato sostituito ze zz. Vedi la documentazione qui
tabish89,

1
Mentre moment.js era una grande biblioteca nel corso della giornata, ci sono alternative molto più piccole attualmente ( dayjs , date-fns ). Il momento è enorme ; per favore non lo consiglio per le applicazioni client.
Dan Dascalescu,

6

Con , puoi trovare il fuso orario corrente come

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>


Con , puoi trovare il fuso orario corrente come

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>

Entrambe le API restituiscono l'offset utc in pochi minuti.


Mentre moment.js era una grande biblioteca nel corso della giornata, ci sono alternative molto più piccole attualmente ( dayjs , date-fns ). Il momento è enorme ; per favore non lo consiglio per le applicazioni client.
Dan Dascalescu,

1
"Con dayjs, puoi trovare il fuso orario corrente come" non è esattamente preciso: troverai solo l'offset, non il fuso orario . Inoltre, Dayjs non ha il supporto del fuso orario . Il suo metodo .utcOffset () è un semplice wrapper sul nativo getTimezoneOffset().
Dan Dascalescu,

4

Fuso orario in ore

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);

Se vuoi essere preciso come hai detto nel commento, allora dovresti provare in questo modo-

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));
}


Non funziona per i fusi orari quando non è un'ora intera, come il Venezuela, dove ritorna GMT-4.5
Mirko

Si è giusto. 0,5 significa 0,5 * 30 minuti. Penso che tu abbia questo perché sta dando 0,5?
Abrar Jahin

sì, quindi GMT-4.5 non è un fuso orario valido, ha bisogno di un po 'di analisi extra per diventare GMT-4: 30
Mirko

@ Mirko ora la seconda parte della risposta è per te
Abrar Jahin

Se vuoi essere più preciso, usa UTC invece di GMT, [Hilton e McCarthy 2013, p. 231-2. ], vedi anche su wikipedia GMT - ( en.wikipedia.org/wiki/Greenwich_Mean_Time )
Tom Kuschel

3

Se tutto ciò che serve è l'abbreviazione del fuso orario "MST" o "EST":

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

L'uso Date.toString()non è affidabile e MDN spiega perché. Nella mia risposta ho incollato la sezione pertinente dai loro documenti .
Dan Dascalescu,

3

Vedere questo operatore risultante era opposto al fuso orario. Quindi applicare alcune funzioni matematiche quindi convalidare il numero minore o più.

inserisci qui la descrizione dell'immagine

Vedi il documento MDN

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

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

console.log(res)


1
in caso di valore negativo, qualche problema
Arun Prasad ES

1
Perché round? Dovrebbe essere floor, no?
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;
}

Esempio: gio 21 giu 2018 18:12:50 GMT + 0530 (India Standard Time)

O / P: +0530


L'uso Date.toString()non è affidabile e MDN spiega perché. Nella mia risposta ho incollato la sezione pertinente dai loro documenti .
Dan Dascalescu,


2

Questo valore proviene dalla macchina dell'utente e può essere modificato in qualsiasi momento, quindi penso che non abbia importanza, voglio solo ottenere un valore approssimativo e convertirlo in GMT nel mio server.

Ad esempio, vengo da Taiwan e per me restituisce "+8".

Esempio funzionante

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>

Risultato

+8

2

Sul new Date() è possibile ottenere l'offset, per ottenere il nome del fuso orario che si può fare:

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

ottieni il valore tra ()alla fine della data, ovvero il nome del fuso orario.


L'uso Date.toString()non è affidabile e MDN spiega perché. Nella mia risposta ho incollato la sezione pertinente dai loro documenti . Inoltre, questa risposta è stata già fornita almeno 3 volte.
Dan Dascalescu,

2

Questa sarebbe la mia soluzione:


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

1

In alternativa a new Date().getTimezoneOffset()e moment().format('zz'), puoi anche usare:

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 è anche piuttosto difettoso e non mantenuto ( https://bitbucket.org/pellepim/jstimezonedetect/issues?status=new&status=open )


Mentre moment.js era una grande biblioteca nel corso della giornata, ci sono alternative molto più piccole attualmente ( dayjs , date-fns ). Il momento è enorme ; per favore non lo consiglio per le applicazioni client.
Dan Dascalescu,

1

Usa questo per convertire OffSet in postivo:

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

-2

Stavo cercando solo la stringa di 3 lettere (come "PDT") e ho provato la risposta di Marquez, ma ho dovuto modificarla un po 'per il supporto cross-browser. Fortunatamente, la stringa è l'ultima potenziale corrispondenza :)

Ecco cosa ho fatto, in CoffeeScript:

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

Funziona in IE8, IE9, Safari 9, Firefox 44 e Chrome 48


2
Ci sono fusi orari con 4 lettere - attenzione: CEST per esempio (ora legale dell'Europa centrale)
jbrosi

L'uso Date.toString()non è affidabile e MDN spiega perché. Nella mia risposta ho incollato la sezione pertinente dai loro documenti .
Dan Dascalescu,

-3

Devi solo includere moment.js e 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>

dopodiché

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

</script>

-3

Questo è un ottimo lavoro per me:

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

1
Alcuna spiegazione ?

-4

puoi semplicemente provare questo. ti restituirà il tempo corrente della macchina

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


Ecco come dovrebbe essere fatto penso: new Date(new Date().getTime()); visualizzerebbe: "Ven 28 dic 2018 10:15:23 GMT + 0100 (Central European Standard Time) {}"
darmis

-4

Questo farà il lavoro.


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

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

non definito

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.