Existe-t-il un moyen fiable d'obtenir un fuseau horaire à partir du navigateur client? J'ai vu les liens suivants, mais je veux une solution plus robuste.
Regardez ce dépôt pageloom c'est utile
téléchargez jstz.min.js et ajoutez une fonction à votre page html
<script language="javascript">
function getTimezoneName() {
timezone = jstz.determine()
return timezone.name();
}
</script>
et appelez cette fonction depuis votre balise display
Une demi-décennie plus tard, nous avons un moyen intégré pour cela! Pour les navigateurs modernes, j'utiliserais:
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tz);
Ceci retourne une chaîne de fuseau horaire IANA, mais pas le décalage . En savoir plus sur le référence MDN .
Tableau de compatibilité - à compter de mars 2019, fonctionne pour 90% des navigateurs utilisés dans le monde. Ne fonctionne pas sur Internet Explorer .
Souvent, lorsque les gens recherchent des "fuseaux horaires", ce qui suffira sera simplement "décalage UTC". Par exemple, leur serveur est au format UTC + 5 et ils veulent savoir que leur client s'exécute en mode UTC-8 .
En clair, javascript (new Date()).getTimezoneOffset()/60
renverra le nombre actuel d’heures décalées par rapport à UTC.
Il convient de noter un possible "gotcha" dans le signe de la valeur de retour getTimezoneOffset()
((à partir de la documentation MDN)) :
Le décalage de fuseau horaire correspond à 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 situé derrière l’UTC et négatif s’il est avancé. Par exemple, pour le fuseau horaire UTC + 10: 00 (heure normale de l'Est de l'Australie, heure de Vladivostok, heure normale de Chamorro), -600 sera renvoyé.
Cependant, je vous recommande d'utiliser le day.js pour le code Javascript lié à l'heure et à la date. Dans ce cas, vous pouvez obtenir un décalage UTC au format ISO 8601 en exécutant:
> dayjs().format("Z")
"-08:00"
Il convient probablement de mentionner que le client peut facilement falsifier ces informations.
(Remarque: cette réponse était à l'origine recommandée https://momentjs.com/ , mais dayjs est une alternative plus moderne et plus petite.)
Pour l'instant, le meilleur choix est probablement jstz, comme suggéré dans réponse de mbayloon .
Pour être complet, il convient de mentionner qu’il existe une norme sur son chemin: Intl . Vous pouvez déjà le voir dans Chrome:
> Intl.DateTimeFormat().resolvedOptions().timeZone
"America/Los_Angeles"
(Cela ne suit pas réellement la norme, ce qui est une raison de plus de rester avec la bibliothèque)
Voici un jsfiddle
Il fournit l'abréviation du fuseau horaire de l'utilisateur actuel.
Voici l'exemple de code
var tz = jstz.determine();
console.log(tz.name());
console.log(moment.tz.zone(tz.name()).abbr(new Date().getTime()));
J'ai utilisé une approche similaire à celle de Josh Fraser , qui détermine le décalage temporel du navigateur par rapport à l'UTC et s'il reconnaît ou non l'heure d'été (mais quelque peu simplifié à partir de son code):
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();
Lors du chargement, la fonction ClientTZ.getBrowserTZ()
est exécutée et définit:
ClientTZ.UTCoffset
vers le décalage de l'heure du navigateur par rapport à l'UTC en minutes (par exemple, CST est de -360 minutes, ce qui correspond à -6,0 heures à partir de l'heure UTC);ClientTZ.UTCoffsetT
au décalage sous la forme '±hhmmD'
(par exemple, '-0600D'
), où le suffixe est D
pour DST et S
pour standard (non DST) ;ClientTZ.hasDST
(à vrai ou faux).Le ClientTZ.UTCoffset
est fourni en minutes au lieu de plusieurs heures, car certains fuseaux horaires ont des décalages horaires fractionnaires (par exemple, +0415).
Le but de ClientTZ.UTCoffsetT
est de l’utiliser comme clé dans une table de fuseaux horaires (non fournie ici), comme pour une liste déroulante <select>
.
vous pouvez utiliser moment-fuseau horaire pour deviner le fuseau horaire:
> moment.tz.guess()
"America/Asuncion"