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.
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.
Réponses:
Regardez ce pageloom de référentiel, il 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 tag d'affichage
Intl.DateTimeFormat().resolvedOptions().timeZone
(pas d'IE11) comme suggéré par Wallace.
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);
Cela renvoie une chaîne de fuseau horaire IANA, mais pas le décalage . En savoir plus sur la référence MDN .
Tableau de compatibilité - en mars 2019, fonctionne pour 90% des navigateurs utilisés dans le monde. Ne fonctionne pas sur Internet Explorer .
Intl.DateTimeFormat().resolvedOptions().timeZone
->undefined
Intl.DateTimeFormat().resolvedOptions().timeZone
renverra la valeur attendue à partir de Firefox 52: kangax.github.io/compat-table/esintl/…
Souvent, lorsque les gens recherchent des «fuseaux horaires», ce qui suffit, c'est simplement le «décalage UTC». par exemple, leur serveur est en UTC + 5 et ils veulent savoir que leur client fonctionne en UTC-8 .
En clair, l'ancien javascript (new Date()).getTimezoneOffset()/60
retournera le nombre actuel d'heures de décalage par rapport à UTC.
Il convient de noter un possible "gotcha" dans le signe de la getTimezoneOffset()
valeur de retour (à partir de la documentation MDN) :
Le décalage du 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 en avance. Par exemple, pour le fuseau horaire UTC + 10: 00 (heure normale de l'est de l'Australie, heure de Vladivostok, heure standard de Chamorro), -600 sera renvoyé.
Cependant, je vous recommande d'utiliser le day.js pour le code Javascript lié à l'heure / 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 recommandait à l'origine https://momentjs.com/ , mais dayjs est une alternative plus moderne et plus petite.)
Pour l'instant, le meilleur pari est probablement jstz comme suggéré dans la réponse de mbayloon .
Par souci d'exhaustivité, il convient de mentionner qu'il existe une norme sur son chemin: Intl . Vous pouvez déjà voir cela 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 s'en tenir à la bibliothèque)
Intl
sont censées renvoyer undefined
pour la timeZone
propriété si vous n'avez pas spécifié manuellement de fuseau horaire lors de la construction du fichier DateTimeFormat
. Chrome s'écarte de la norme en renvoyant le fuseau horaire du système à la place; c'est ce que la réponse de Johannes exploite, mais aussi pourquoi il a dit "ne suit pas réellement la norme".
vous pouvez utiliser le fuseau horaire du moment pour deviner le fuseau horaire:
> moment.tz.guess()
"America/Asuncion"
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()));
May 22 2015 03:45 PM CDT
je l'ai utilisée console.log(moment(now).format('MMM DD YYYY hh:mm A') + ' ' + moment.tz.zone(tz.name()).abbr(now.getTime()));
J'ai utilisé une approche similaire à celle adoptée par Josh Fraser , qui détermine le décalage horaire du navigateur par rapport à UTC et s'il reconnaît ou non l'heure d'été (mais quelque peu simplifiée à 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 ClientTZ.getBrowserTZ()
fonction est exécutée, ce qui définit:
ClientTZ.UTCoffset
au décalage horaire du navigateur par rapport à UTC en minutes (par exemple, CST est de -360 minutes, qui est de -6,0 heures de 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 d'heures, car certains fuseaux horaires ont des décalages horaires fractionnaires (par exemple, +0415).
L'intention derrière ClientTZ.UTCoffsetT
est de l'utiliser comme clé dans un tableau de fuseaux horaires (non fourni ici), comme pour une <select>
liste déroulante .
7-1
pour juillet au lieu de juin. Je ne sais pas si cela fait vraiment une différence, car je doute qu'il existe des régimes régionaux d'heure d'été qui n'incluent pas le mois de juin.
Non. Il n'y a pas de moyen fiable unique et il n'y en aura jamais. Pensiez-vous vraiment pouvoir faire confiance au client?