2010-04-04 23 views
224

Tengo un objeto Date. ¿Cómo represento la parte title del siguiente fragmento?¿Cómo puedo exportar una cadena con formato ISO 8601 en JavaScript?

<abbr title="2010-04-02T14:12:07">A couple days ago</abbr> 

que tienen el "tiempo relativo en las palabras" parte de otra biblioteca.

He intentado lo siguiente:

function isoDate(msSinceEpoch) { 

    var d = new Date(msSinceEpoch); 
    return d.getUTCFullYear() + '-' + (d.getUTCMonth() + 1) + '-' + d.getUTCDate() + 'T' + 
      d.getUTCHours() + ':' + d.getUTCMinutes() + ':' + d.getUTCSeconds(); 

} 

Pero eso me da:

"2010-4-2T3:19" 

Respuesta

398

Ya existe una función llamada toISOString():

var date = new Date(); 
date.toISOString(); //"2011-12-19T15:28:46.493Z" 

Si, de alguna manera, estás en a browser que no lo soporta, tengo todo cubierto:

if (!Date.prototype.toISOString) { 
    (function() { 

    function pad(number) { 
     var r = String(number); 
     if (r.length === 1) { 
     r = '0' + r; 
     } 
     return r; 
    } 

    Date.prototype.toISOString = function() { 
     return this.getUTCFullYear() 
     + '-' + pad(this.getUTCMonth() + 1) 
     + '-' + pad(this.getUTCDate()) 
     + 'T' + pad(this.getUTCHours()) 
     + ':' + pad(this.getUTCMinutes()) 
     + ':' + pad(this.getUTCSeconds()) 
     + '.' + String((this.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5) 
     + 'Z'; 
    }; 

    }()); 
} 
+1

.toISOString() definitivamente devuelve la fecha en UTC? – JonWells

+3

No en todos los navegadores, como se indica: http://kangax.github.com/es5-compat-table/ – Alastair

+0

'new Date (" xx "). ToISOString()' produce 'NaN-NaN-NaNTNaN: NaN: NaN .NZ' La implementación nativa arroja RangeException. –

3

Hay un '+' desaparecidos después de la 'T'

isoDate: function(msSinceEpoch) { 
    var d = new Date(msSinceEpoch); 
    return d.getUTCFullYear() + '-' + (d.getUTCMonth() + 1) + '-' + d.getUTCDate() + 'T' 
     + d.getUTCHours() + ':' + d.getUTCMinutes() + ':' + d.getUTCSeconds(); 
} 

Deberías hacerlo.

Para los ceros a la izquierda que podría utilizar esto desde here:

function PadDigits(n, totalDigits) 
{ 
    n = n.toString(); 
    var pd = ''; 
    if (totalDigits > n.length) 
    { 
     for (i=0; i < (totalDigits-n.length); i++) 
     { 
      pd += '0'; 
     } 
    } 
    return pd + n.toString(); 
} 

Usando esta manera:

PadDigits(d.getUTCHours(),2) 
+0

gran captura! Sin embargo, no aborda los "0" faltantes. –

+1

Escribe una función para convertir un número entero en una cadena de 2 caracteres (anteponiendo un '0' si el argumento es menor que 10), y llámalo para cada parte de la fecha/hora. – dan04

61

Ver el último ejemplo en pag e https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference:Global_Objects:Date:

/* Use a function for the exact format desired... */ 
function ISODateString(d) { 
    function pad(n) {return n<10 ? '0'+n : n} 
    return d.getUTCFullYear()+'-' 
     + pad(d.getUTCMonth()+1)+'-' 
     + pad(d.getUTCDate())+'T' 
     + pad(d.getUTCHours())+':' 
     + pad(d.getUTCMinutes())+':' 
     + pad(d.getUTCSeconds())+'Z' 
} 

var d = new Date(); 
console.log(ISODateString(d)); // Prints something like 2009-09-28T19:03:12Z 
+0

El ejemplo proporcionado por el OP ('' no tiene zona horaria. Tal vez querían la hora local, ¿cuál tendría sentido para una cadena de tiempo UI? –

12

Si no es necesario para apoyar IE7, el siguiente es un grande, truco concisa:

JSON.parse(JSON.stringify(new Date())) 
+0

para IE7 esta decisión también se ajusta si se incluyó json3-library (http://bestiejs.github.io/json3). Gracias :) – vladimir77

+0

También falla en IE8. ("'JSON' no está definido") –

+0

El viaje de ida y vuelta a través de JSON es feo, especialmente si su objetivo declarado es la concisión; utilice el método 'toJSON' de la fecha en su lugar. 'JSON.stringify' lo está usando debajo de las coberturas de todos modos. –

11

más corta, pero no compatible con Internet   Explorador   8 y versiones anteriores:

new Date().toJSON() 
58

Casi todos los métodos para-ISO en la web cae la información de zona horaria mediante la aplicación de un convertido a la "Z" tiempo ulu (UTC) antes de dar salida a la cadena. La .toISOString() nativa del navegador también elimina la información de la zona horaria.

Esto descarta información valiosa, ya que el servidor, o el destinatario, siempre puede convertir una fecha ISO completa en zulú o en cualquier zona horaria que lo requiera, al tiempo que obtiene la información de zona horaria del remitente.

La mejor solución que he encontrado es utilizar el Moment.js librería javascript y utilizar el siguiente código:

Para obtener la hora actual ISO con la información de zona horaria en milisegundos

now = moment().format("YYYY-MM-DDTHH:mm:ss.SSSZZ") 
// "2013-03-08T20:11:11.234+0100" 

now = moment().utc().format("YYYY-MM-DDTHH:mm:ss.SSSZZ") 
// "2013-03-08T19:11:11.234+0000" 

now = moment().utc().format("YYYY-MM-DDTHH:mm:ss") + "Z" 
// "2013-03-08T19:11:11Z" <- better use the native .toISOString() 

Para obtener la hora ISO de un objeto JavaScript Fecha nativo con información de zona horaria pero sin milisegundos

var current_time = Date.now(); 
moment(current_time).format("YYYY-MM-DDTHH:mm:ssZZ") 

Esto se puede combinar con Date.js para obtener funciones como Date.today(), cuyo resultado se puede pasar al momento.

Una cadena de fecha formateada de esta manera es compiladora JSON, y se presta para ser almacenada en una base de datos. Python y C# parecen gustarle.

+16

No rellene las fechas con personas. Solo usa moment.js y guarda tu cabello. –

+1

en realidad, en Python y DB's resultó ser un dolor. db usa UTC (no es un problema, ya que puedes convertirlo fácilmente al lado del servidor UTC), por lo que si deseas conservar la información de compensación necesitas otro campo. Y Python prefiere el uso de nanosegundos en lugar de los milisegundos de javascript, que suelen ser suficientes y preferibles en segundos sencillos. En python, solo * dateutil.parser.parse * lo analiza correctamente, y para escribir en milisegundos ISO se necesita un "_when = when.strftime ("% Y-% m-% dT% H:% M:% S.% f % z "); return _when [: - 8] + _when [-5:]" para convertir los nanos a millis. eso no es agradable. –

+3

Puedes simplemente omitir el formato como: 'momento (new Date()). Format()'. "A partir de la versión 1.5.0, el formato de momento de llamada sin un formato tendrá como valor predeterminado ... el formato ISO8601' YYYY-MM-DDTHH: mm: ssZ' ". Doc: Desplácese hacia arriba desde http://momentjs.com/docs/#/displaying/fromnow/ – user193130

5

Normalmente no quiero mostrar una fecha UTC ya que a los clientes no les gusta hacer la conversión en su cabeza. Para mostrar un local de fecha ISO, utilizo la función:

function toLocalIsoString(date, includeSeconds) { 
    function pad(n) { return n < 10 ? '0' + n : n } 
    var localIsoString = date.getFullYear() + '-' 
     + pad(date.getMonth() + 1) + '-' 
     + pad(date.getDate()) + 'T' 
     + pad(date.getHours()) + ':' 
     + pad(date.getMinutes()) + ':' 
     + pad(date.getSeconds()); 
    if(date.getTimezoneOffset() == 0) localIsoString += 'Z'; 
    return localIsoString; 
}; 

La función anterior omite compensación de zona horaria información (excepto si la hora local pasa a ser GMT), por lo que utilizar la función de abajo para mostrar lo local desplazamiento en una sola ubicación. También puede añadir su salida con los resultados de la función anterior, si desea mostrar el desplazamiento en todas y cada una:

function getOffsetFromUTC() { 
    var offset = new Date().getTimezoneOffset(); 
    return ((offset < 0 ? '+' : '-') 
     + pad(Math.abs(offset/60), 2) 
     + pad(Math.abs(offset % 60), 2)) 
}; 

toLocalIsoString utiliza pad. Si es necesario, funciona como casi cualquier función de la almohadilla, pero en aras de la exhaustividad esto es lo que yo uso:

// Pad a number to length using padChar 
function pad(number, length, padChar) { 
    if (typeof length === 'undefined') length = 2; 
    if (typeof padChar === 'undefined') padChar = '0'; 
    var str = "" + number; 
    while (str.length < length) { 
     str = padChar + str; 
    } 
    return str; 
} 
23

La pregunta era formato ISO con precisión reducida. Voila:

new Date().toISOString().slice(0, 19) + 'Z' 
// '2014-10-23T13:18:06Z' 

Asumiendo que se desea Z, de lo contrario simplemente omita.

0
function getdatetime() { 
    d = new Date(); 
    return (1e3-~d.getUTCMonth()*10+d.toUTCString()+1e3+d/1) 
     .replace(/1(..)..*?(\d+)\D+(\d+).(\S+).*(...)/,'$3-$1-$2T$4.$5Z') 
     .replace(/-(\d)T/,'-0$1T'); 
} 

me encontré con los conceptos básicos en pila   desbordamiento en alguna parte (creo que era parte de algún otro Pila   golf código de Exchange), y yo lo mejoraron por lo que funciona en internet   Explorador   10 o anterior también. Es feo, pero hace el trabajo bien.

2
function timeStr(d) { 
    return ''+ 
    d.getFullYear()+ 
    ('0'+(d.getMonth()+1)).slice(-2)+ 
    ('0'+d.getDate()).slice(-2)+ 
    ('0'+d.getHours()).slice(-2)+ 
    ('0'+d.getMinutes()).slice(-2)+ 
    ('0'+d.getSeconds()).slice(-2); 
} 
+1

En el modo IE5 tenía que seguir esta ruta ya que todas las otras respuestas aquí usaban funciones que no existen. – Elaskanator

3

El problema con toISOString es que da fecha y hora solo como "Z".

ISO-8601 también define datetime con la diferencia de zona horaria en horas y minutos, en las formas como 2016-07-16T19: 20: 30 + 5: 30 (cuando la zona horaria está adelante UTC) y 2016-07-16T19: 20 : 30-01: 00 (cuando la zona horaria está detrás de UTC).

No creo que sea una buena idea usar otro complemento, moment.js para una tarea tan pequeña, especialmente cuando se puede obtener con unas pocas líneas de código.



    var timezone_offset_min = new Date().getTimezoneOffset(), 
     offset_hrs = parseInt(Math.abs(timezone_offset_min/60)), 
     offset_min = Math.abs(timezone_offset_min%60), 
     timezone_standard; 

    if(offset_hrs < 10) 
     offset_hrs = '0' + offset_hrs; 

    if(offset_min > 10) 
     offset_min = '0' + offset_min; 

    // getTimezoneOffset returns an offset which is positive if the local timezone is behind UTC and vice-versa. 
    // So add an opposite sign to the offset 
    // If offset is 0, it means timezone is UTC 
    if(timezone_offset_min < 0) 
     timezone_standard = '+' + offset_hrs + ':' + offset_min; 
    else if(timezone_offset_min > 0) 
     timezone_standard = '-' + offset_hrs + ':' + offset_min; 
    else if(timezone_offset_min == 0) 
     timezone_standard = 'Z'; 

    // Timezone difference in hours and minutes 
    // String such as +5:30 or -6:00 or Z 
    console.log(timezone_standard); 


Una vez que tenga el desplazamiento en horas y minutos zona horaria, puede anexar a una cadena de fecha y hora.

me escribió una entrada de blog en él: http://usefulangle.com/post/30/javascript-get-date-time-with-offset-hours-minutes

2

que era capaz de conseguir debajo de la salida con muy menos código.

var ps = new Date('2010-04-02T14:12:07') ; 
ps = ps.toDateString() + " " + ps.getHours() + ":"+ ps.getMinutes() + " hrs"; 

Salida:

Fri Apr 02 2010 19:42 hrs 
Cuestiones relacionadas