web-dev-qa-db-fra.com

obtenir le fuseau horaire du client à partir du navigateur

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.

Détection automatique d'un fuseau horaire avec JavaScript

Détection du fuseau horaire en JavaScript

121
confucius

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

82
Georgian Citizen

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 .

131
Wallace

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

65
Chris W.

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)

41
Johannes Hoff

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()));
4
Pushkar Newaskar

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>.

2
David R Tribble

vous pouvez utiliser moment-fuseau horaire pour deviner le fuseau horaire:

> moment.tz.guess()
"America/Asuncion"
2
SummerBreeze