Caso uno:
new Date(Date.parse("Jul 8, 2005"));
Salida:
Vie 08 de julio 2005 00:00:00 GMT-0700 (PST)
Caso dos:
new Date(Date.parse("2005-07-08"));
Salida:
Jue 07 jul 2005 17:00:00 GMT-0700 (PST)
¿Por qué es incorrecto el segundo análisis?
javascript
date
usuario121196
fuente
fuente
NaN
en Firefox, descubrí que la mayoría de los otros navegadores (y Node.js) analizarán una fecha sin un día, como "abril de 2014" como el 1 de abril de 2014, pero Firefox devuelve NaN. Debes pasar una fecha adecuada.Respuestas:
Hasta que salió la especificación de la quinta edición, el
Date.parse
método era completamente dependiente de la implementación (new Date(string)
es equivalente aDate.parse(string)
excepto que este último devuelve un número en lugar de un aDate
). En la especificación de la quinta edición, el requisito se agregó para admitir un ISO-8601 simplificado (y ligeramente incorrecto) (consulte también ¿Qué son las cadenas de fecha y hora válidas en JavaScript? ). Pero aparte de eso, no había ninguna necesidad de lo queDate.parse
/new Date(string)
debe aceptar distinta de la que tenían que aceptar lo queDate#toString
la salida (sin decir lo que era).A partir de ECMAScript 2017 (edición 8), se requirió que las implementaciones analizaran su salida para
Date#toString
yDate#toUTCString
, pero no se especificó el formato de esas cadenas.A partir de ECMAScript 2019 (edición 9), el formato para
Date#toString
yDate#toUTCString
, se ha especificado como (respectivamente):por ejemplo, martes 10 de julio de 2018 18:39:58 GMT + 0530 (IST)
ej. Martes 10 jul 2018 13:09:58 GMT
proporcionando 2 formatos más que
Date.parse
deberían analizarse de manera confiable en nuevas implementaciones (señalando que el soporte no es ubicuo y que las implementaciones no conformes seguirán en uso durante algún tiempo).Recomendaría que las cadenas de fecha se analicen manualmente y el constructor de fecha se use con argumentos de año, mes y día para evitar la ambigüedad:
fuente
Date.parse
no me estaba comportando con los formatos de fecha del Reino Unido por alguna razón que no pude resolverreturn new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);
Funciona perfectamente, ¡gracias!Durante la experiencia reciente escribiendo un intérprete de JS luché mucho con el funcionamiento interno de las fechas de ECMA / JS. Entonces, supongo que arrojaré mis 2 centavos aquí. Espero que compartir estas cosas ayude a otros con cualquier pregunta sobre las diferencias entre los navegadores en cómo manejan las fechas.
El lado de entrada
Todas las implementaciones almacenan sus valores de fecha internamente como números de 64 bits que representan la cantidad de milisegundos (ms) desde 1970-01-01 UTC (GMT es lo mismo que UTC). Esta fecha es la época de ECMAScript que también utilizan otros lenguajes como los sistemas Java y POSIX como UNIX. Las fechas que ocurren después de la época son números positivos y las fechas anteriores son negativas.
El siguiente código se interpreta como la misma fecha en todos los navegadores actuales, pero con el desplazamiento de la zona horaria local:
En mi zona horaria (EST, que es -05: 00), el resultado es 18000000 porque esa es la cantidad de ms en 5 horas (son solo 4 horas durante los meses de verano). El valor será diferente en diferentes zonas horarias. Este comportamiento se especifica en ECMA-262, por lo que todos los navegadores lo hacen de la misma manera.
Si bien existe una cierta variación en los formatos de cadena de entrada que los principales navegadores analizarán como fechas, esencialmente los interpretan de la misma manera en lo que respecta a las zonas horarias y al horario de verano, aunque el análisis depende en gran medida de la implementación.
Sin embargo, el formato ISO 8601 es diferente. Es uno de los dos únicos formatos descritos en ECMAScript 2015 (ed. 6) específicamente que todas las implementaciones deben analizar de la misma manera (el otro es el formato especificado para Date.prototype.toString ).
Pero, incluso para las cadenas de formato ISO 8601, algunas implementaciones se equivocan. Aquí hay una salida de comparación de Chrome y Firefox cuando esta respuesta se escribió originalmente para el 1/1/1970 (la época) en mi máquina usando cadenas de formato ISO 8601 que deberían analizarse exactamente con el mismo valor en todas las implementaciones:
Esta diferencia se ha solucionado a partir de 2020, pero existen otras peculiaridades entre los navegadores al analizar cadenas de formato ISO 8601.
Pero se pone peor. Una peculiaridad de ECMA-262 es que se requiere que el formato de fecha ISO 8601 (AAAA-MM-DD) se analice como UTC, mientras que ISO 8601 requiere que se analice como local. Aquí está la salida de FF con los formatos de fecha ISO largos y cortos sin especificador de zona horaria.
Entonces, el primero se analiza como local porque es la fecha y hora ISO 8601 sin zona horaria, y el segundo se analiza como UTC porque es solo la fecha ISO 8601.
Entonces, para responder la pregunta original directamente,
"YYYY-MM-DD"
ECMA-262 requiere que se interprete como UTC, mientras que el otro se interpreta como local. Es por eso:Esto no produce resultados equivalentes:
Esto hace:
La conclusión es esto para analizar cadenas de fechas. La ÚNICA cadena ISO 8601 que puede analizar de forma segura en los navegadores es la forma larga con un desplazamiento (ya sea ± HH: mm o "Z"). Si lo hace, puede ir y venir con seguridad entre la hora local y la hora UTC.
Esto funciona en todos los navegadores (después de IE9):
La mayoría de los navegadores actuales tratan los otros formatos de entrada por igual, incluidos los '1/1/1970' (M / D / AAAA) y '1/1/1970 00:00:00 AM' (M / D / AAAA hh) utilizados con frecuencia. : mm: ss ap) formatos. Todos los siguientes formatos (excepto el último) se tratan como entrada de hora local en todos los navegadores. La salida de este código es la misma en todos los navegadores en mi zona horaria. El último se trata como -05: 00 independientemente de la zona horaria del host porque el desplazamiento se establece en la marca de tiempo:
Sin embargo, dado que el análisis de incluso los formatos especificados en ECMA-262 no es coherente, se recomienda no confiar nunca en el analizador incorporado y analizar siempre las cadenas manualmente, por ejemplo, utilizando una biblioteca y proporcionar el formato al analizador.
Por ejemplo, en moment.js podrías escribir:
El lado de salida
En el lado de salida, todos los navegadores traducen las zonas horarias de la misma manera, pero manejan los formatos de cadena de manera diferente. Aquí están las
toString
funciones y lo que generan. Observe la salidatoUTCString
y lastoISOString
funciones a las 5:00 AM en mi máquina. Además, el nombre de la zona horaria puede ser una abreviatura y puede ser diferente en diferentes implementaciones.Convierte de UTC a hora local antes de imprimir
Imprime la hora UTC almacenada directamente
Normalmente no uso el formato ISO para la entrada de cadenas. El único momento en que usar ese formato es beneficioso para mí es cuando las fechas deben clasificarse como cadenas. El formato ISO se puede ordenar tal cual, mientras que los demás no. Si tiene que tener compatibilidad entre navegadores, especifique la zona horaria o use un formato de cadena compatible.
El código
new Date('12/4/2013').toString()
pasa por la siguiente pseudo-transformación interna:Espero que esta respuesta haya sido útil.
fuente
Hay algún método para la locura. Como regla general, si un navegador puede interpretar una fecha como ISO-8601, lo hará. "2005-07-08" cae en este campamento, por lo que se analiza como UTC. "8 de julio de 2005" no puede, por lo que se analiza en la hora local.
Ver JavaScript y fechas, ¡qué desastre! para más.
fuente
Otra solución es construir una matriz asociativa con formato de fecha y luego reformatear los datos.
Este método es útil para la fecha formateada de manera no usual.
Un ejemplo:
fuente
Use moment.js para analizar fechas:
El tercer argumento determina el análisis estricto (disponible a partir de 2.3.0). Sin él, moment.js también puede dar resultados incorrectos.
fuente
De acuerdo con http://blog.dygraphs.com/2012/03/javascript-and-dates-what-mess.html, el formato "aaaa / mm / dd" resuelve los problemas habituales. Él dice: "Adhiérase a" AAAA / MM / DD "para sus cadenas de fecha siempre que sea posible. Es universalmente compatible y sin ambigüedades. Con este formato, todos los horarios son locales". He establecido pruebas: http://jsfiddle.net/jlanus/ND2Qg/432/ Este formato: + evita la ambigüedad del pedido de día y mes mediante el uso de pedidos ymd y un año de 4 dígitos + evita el problema UTC vs. local no cumplir con el formato ISO mediante el uso de barras inclinadas + danvk, el tipo de gráficos , dice que este formato es bueno en todos los navegadores.
fuente
Si bien CMS tiene razón en que pasar cadenas al método de análisis generalmente no es seguro, la nueva especificación ECMA-262 5th Edition (también conocida como ES5) en la sección 15.9.4.2 sugiere que en
Date.parse()
realidad debería manejar las fechas con formato ISO. La antigua especificación no hizo tal afirmación. Por supuesto, los navegadores antiguos y algunos navegadores actuales aún no ofrecen esta funcionalidad ES5.Tu segundo ejemplo no está mal. Es la fecha especificada en UTC, según lo implica
Date.prototype.toISOString()
, pero está representada en su zona horaria local.fuente
Esta biblioteca de análisis de fechas de peso ligero debería resolver todos los problemas similares. Me gusta la biblioteca porque es bastante fácil de extender. También es posible hacerlo (no muy sencillo, pero no tan difícil).
Ejemplo de análisis:
Y formateando de nuevo a cadena (notará que ambos casos dan exactamente el mismo resultado):
fuente
Aquí hay un fragmento corto y flexible para convertir una cadena de fecha y hora de una manera segura para todos los navegadores, como detalla nicel por @ drankin2112.
Su navegador debe proporcionar el mismo resultado de marca de tiempo que
Date.parse
con:fuente
Ambos son correctos, pero se interpretan como fechas con dos zonas horarias diferentes. Entonces comparaste manzanas y naranjas:
Eliminé la
Date.parse()
llamada ya que se usa automáticamente en un argumento de cadena. También comparé las fechas con el formato ISO8601 para que pueda comparar visualmente las fechas entre sus fechas locales y las fechas UTC. Los tiempos están separados por 7 horas, que es la diferencia de zona horaria y por qué sus pruebas mostraron dos fechas diferentes.La otra forma de crear estas mismas fechas locales / UTC sería:
Pero todavía recomiendo Moment.js, que es tan simple pero potente :
fuente
La respuesta aceptada de CMS es correcta, acabo de agregar algunas características:
fuente