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.

Árvíztűrő tükörfúrógép
la source
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).

NickFitz
la source
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.

Pawel Dubiel
la source
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

Marquez
la source
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))
cryo
la source
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
Sameer Ek
la source
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

Monsieur green
la source
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.

Dan Dascalescu
la source
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.

dfa
la source
9

JavaScript:

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

زياد
la source
3
Qu'est-ce que cette réponse apporte aux réponses précédentes?
Dan Dascalescu
7

Avec moment.js :

moment().format('zz');
kolypto
la source
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/[email protected]/dayjs.min.js"></script>

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

Fizer Khan
la source
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));
}

Abrar Jahin
la source
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;
}
JohnP2
la source
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)

prasanth
la source
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

Chandrakanth Gowda
la source
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

Essaye ça,

new Date().toString().split("GMT")[1].split(" (")[0]
Srinivasan Sekar
la source
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
Terry Lin
la source
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.

Moysés Lacerda
la source
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`);

la source
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 )

brauliobo
la source
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);
Kumal Pereira
la source
-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

ari gold
la source
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>
Dayachand Patel
la source
-3

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

// Translation to offset in Unix Timestamp
let timeZoneOffset = ((new Date().getTimezoneOffset())/60)*3600;
Alexandre
la source
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())

user8066707
la source
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

SysMurff
la source