Obtention du décalage du fuseau horaire du client en JavaScript


616

Comment puis-je recueillir les informations de fuseau horaire du visiteur? J'ai besoin du fuseau horaire, ainsi que des heures de décalage GMT.


3
Je vois le même problème maintenant. Voici une approche intéressante.
Tamás Pap

31
Le titre demande un fuseau horaire, tandis que le texte demande un décalage GMT. Ce sont 2 choses différentes. Un fuseau horaire contient des informations sur l'heure d'été, le décalage utc non. Un fuseau horaire a un nom et un historique, contrairement à l'offset. Recommandez de modifier le titre en "Obtention du décalage gmt du client dans JS".
citykid

J'ai besoin du fuseau horaire. Le décalage GMT serait également utile.
DaveWalley

9
Les réponses se concentrent ici principalement sur l' offset . Pour le fuseau horaire, voir cette réponse . Voir "Time Zone! = Offset" dans le wiki des balises de fuseau horaire .
Matt Johnson-Pint

7
Vous obtenez le fuseau horaire exact en utilisant ce Intl.DateTimeFormat () .olvedOptions (). TimeZone
Mangesh Mandavgane

Réponses:


594

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

Le décalage de fuseau horaire est la différence, en minutes, entre l'heure UTC et l'heure locale. Notez que cela signifie que le décalage est positif si le fuseau horaire local est derrière UTC et négatif s'il est devant. Par exemple, si votre fuseau horaire est UTC + 10 (Australian Eastern Standard Time), -600 sera renvoyé. L'heure d'été empêche cette valeur d'être constante même pour un lieu donné

Notez que tous les fuseaux horaires ne sont pas décalés par des heures entières: par exemple, Terre-Neuve est UTC moins 3 h 30 (ce qui laisse l'heure d'été hors de l'équation).


42
@abernier La déclaration sur l' getTimezoneOffsetinexactitude est-elle en vigueur? L'article auquel vous faites référence est daté de juin 2007 et ne contient aucun détail sur l'inexactitude de la fonction. Et en fait, la bibliothèque que jsTimezoneDetectvous avez pointée utilise getTimezoneOffsetelle-même.
Mike

5
@abernier C'est une norme depuis ES 1, donc je suis sûr que tout problème d'implémentation pourrait être résolu maintenant, je veux dire, c'est un article vieux de 7 ans.
LasagnaAndroid

49
var hrs = -(new Date().getTimezoneOffset() / 60) pour compenser les heures généralement utilisées
Edwin Daniels

6
Semble qu'il ne considère pas l'heure d'été
Shahdat

21
timezone! =utc offset
bendytree

484

L'utilisation d'un décalage pour calculer le fuseau horaire est une mauvaise approche et vous rencontrerez toujours des problèmes. Les fuseaux horaires et les règles d'heure d'été peuvent changer à plusieurs reprises au cours d'une année, et il est difficile de suivre les changements.

Pour obtenir le fuseau horaire IANA du système en JavaScript, vous devez utiliser

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

En septembre 2019, cela fonctionne dans 95% des navigateurs utilisés dans le monde .

Anciennes informations de compatibilité

ecma-402 / 1.0 indique que cela timeZonepeut être indéfini s'il n'est pas fourni au constructeur. Cependant, le futur brouillon (3.0) a résolu ce problème en passant au fuseau horaire par défaut du système.

Dans cette version de l'API d'internationalisation ECMAScript, la timeZonepropriété restera indéfinie si aucunetimeZone propriété été fournie dans l'objet options fourni au Intl.DateTimeFormat constructeur . Cependant, les applications ne doivent pas se fier à cela, car les futures versions pourraient renvoyer une valeur String identifiant le fuseau horaire actuel de l'environnement hôte.

dans ecma-402 / 3.0 qui est encore dans un projet, il est devenu

Dans cette version de l'API d'internationalisation ECMAScript 2015, la timeZonepropriété sera le nom du fuseau horaire par défaut si aucune timeZonepropriété n'a été fournie dans l'objet options fourni au Intl.DateTimeFormatconstructeur. La version précédente laissait la timeZonepropriété non définie dans ce cas.


17
C'est la seule réponse pour obtenir le fuseau horaire, dont certains utilisateurs peuvent avoir besoin par opposition au décalage uniquement. Ainsi, en tant que mise à jour en 2016-09, Intl fonctionne sur la plupart des navigateurs modernes mais pas sur Safari. Pour ce navigateur, il existe une solution de
user2085368

6
Vérifié que cela semble maintenant fonctionner dans Safari. (En utilisant la version 10.0)
BadPirate

2
Ce serait bien si cela fonctionnait dans tous les navigateurs modernes. Cependant, IE11 et le dernier Firefox renvoient tous deux non définis pour la propriété timeZone.
Haprog

7
J'ai testé maintenant avec Chrome 58, Edge 40 et Firefox 53 - cela fonctionne tous. Cela ne fonctionne pas avec IE 11, je n'ai pas testé Opera.
Suma

8
Il m'a fallu un certain temps pour trouver la liste des fuseaux horaires renvoyés par cette API. Le voici: en.wikipedia.org/wiki/List_of_tz_database_time_zones
Xavier Poinas

123

Je me rends compte que cette réponse est un peu hors sujet, mais j'imagine que beaucoup d'entre nous à la recherche d'une réponse voulaient également formater le fuseau horaire pour l'affichage et peut-être aussi l'abréviation de la zone. Alors c'est parti ...

Si vous voulez que le fuseau horaire du client soit bien formaté, vous pouvez vous fier à la méthode JavaScript Date.toString et faire:

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

Cela vous donnera par exemple «GMT-0400 (EST)», y compris les minutes du fuseau horaire, le cas échéant.

Alternativement, avec regex, vous pouvez extraire n'importe quelle partie souhaitée:

Pour "GMT-0400 (EDT)":

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

Pour "GMT-0400":

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

Pour "EDT":

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

Pour "-0400" seulement:

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

Référence Date.toString: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/toString


4
Cassé avec Chrome car il ajoute le nom du fuseau horaire. N'utilisez pas split.length mais une constante à la place split[4] + " " + split[5]?!
Christophe Roussy

4
Cela ne fonctionne pas non plus dans (surprise, surprise) IE. Je viens de faire un vidage sur console de l'objet Date fractionné. C'est la même chose dans Chrome, Firefox et Safari, mais différent dans IE. Donc, vous ne pouvez pas non plus compter sur les index constants. 02 décembre 2013 10:22:50 GMT-0500 (EST): Chrome, FF, Safari; 2 déc 10:22:50 HNE 2013: IE10
adimauro

1
Mon Dieu merci! J'ai sauté dans les cerceaux en essayant d'afficher le fuseau horaire du navigateur ..... ew Date (). ToString (). Match (/ ([AZ] + [\ + -] [0-9] +. *) /) [ 1] était exactement ce dont j'avais besoin!
KiwiSunGoddess

1
Ça ne marche pas. Pour moi splitcontient: ["Mon", "Mar", "13", "2017", "14:05:22", "GMT-0400", "(Eastern", "Daylight", "Time)"]donc le résultat estDaylight Time)
DLeh

