JavaScript Creazione di una data da UTC


Esempio

Per impostazione predefinita, un oggetto Date viene creato come ora locale. Ciò non è sempre auspicabile, ad esempio quando si comunica una data tra un server e un client che non risiedono nello stesso fuso orario. In questo scenario, non ci si deve preoccupare affatto dei fusi orari finché non è necessario visualizzare la data nell'ora locale, se è addirittura necessario.

Il problema

In questo problema vogliamo comunicare una data specifica (giorno, mese, anno) con qualcuno in un fuso orario diverso. La prima implementazione utilizza in modo ingenuo le ore locali, il che si traduce in risultati errati. La seconda implementazione utilizza le date UTC per evitare i fusi orari in cui non sono necessari.

Approccio ingenuo con risultati WRONG

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());

Esempio di output: 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()));

Esempio di produzione: Foo was born on: Fri Dec 31 1999

E così, Bar avrebbe sempre creduto che Foo fosse nato l'ultimo giorno del 1999.

Approccio corretto

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());

Esempio di output: 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()));

Esempio di output: Foo was born on: Sat Jan 1 2000

Creazione di una data da UTC

Se si desidera creare un oggetto Date basato su UTC o GMT, è possibile utilizzare il Date.UTC(...) . Utilizza gli stessi argomenti del costruttore di Date più lungo. Questo metodo restituirà un numero che rappresenta il tempo trascorso dal 1 ° gennaio 1970 alle 00:00:00 UTC.

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

Uscita campione: 949320000000

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

Risultati del campione: Mon Jan 31 2000 13:00:00 GMT+0100 (West-Europa (standaardtijd))

Non sorprende che la differenza tra ora UTC e ora locale sia, in effetti, l'offset del fuso orario convertito in millisecondi.

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

Esempio di output: true

Modifica di un oggetto Date

Tutti i modificatori di oggetti Date , come setDate(...) e setFullYear(...) hanno un equivalente, accetta un argomento in ora UTC piuttosto che in ora locale.

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

Risultati del campione: Mon Jan 31 2000 13:00:00 GMT+0100 (West-Europa (standaardtijd))

Gli altri modificatori specifici per UTC sono .setUTCMonth() , .setUTCDate() (per il giorno del mese), .setUTCMinutes() , .setUTCSeconds() e .setUTCMilliseconds() .

Evitare ambiguità con getTime () e setTime ()

Laddove i metodi di cui sopra sono necessari per distinguere tra ambiguità nelle date, di solito è più semplice comunicare una data come la quantità di tempo trascorso dal 1 ° gennaio 1970 alle 00:00:00 UTC. Questo singolo numero rappresenta un singolo punto nel tempo e può essere convertito all'ora locale ogni volta che è necessario.

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

Esempio di output: 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);

Uscita di esempio:

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