Afficher la date / l'heure au format des paramètres régionaux de l'utilisateur et le décalage horaire

167

Je souhaite que le serveur affiche toujours les dates en UTC dans le HTML et que JavaScript sur le site client le convertisse dans le fuseau horaire local de l'utilisateur.

Bonus si je peux produire dans le format de date locale de l'utilisateur.

kch
la source

Réponses:

165

Il semble que le moyen le plus infaillible de commencer avec une date UTC est de créer un nouvel Dateobjet et d'utiliser les setUTC…méthodes pour le définir à la date / heure souhaitée.

Ensuite, les différentes toLocale…Stringméthodes fourniront une sortie localisée.

Exemple:

// This would come from the server.
// Also, this whole block could probably be made into an mktime function.
// All very bare here for quick grasping.
d = new Date();
d.setUTCFullYear(2004);
d.setUTCMonth(1);
d.setUTCDate(29);
d.setUTCHours(2);
d.setUTCMinutes(45);
d.setUTCSeconds(26);

console.log(d);                        // -> Sat Feb 28 2004 23:45:26 GMT-0300 (BRT)
console.log(d.toLocaleString());       // -> Sat Feb 28 23:45:26 2004
console.log(d.toLocaleDateString());   // -> 02/28/2004
console.log(d.toLocaleTimeString());   // -> 23:45:26

Quelques références:

kch
la source
1
Dans Firefox, toLocateDateString()renvoie quelque chose qui ressemble à «dimanche 12 janvier 2014».
BlueRaja - Danny Pflughoeft
1
Hmm oui, c'est un problème assez grave. L'utilisation de ces méthodes ne fonctionnera pas si vous souhaitez que la date soit la même dans tous les navigateurs. Des alternatives connues?
Josh Mc
6
Version sur une seule ligne de l'initialisation ci-dessus:var d = new Date(Date.UTC(2004,1,29,2,45,26));
m1kael
4
Il peut être utile de considérer que Chrome (à partir de la v35) ne prend pas en compte les paramètres régionaux de l'utilisateur dans les toLocaleString()fonctions.
benno
8
Je suis désolé mais cette méthode ne fonctionne pas sous (je suis en Australie), lorsque j'exécute le code ci-dessus, la date est affichée au format américain. De plus, MDN dit que «les paramètres régionaux utilisés et la forme de la chaîne renvoyée dépendent entièrement de l'implémentation».
tgrrr
65

Pour les nouveaux projets, utilisez simplement moment.js

Cette question est assez ancienne, donc moment.js n'existait pas à ce moment-là, mais pour les nouveaux projets, cela simplifie beaucoup des tâches comme celle-ci.

Il est préférable d' analyser votre chaîne de date à partir de UTC comme suit (créez une chaîne compatible ISO-8601 sur le serveur pour obtenir des résultats cohérents sur tous les navigateurs):

var m = moment("2013-02-08T09:30:26Z");

Maintenant, utilisez simplement mdans votre application, moment.js utilise par défaut le fuseau horaire local pour les opérations d'affichage. Il existe de nombreuses façons de mettre en forme les valeurs de date et d'heure ou d'en extraire des parties.

Vous pouvez même formater un objet moment dans les paramètres régionaux de l'utilisateur comme ceci:

m.format('LLL') // Returns "February 8 2013 8:30 AM" on en-us