7
Ce n'est en fait pas une bonne idée de la représentation réelle de l'heure JS après que vous ayez new Date().toString()dépend complètement de vos paramètres régionaux. Attendre des sorties des autres clients qu'elles ressemblent aux vôtres est une très mauvaise idée.
Octopus

71

On a déjà répondu comment obtenir l'offset en minutes sous forme d'entier, mais au cas où quelqu'un voudrait l'offset GMT local sous forme de chaîne, par exemple "+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
Vous devez remplacer le premier rembourrage par pad(parseInt(Math.abs(offset/60)), 2)pour le faire correctement ... sinon vous pourriez finir par obtenir +5.530 comme dans mon cas ... je ne sais pas si le plancher de mathématiques, etc. sera une meilleure chose ici ou non .... mais cela au moins me donne +0530 comme prévu
Abhinav Singh

Exactement ce que je cherchais. Merci !
codesnooker

cela donnera un résultat correct: this.pad (Math.floor ((Math.abs (offset / 60))), 2)
Vivek

Au lieu d'utiliser votre fonction pad, je trouve plus facile de le faire: offset = (offset <0? "+": "-") + ("0000" + parseInt ((Math.abs (offset / 60)))) .slice (-4)
flurbius

67

Vous pouvez utiliser:

fuseau horaire

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

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

La détection du fuseau horaire du navigateur est plutôt délicate à effectuer, car il y a peu d'informations fournies par le navigateur.

Moment Timezone utilise Date.getTimezoneOffset()et Date.toString()sur une poignée de moments de l'année en cours pour collecter autant d'informations que possible sur l'environnement du navigateur. Il compare ensuite ces informations avec toutes les données de fuseau horaire chargées et renvoie la correspondance la plus proche. En cas d'égalité, le fuseau horaire avec la ville la plus peuplée est retourné.

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

