In che modo ISO 8601 formattare una data con l’offset del fuso orario in JavaScript?

Obiettivo: trovare l’ local time e l’ UTC time offset quindi build l’URL nel seguente formato.

URL di esempio: / Actions / Sleep? Duration = 2002-10-10T12: 00: 00-05: 00

Il formato si basa sulla raccomandazione del W3C: http://www.w3.org/TR/xmlschema11-2/#dateTime

La documentazione dice:

  For example, 2002-10-10T12:00:00−05:00 (noon on 10 October 2002, Central Daylight Savings Time as well as Eastern Standard Time in the US) is equal to 2002-10-10T17:00:00Z, five hours later than 2002-10-10T12:00:00Z. 

Quindi, in base alla mia comprensione, ho bisogno di trovare la mia ora locale con il nuovo Date () quindi utilizzare la funzione getTimezoneOffset () per calcolare la differenza, quindi collegarla alla fine della stringa.

1. Ottenere ora locale con il formato

 var local = new Date().format("yyyy-MM-ddThh:mm:ss"); //today (local time) 

produzione

 2013-07-02T09:00:00 

2.Regolare l’ora UTC in base all’ora

 var offset = local.getTimezoneOffset() / 60; 

produzione

 7 

3. Costruisci URL (solo tempo parte)

 var duration = local + "-" + offset + ":00"; 

produzione:

 2013-07-02T09:00:00-7:00 

L’output sopra indica che l’ora locale è 2013/07/02 9:00 e la differenza rispetto all’ora UTC è 7 ore (UTC è 7 ore prima dell’ora locale)

Finora sembra funzionare ma cosa succede se getTimezoneOffset () restituisce un valore negativo come -120?

Mi chiedo come dovrebbe apparire il formato in questo caso perché non riesco a capire dal documento del W3C. Grazie in anticipo.

Il sotto dovrebbe funzionare correttamente e per tutti i browser (grazie a @MattJohnson per il suggerimento)

 Date.prototype.toIsoString = function() { var tzo = -this.getTimezoneOffset(), dif = tzo >= 0 ? '+' : '-', pad = function(num) { var norm = Math.floor(Math.abs(num)); return (norm < 10 ? '0' : '') + norm; }; return this.getFullYear() + '-' + pad(this.getMonth() + 1) + '-' + pad(this.getDate()) + 'T' + pad(this.getHours()) + ':' + pad(this.getMinutes()) + ':' + pad(this.getSeconds()) + dif + pad(tzo / 60) + ':' + pad(tzo % 60); } var dt = new Date(); console.log(dt.toIsoString()); 

getTimezoneOffset() restituisce il segno opposto del formato richiesto dalle specifiche a cui si fa riferimento.

Questo formato è anche noto come ISO8601 o, più precisamente, come RFC3339 .

In questo formato, UTC è rappresentato con una Z mentre tutti gli altri formati sono rappresentati da un offset da UTC. Il significato è lo stesso di JavaScript, ma l’ordine di sottrazione è invertito, quindi il risultato porta il segno opposto.

Inoltre, non esiste alcun metodo sull’object Date nativo chiamato format , quindi la tua funzione in # 1 avrà esito negativo a meno che tu non stia utilizzando una libreria per ottenere ciò. Fare riferimento a questa documentazione .

Se stai cercando una libreria che possa funzionare direttamente con questo formato, ti consiglio di provare moment.js . In effetti, questo è il formato predefinito, quindi puoi semplicemente fare questo:

 var m = moment(); // get "now" as a moment var s = m.format(); // the ISO format is the default so no parameters are needed // sample output: 2013-07-01T17:55:13-07:00 

Questa è una soluzione cross-browser ben collaudata e ha molte altre utili funzionalità.

Questa è la mia funzione per il fuso orario dei clienti, è leggera e semplice

  function getCurrentDateTimeMySql() { var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, 19).replace('T', ' '); var mySqlDT = localISOTime; return mySqlDT; }