Pour transformer un objet moment.js en un fuseau horaire différent (c'est-à-dire ni le fuseau horaire local ni UTC), vous aurez besoin de l' extension de fuseau horaire moment.js . Cette page a aussi quelques exemples, c'est assez simple à utiliser.

theDmi
la source
Comment combinez-vous tout cela? m.utcOffset (offset) .format ('LLL') ne semble pas fonctionner.
bart
Faut - Luxon ou Day.js être maintenant la bibliothèque proposée?
Homer
1
Je suggère d'ajouterFor old projects, just use jQuery
Xenos
Ne fonctionne pas sur Chrome - affiche toujours am / pm même si l'heure est réglée sur 24h dans les paramètres régionaux de l'ordinateur
vir nous
20

Vous pouvez utiliser new Date().getTimezoneOffset()/60pour le fuseau horaire. Il existe également une toLocaleString()méthode pour afficher une date en utilisant les paramètres régionaux de l'utilisateur.

Voici la liste complète: Travailler avec des dates

sauter
la source
toLocaleString est extrêmement peu fiable pour présenter les dates dans le format auquel un utilisateur pourrait s'attendre. Même là où ISO 402 est pris en charge, il est toujours très peu fiable et base le format sur une langue, pas sur une locale.
RobG
@RobG quelle est la solution au lieu de toLocaleString?
user924
@ user924 - vous pouvez utiliser une bibliothèque, il y en a beaucoup à choisir. Le problème avec toLocaleString est que différentes implémentations donnent des résultats différents avec différents niveaux de prise en charge pour différentes langues et régions. Par exemple, la langue par défaut de mon système n'est pas en-US mais le format par défaut de toLocaleString pour certains navigateurs est le format américain, d'autres respectent la langue de mon système. C'est la même chose avec les noms de fuseau horaire, mais en pire car ils ne sont pas du tout standardisés. :-(
RobG
7

Une fois que vous avez construit votre objet de date, voici un extrait de code pour la conversion:

La fonction prend un objet Date au format UTC et une chaîne de format.
Vous aurez besoin d'un Date.strftimeprototype.

function UTCToLocalTimeString(d, format) {
    if (timeOffsetInHours == null) {
        timeOffsetInHours = (new Date().getTimezoneOffset()/60) * (-1);
    }
    d.setHours(d.getHours() + timeOffsetInHours);

    return d.strftime(format);
}
armée simienne
la source
6
d'où viens-tu?
Anuj Pandey
Le réglage des heures a-t-il un effet sur les parties Jour / Date / Année d'un objet Date? Cela ne semble pas.
ChristoKiwi
1
@ ChristoKiwi - la valeur transmise à setHours devrait être un entier et getTimezoneOffset()/60peut renvoyer une fraction (par exemple, un décalage de l'Inde de +05: 30 renverra 5,5). Les décimales sont tronquées. Sinon, le réglage des heures met à jour les autres valeurs (définissez les heures sur 48 et voyez ce qui se passe).
RobG
7

Dans JS, il n'y a pas de moyen simple et multiplateforme pour formater l'heure locale, en dehors de la conversion de chaque propriété comme mentionné ci-dessus.

Voici un hack rapide que j'utilise pour obtenir le YYYY-MM-DD local. Notez qu'il s'agit d'un hack, car la date finale n'aura plus le fuseau horaire correct (vous devez donc ignorer le fuseau horaire). Si j'ai besoin d'autre chose, j'utilise moment.js.

var d = new Date();    
d = new Date(d.getTime() - d.getTimezoneOffset() * 60000)
var yyyymmdd = t.toISOString().slice(0,0); 
// 2017-05-09T08:24:26.581Z (but this is not UTC)

Le d.getTimezoneOffset () renvoie le décalage du fuseau horaire en minutes, et le d.getTime () est en ms, d'où le x 60 000.

Jeremy Chone
la source
1
@VG J'ai ajouté plus d'informations sur l'origine du 60k. J'espère que cette aide.
Jeremy Chone
5

Voici ce que j'ai utilisé dans les projets précédents:

var myDate = new Date();
var tzo = (myDate.getTimezoneOffset()/60)*(-1);
//get server date value here, the parseInvariant is from MS Ajax, you would need to do something similar on your own
myDate = new Date.parseInvariant('<%=DataCurrentDate%>', 'yyyyMMdd hh:mm:ss');
myDate.setHours(myDate.getHours() + tzo);
//here you would have to get a handle to your span / div to set.  again, I'm using MS Ajax's $get
var dateSpn = $get('dataDate');
dateSpn.innerHTML = myDate.localeFormat('F');
marque
la source
4
C'est avec des trucs spécifiques à ASP.NET.
ZiggyTheHamster
Les décalages de fuseau horaire ne sont pas nécessairement même des multiples d'une heure, ils getTimezoneOffset()/60renverront donc souvent une valeur décimale. Cela est particulièrement vrai pour les dates antérieures à 1900, où de nombreux endroits avaient des décalages en minutes et secondes. De plus, les dates javascript sont désormais requises pour prendre en charge les décalages historiques. Par exemple, en 1890, le décalage à Moscou était de +2: 30: 17. Voir Navigateurs, fuseaux horaires, erreur Chrome 67 .
RobG
3

le .getTimezoneOffset() méthode rapporte le décalage du fuseau horaire en minutes, en comptant "vers l'ouest" à partir du fuseau horaire GMT / UTC, ce qui entraîne une valeur de décalage négative par rapport à ce à quoi on est habitué. (Par exemple, l'heure de New York serait de +240 minutes ou +4 heures)

Pour obtenir un décalage de fuseau horaire normal en heures, vous devez utiliser:

var timeOffsetInHours = -(new Date()).getTimezoneOffset()/60

Détail important:
notez que l'heure d'été est prise en compte dans le résultat - donc ce que cette méthode vous donne est vraiment le décalage horaire - et non le décalage horaire géographique réel .

Már Örlygsson
la source
3

Avec la date du code PHP, j'ai utilisé quelque chose comme ça.

function getLocalDate(php_date) {
  var dt = new Date(php_date);
  var minutes = dt.getTimezoneOffset();
  dt = new Date(dt.getTime() + minutes*60000);
  return dt;
}

On peut l'appeler comme ça

var localdateObj = getLocalDate('2015-09-25T02:57:46');
hriziya
la source
La question concernait JavaScript, pas PHP.
pipedreambomb
5
La réponse est en javascript uniquement, il est mentionné en question que la date du serveur est en UTC. donc le serveur peut être dans n'importe quelle langue. donc j'ai répondu pour PHP uniquement
hriziya
3

Jusqu'à présent, je mélange les réponses et j'y ajoute, car je devais les lire toutes et enquêter en plus pendant un certain temps pour afficher une chaîne de date et d'heure de db dans le format de fuseau horaire local d'un utilisateur.

La chaîne datetime provient d'une base de données python / django au format: 2016-12-05T15: 12: 24.215Z

La détection fiable de la langue du navigateur dans JavaScript ne semble pas fonctionner dans tous les navigateurs (voir JavaScript pour détecter la préférence de langue du navigateur ), donc j'obtiens la langue du navigateur du serveur.

Python / Django: envoyer le langage du navigateur de requête comme paramètre de contexte:

language = request.META.get('HTTP_ACCEPT_LANGUAGE')
return render(request, 'cssexy/index.html', { "language": language })

HTML: écrivez-le dans une entrée masquée:

<input type="hidden" id="browserlanguage" value={{ language }}/>

JavaScript: obtenir la valeur de l'entrée cachée, par exemple en-GB, en-US; q = 0.8, en; q = 0.6 / puis prendre la première langue de la liste uniquement via replace et expression régulière

const browserlanguage = document.getElementById("browserlanguage").value;
var defaultlang = browserlanguage.replace(/(\w{2}\-\w{2}),.*/, "$1");

JavaScript: convertir en datetime et le formater:

var options = { hour: "2-digit", minute: "2-digit" };
var dt = (new Date(str)).toLocaleDateString(defaultlang, options);

Voir: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString

Le résultat est (la langue du navigateur est en-gb): 05/12/2016, 14:58

Anja
la source
3

// new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]])
var serverDate = new Date(2018, 5, 30, 19, 13, 15); // just any date that comes from server
var serverDateStr = serverDate.toLocaleString("en-US", {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
})
var userDate = new Date(serverDateStr + " UTC");
var locale = window.navigator.userLanguage || window.navigator.language;

var clientDateStr = userDate.toLocaleString(locale, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric'
});

var clientDateTimeStr = userDate.toLocaleString(locale, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
});

console.log("Server UTC date: " + serverDateStr);
console.log("User's local date: " + clientDateStr);
console.log("User's local date&time: " + clientDateTimeStr);

Sergey
la source
Pour la référence: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… (j'avais besoin de la optionspièce pour mon cas)
Xenos
2

La meilleure solution que j'ai rencontrée est de créer des balises [time display = "llll" datetime = "UTC TIME" /] et d'utiliser javascript (jquery) pour les analyser et les afficher par rapport à l'heure de l'utilisateur.

http://momentjs.com/ Moment.js

affichera bien l'heure.

Daniel
la source
2

Vous pouvez utiliser ce qui suit, qui indique le décalage du fuseau horaire par rapport à GMT en quelques minutes:

new Date().getTimezoneOffset();

Remarque: - cette fonction renvoie un nombre négatif.

Dave
la source
1

getTimeZoneOffset () et toLocaleString sont parfaits pour le travail de base sur les dates, mais si vous avez besoin d'un support de fuseau horaire réel, regardez TimeZone.js de mde .

Il y a quelques autres options discutées dans la réponse à cette question

Temps infini
la source
1

Pour convertir une date en date locale, utilisez la méthode toLocaleDateString ().

var date = (new Date(str)).toLocaleDateString(defaultlang, options);

Pour convertir l'heure en heure locale, utilisez la méthode toLocaleTimeString ().

var time = (new Date(str)).toLocaleTimeString(defaultlang, options);
Codemaker
la source
-12

Je ne sais pas comment utiliser les paramètres régionaux, mais javascript est une technologie côté client.

usersLocalTime = new Date();

aura l'heure et la date du client (comme indiqué par son navigateur, et par extension l'ordinateur sur lequel il est assis). Il devrait être simple d'inclure l'heure du serveur dans la réponse et de faire quelques calculs simples pour deviner le décalage temporel.

japollock
la source