12
Ce devrait être la réponse acceptée. C'est le seul qui donne le nom du fuseau horaire réel plutôt que le décalage. N'oubliez pas que le décalage de fuseau horaire peut être dérivé du nom, l'inverse n'est pas vrai. En raison de l'heure d'été et d'autres subtilités, plusieurs fuseaux horaires peuvent avoir le même décalage certains jours spécifiques de l'année uniquement.
Romain G

1
Il existe maintenant une solution native pour cela - l' API Intl . Alors que moment.js était une excellente bibliothèque à l'époque, il existe actuellement des alternatives beaucoup plus petites ( dayjs , date-fns ). Le moment est énorme ; veuillez ne pas le recommander pour les applications clientes.
Dan Dascalescu

43

J'ai écrit une fonction dans mon projet, qui renvoie le fuseau horaire au hh:mmformat. J'espère que cela peut aider quelqu'un:

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

Violon de travail


1
Je vous remercie! Voilà ce dont j'avais besoin!
Jeremy Moritz

15

Une ligne unique qui donne à la fois le décalage et le fuseau horaire consiste à simplement appeler toTimeString () sur un nouvel objet Date. De MDN:

La toTimeString()méthode renvoie la partie heure d'un objet Date sous une forme lisible par l'homme en anglais américain.

Le hic, c'est que le fuseau horaire n'est pas au format IANA standard; il est un peu plus convivial que le format IANA "continent / ville" . Essaye le:

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

En Californie en ce moment, toTimeString()revient Pacific Daylight Timetandis que l'API Intl revient America/Los_Angeles. En Colombie, vous auriez Colombia Standard Time, contre America/Bogota.

Notez que de nombreuses autres réponses à cette question tentent d'obtenir les mêmes informations en appelant Date.toString (). Cette approche n'est pas aussi fiable que explique MDN :

Les instances de date font référence à un moment précis. L'appel à toString () renverra la date formatée sous une forme lisible par l'homme en anglais américain. [...] Parfois, il est souhaitable d'obtenir une chaîne de temps; une telle chose peut être accomplie avec la toTimeString()méthode.

La toTimeString()méthode est particulièrement utile car les moteurs conformes implémentant ECMA-262 peuvent différer dans la chaîne obtenue à partir toString()des Dateobjets, car le format dépend de l'implémentation; les approches de découpage de chaîne simples peuvent ne pas produire des résultats cohérents sur plusieurs moteurs.


13

essai getTimezoneOffset()de l' Dateobjet:

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

Cette méthode renvoie le décalage horaire en minutes, qui est la différence entre l'heure GMT et l'heure locale en minutes.


9

JavaScript:

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


3
Qu'est-ce que cette réponse apporte aux réponses précédentes?
Dan Dascalescu

7

Avec moment.js :

moment().format('zz');

6
zet zzont été dépréciés à partir du 1.6.0 voir momentjs.com/docs/#/displaying/format
MrUpsidown

3
@MrUpsidown c'est maintenant ZetZZ
brauliobo

4
@brauliobo Ces paramètres ne renvoient pas la même chose. z et zz ont renvoyé le fuseau horaire, par exemple CST, mais Z et ZZ retournent le décalage, par exemple -0600.
Luca Spiller

La dernière émission de documents .zoneAbbr()a remplacé zet zz. Voir la documentation ici
tabish89

1
Alors que moment.js était une excellente bibliothèque à l'époque, il existe actuellement des alternatives beaucoup plus petites ( dayjs , date-fns ). Le moment est énorme ; veuillez ne pas le recommander pour les applications clientes.
Dan Dascalescu

6

Avec , vous pouvez trouver le fuseau horaire actuel

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>


Avec , vous pouvez trouver le fuseau horaire actuel

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>

Les deux API renvoient le décalage utc en quelques minutes.


Alors que moment.js était une excellente bibliothèque à l'époque, il existe actuellement des alternatives beaucoup plus petites ( dayjs , date-fns ). Le moment est énorme ; veuillez ne pas le recommander pour les applications clientes.
Dan Dascalescu

1
"Avec dayjs, vous pouvez trouver le fuseau horaire actuel car" n'est pas exactement précis - vous ne trouverez que le décalage, pas le fuseau horaire . De plus, Dayjs ne prend pas en charge le fuseau horaire . Sa méthode .utcOffset () est un simple wrapper sur le natif getTimezoneOffset().
Dan Dascalescu

4

Fuseau horaire en heures-

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

Si vous voulez être précis comme vous l'avez mentionné dans le commentaire, alors vous devriez essayer comme ça-

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


