JavaScript Création d'une date depuis UTC


Exemple

Par défaut, un objet Date est créé en tant qu'heure locale. Ce n'est pas toujours souhaitable, par exemple lors de la communication d'une date entre un serveur et un client qui ne réside pas dans le même fuseau horaire. Dans ce scénario, on ne veut pas du tout s’inquiéter des fuseaux horaires tant que la date ne doit pas être affichée à l’heure locale, s’il est même nécessaire.

Le problème

Dans ce problème, nous souhaitons communiquer une date spécifique (jour, mois, année) avec une personne dans un fuseau horaire différent. La première implémentation utilise naïvement les heures locales, ce qui entraîne des résultats incorrects. La deuxième implémentation utilise des dates UTC pour éviter les fuseaux horaires là où ils ne sont pas nécessaires.

Approche naïve avec des résultats incorrects

function formatDate(dayOfWeek, day, month, year) {
  var daysOfWeek = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
  var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
  return daysOfWeek[dayOfWeek] + " " + months[month] + " " + day + " " + year;
}

//Foo lives in a country with timezone GMT + 1
var birthday = new Date(2000,0,1);
console.log("Foo was born on: " + formatDate(birthday.getDay(), birthday.getDate(),
      birthday.getMonth(), birthday.getFullYear()));

sendToBar(birthday.getTime());

Exemple de sortie: Foo was born on: Sat Jan 1 2000

//Meanwhile somewhere else...

//Bar lives in a country with timezone GMT - 1
var birthday = new Date(receiveFromFoo());
console.log("Foo was born on: " + formatDate(birthday.getDay(), birthday.getDate(),
      birthday.getMonth(), birthday.getFullYear()));

Exemple de production: Foo was born on: Fri Dec 31 1999

Et ainsi, Bar croit toujours que Foo est né le dernier jour de 1999.

Approche correcte

function formatDate(dayOfWeek, day, month, year) {
  var daysOfWeek = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
  var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
  return daysOfWeek[dayOfWeek] + " " + months[month] + " " + day + " " + year;
}

//Foo lives in a country with timezone GMT + 1
var birthday = new Date(Date.UTC(2000,0,1));
console.log("Foo was born on: " + formatDate(birthday.getUTCDay(), birthday.getUTCDate(),
      birthday.getUTCMonth(), birthday.getUTCFullYear()));

sendToBar(birthday.getTime());

Exemple de sortie: Foo was born on: Sat Jan 1 2000

//Meanwhile somewhere else...

//Bar lives in a country with timezone GMT - 1
var birthday = new Date(receiveFromFoo());
console.log("Foo was born on: " + formatDate(birthday.getUTCDay(), birthday.getUTCDate(), 
      birthday.getUTCMonth(), birthday.getUTCFullYear()));

Exemple de sortie: Foo was born on: Sat Jan 1 2000

Création d'une date depuis UTC

Si l'on veut créer un objet Date basé sur UTC ou GMT, la Date.UTC(...) peut être utilisée. Il utilise les mêmes arguments que le constructeur de Date le plus long. Cette méthode renverra un nombre représentant le temps écoulé depuis le 1er janvier 1970 à 00:00:00 UTC.

console.log(Date.UTC(2000,0,31,12));

Sortie de l'échantillon: 949320000000

var utcDate = new Date(Date.UTC(2000,0,31,12));
console.log(utcDate);

Exemple de production: Mon Jan 31 2000 13:00:00 GMT+0100 (West-Europa (standaardtijd))

Sans surprise, la différence entre l'heure UTC et l'heure locale est en fait le décalage du fuseau horaire converti en millisecondes.

var utcDate = new Date(Date.UTC(2000,0,31,12));
var localDate = new Date(2000,0,31,12);

console.log(localDate - utcDate === utcDate.getTimezoneOffset() * 60 * 1000);

Exemple de sortie: true

Changer un objet Date

Tous les modificateurs d'objet Date , tels que setDate(...) et setFullYear(...) ont un équivalent qui prend un argument à l'heure UTC plutôt qu'à l'heure locale.

var date = new Date();
date.setUTCFullYear(2000,0,31);
date.setUTCHours(12,0,0,0);
console.log(date);

Exemple de production: Mon Jan 31 2000 13:00:00 GMT+0100 (West-Europa (standaardtijd))

Les autres modificateurs spécifiques à UTC sont .setUTCMonth() , .setUTCDate() (pour le jour du mois), .setUTCMinutes() , .setUTCSeconds() et .setUTCMilliseconds() .

Éviter toute ambiguïté avec getTime () et setTime ()

Lorsque les méthodes ci-dessus sont nécessaires pour différencier les ambiguïtés dans les dates, il est généralement plus facile de communiquer une date comme étant le temps écoulé depuis le 1er janvier 1970 à 00:00:00 UTC. Ce numéro unique représente un seul point dans le temps et peut être converti en heure locale si nécessaire.

var date = new Date(Date.UTC(2000,0,31,12));
var timestamp = date.getTime();
//Alternatively
var timestamp2 = Date.UTC(2000,0,31,12);
console.log(timestamp === timestamp2);

Exemple de sortie: true

//And when constructing a date from it elsewhere...
var otherDate = new Date(timestamp);

//Represented as an universal date
console.log(otherDate.toUTCString());
//Represented as a local date
console.log(otherDate);

Sortie de l'échantillon:

Mon, 31 Jan 2000 12:00:00 GMT
Mon Jan 31 2000 13:00:00 GMT+0100 (West-Europa (standaardtijd))