2012-05-31 26 views
58

Sto provando a convertire Twitter datetime in una iso-stringa locale (per prettyDate) ora per 2 giorni. Non sto ottenendo il diritto ora locale ..javascript toISOString() ignora l'offset del fuso orario

im utilizzando la seguente funzione:

function getLocalISOTime(twDate) { 
    var d = new Date(twDate); 
    var utcd = Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), 
     d.getMinutes(), d.getSeconds(), d.getMilliseconds()); 

    // obtain local UTC offset and convert to msec 
    localOffset = d.getTimezoneOffset() * 60000; 
    var newdate = new Date(utcd + localOffset); 
    return newdate.toISOString().replace(".000", ""); 
} 

in NewDate tutto è ok ma il toISOString() getta indietro al tempo originale di nuovo ... Qualcuno può aiutarmi a ottenere l'ora locale in iso dal formato Twitter come: Thu, 31 maggio 2012 08:33:41 +0000

+2

Il formato si descrive alla fine non è il formato [ISO-8601E] (http://dotat.at/tmp/ISO_8601-2004_E.pdf) (vedi anche [Date.toISOString] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/toISOString) .Puoi ottenere il formato che desideri abbastanza facilmente, è molto simile a quello che ottieni con 'dateObj.toString()'. Prova a giocare con quello. – Zirak

+0

Grazie! Finito con questo: var d = new Date (twDate); return new Date (d.toISOString(). replace ("Z", "-02: 00")). toISO String(). Replace (".000", ""); Non è la soluzione più carina ma funziona per il mio fuso orario. –

+0

possibile duplicato di [Esiste un modo per produrre questa rappresentazione della data della stringa (con fuso orario) senza utilizzare le funzioni di sottostringa javascript o regex?] (Http://stackoverflow.com/questions/14992051/is-there-any-way -to-produrre-questa-stringa-data-rappresentazione-con-time-zone-wit) – Bergi

risposta

117

moment.js è ottimo ma a volte non si desidera estrarre un gran numero di dipendenze per le cose semplici.

Le seguenti opere così:

var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds 
var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, -1); 
// => '2015-01-26T06:40:36.181' 

Il slice(0, -1) si libera del trailing Z che rappresenta Zulu fuso orario e può essere sostituito da soli.

+4

breve e semplice - geniale! Per renderlo ancora più leggibile, ho messo .toISOString(). Slice (0, -5) .replace ("T", ""); alla fine della tua soluzione. – DerWOK

+2

I tempi sono espressi in UTC (Coordinated Universal Time), con un designatore UTC speciale ("Z"). –

+1

Eccellente, grazie. Eccolo, come funzione che accetta un parametro data opzionale: function localISOTime (d) { if (! D) d = new Date() var tzoffset = d.getTimezoneOffset() * 60000; // offset in millisecondi return (new Date (Date.now() - tzoffset)). toISOString(). slice (0, -1); } – Nico

6

momento.js FTW !!!

Basta convertire la data per un momento e manipolare come più vi preghiamo:

var d = new Date(twDate); 
var m = moment(d).format(); 
console.log(m); 

http://momentjs.com/docs/

+0

Questa non è una risposta corretta ...Puoi dare la risposta giusta usando Moment.js? Se questa è una risposta vera, posso rispondere ogni volta "x86 FTW !!! https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures- software-developer-instruction-set-reference-manual-325383.pdf "e buona fortuna ... – DestyNova

+0

[* Quando" use jQuery "non è una risposta valida a una domanda JavaScript? *] (https: // meta. stackoverflow.com/questions/335328/when-is-use-jquery-not-a-valid-answer-to-a-javascript-question) – RobG

5

Questa funzione data sotto raggiunge l'effetto desiderato senza una libreria di script aggiuntivo. Fondamentalmente si tratta di una semplice concatenazione di componenti data nel giusto formato e di un prototipo dell'oggetto Date.

Date.prototype.dateToISO8601String = function() { 
    var padDigits = function padDigits(number, digits) { 
     return Array(Math.max(digits - String(number).length + 1, 0)).join(0) + number; 
    } 
    var offsetMinutes = this.getTimezoneOffset(); 
    var offsetHours = offsetMinutes/60; 
    var offset= "Z";  
    if (offsetHours < 0) 
     offset = "-" + padDigits(offsetHours.replace("-","") + "00",4); 
    else if (offsetHours > 0) 
     offset = "+" + padDigits(offsetHours + "00", 4); 

    return this.getFullYear() 
      + "-" + padDigits((this.getUTCMonth()+1),2) 
      + "-" + padDigits(this.getUTCDate(),2) 
      + "T" 
      + padDigits(this.getUTCHours(),2) 
      + ":" + padDigits(this.getUTCMinutes(),2) 
      + ":" + padDigits(this.getUTCSeconds(),2) 
      + "." + padDigits(this.getUTCMilliseconds(),2) 
      + offset; 

} 

Date.dateFromISO8601 = function(isoDateString) { 
     var parts = isoDateString.match(/\d+/g); 
     var isoTime = Date.UTC(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]); 
     var isoDate = new Date(isoTime); 
     return isoDate;  
} 

function test() { 
    var dIn = new Date(); 
    var isoDateString = dIn.dateToISO8601String(); 
    var dOut = Date.dateFromISO8601(isoDateString); 
    var dInStr = dIn.toUTCString(); 
    var dOutStr = dOut.toUTCString(); 
    console.log("Dates are equal: " + (dInStr == dOutStr)); 
} 

Usage:

var d = new Date(); 
console.log(d.dateToISO8601String()); 

Speriamo che questo aiuta qualcun altro.

EDIT

Corretto problema UTC accennato nei commenti, e il credito al Alex per la funzione dateFromISO8601.

+0

questo mi ha aiutato e penso che sia una risposta migliore. – Jonathan

+1

Mentre stai ricevendo l'ora locale corretta, stai associando erroneamente quel tempo al tempo zulu aggiungendo la "Z" al posto del fuso orario. Se dovessi prendere il tempo creato da questo e inserirlo in qualsiasi applicazione conforme ISO, non * riceverai * l'ora esatta in cambio. Dovresti chiamare '.getTimezoneOffset()' e quindi calcolare i minuti in un formato di ore al posto di quello in modo che la tua data ISO sia conforme. –

+0

questo è sbagliato e non funziona Impaurito –

26

La mia soluzione senza utilizzare momento è quello di convertirlo in un timestamp, aggiungere l'offset fuso orario, poi convertire indietro a un oggetto data, e quindi eseguire il toISOString()

var date = new Date(); // Or the date you'd like converted. 
isoDate = new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString(); 
+1

Mi piace questo approccio. L'esempio non funziona così com'è perché non hai definito la data. Se anteponi var date = new Date(); per il tuo esempio, funziona. – Brady