Ne fonctionne pas pour les fuseaux horaires quand ce n'est pas une heure complète, comme le Venezuela, où il renvoie GMT-4.5
Mirko

Oui, c'est correcte. 0,5 signifie 0,5 * 30 minutes. Je pense que vous avez compris pourquoi il donne 0,5?
Abrar Jahin

oui, donc GMT-4.5 n'est pas un fuseau horaire valide, il a besoin d'un peu d'analyse supplémentaire pour devenir GMT-4: 30
Mirko

@Mirko maintenant la deuxième partie de la réponse est pour vous
Abrar Jahin

Si vous voulez être plus précis, utilisez UTC au lieu de GMT, [Hilton et McCarthy 2013, p. 231–2. ], voir aussi sur wikipedia GMT - ( en.wikipedia.org/wiki/Greenwich_Mean_Time )
Tom Kuschel

3

Si vous n'avez besoin que de l'abréviation du fuseau horaire "MST" ou "EST":

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

L'utilisation Date.toString()n'est pas fiable et MDN explique pourquoi. J'ai collé la section pertinente de leurs documents dans ma réponse .
Dan Dascalescu

3

Voir cet opérateur résultant était opposé au fuseau horaire. Donc, appliquez une fonction mathématique puis validez le nombre moins ou plus.

entrez la description de l'image ici

Voir le document MDN

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

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

console.log(res)


1
en cas de valeur négative, un problème
Arun Prasad ES

1
Pourquoi round? Ça devrait l'être floor, non?
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;
}

Exemple: jeu 21 juin 2018 18:12:50 GMT + 0530 (heure standard de l'Inde)

O / P: +0530


L'utilisation Date.toString()n'est pas fiable et MDN explique pourquoi. J'ai collé la section pertinente de leurs documents dans ma réponse .
Dan Dascalescu


2

Cette valeur provient de la machine de l'utilisateur et peut être modifiée à tout moment, donc je pense que cela n'a pas d'importance, je veux juste obtenir une valeur approximative puis la convertir en GMT sur mon serveur.

Par exemple, je viens de Taïwan et cela me renvoie "+8".

Exemple de travail

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>

Résultat

+8

2

Sur le new Date(), vous pouvez obtenir le décalage, pour obtenir le nom du fuseau horaire, vous pouvez faire:

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

vous obtenez la valeur entre ()à la fin de la date, c'est le nom du fuseau horaire.


L'utilisation Date.toString()n'est pas fiable et MDN explique pourquoi. J'ai collé la section pertinente de leurs documents dans ma réponse . De plus, cette réponse a déjà été donnée au moins 3 fois.
Dan Dascalescu

2

Ce serait ma solution:


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

1

Comme alternative à new Date().getTimezoneOffset()etmoment().format('zz') , vous pouvez également utiliser:

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 est également assez bogué et non entretenu ( https://bitbucket.org/pellepim/jstimezonedetect/issues?status=new&status=open )


Alors que moment.js était une excellente bibliothèque à l'époque, il existe actuellement des alternatives beaucoup plus petites ( dayjs , date-fns ). Le moment est énorme ; veuillez ne pas le recommander pour les applications clientes.
Dan Dascalescu

1

Utilisez ceci pour convertir OffSet en postive:

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

-2

Je cherchais juste la chaîne de 3 lettres (comme "PDT") et j'ai essayé la réponse de Marquez mais j'ai dû l'ajuster un peu pour la prise en charge de plusieurs navigateurs. Heureusement, la chaîne est le dernier match potentiel :)

Voici ce que j'ai fait, dans CoffeeScript:

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

Fonctionne dans IE8, IE9, Safari 9, Firefox 44 et Chrome 48


2
Il existe cependant des fuseaux horaires avec 4 lettres - attention: CEST par exemple (heure d'été d'Europe centrale)
jbrosi

L'utilisation Date.toString()n'est pas fiable et MDN explique pourquoi. J'ai collé la section pertinente de leurs documents dans ma réponse .
Dan Dascalescu

-3

Il vous suffit d'inclure moment.js et 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>

et après ça

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

</script>

-3

C'est un très bon travail pour moi:

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

1
Une explication?

-4

vous pouvez simplement essayer ceci. il vous renverra l'heure actuelle de la machine

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


Voici comment procéder, je pense: new Date(new Date().getTime()); cela afficherait: "Ven 28 déc 2018 10:15:23 GMT + 0100 (heure normale d'Europe centrale) {}"
darmis

-4

Cela fera l'affaire.


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

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

indéfini

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.