Pregunta ¿Cuál es la diferencia entre la nueva fecha ("2017-01-01") y la nueva fecha ("2017-1-1")? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Yo ingreso new Date("2017-01-01") en la consola de Chrome, la salida muestra que su hora es 8, pero new Date("2017-01-1") y new Date("2017-1-01") muestra que su hora son ambas 0, entonces ¿cómo new Date(dateString) ¿analizar gramaticalmente?

new Date("2017-01-01")
// Sun Jan 01 2017 08:00:00 GMT+0800 (中国标准时间)*
new Date("2017-01-1")
// Sun Jan 01 2017 00:00:00 GMT+0800 (中国标准时间)*
new Date("2017-1-1")
// Sun Jan 01 2017 00:00:00 GMT+0800 (中国标准时间)*
new Date("2017-1-01")
// Sun Jan 01 2017 00:00:00 GMT+0800 (中国标准时间)*

74
2018-03-28 03:23


origen


Respuestas:


"2017-01-01" sigue el Estándar ISO  Formato de cadena de fecha y hora ES5 (simplificación del formato extendido ISO 8601), y por lo tanto es en hora UTC, que es 8am en China. Todas las demás cadenas se analizan como hora local en Chrome1.


1 Código fuente relevante en Chromium: https://cs.chromium.org/chromium/src/v8/src/dateparser-inl.h?type=cs&l=16

El análisis de la fecha en Chromium sigue las reglas estándar de ES5, así como estas reglas adicionales:

  • Cualquier palabra no reconocida antes del primer número se ignora.
  • El texto entre paréntesis se ignora.
  • Un número sin firmar seguido de : es un valor de tiempo, y se agrega a la TimeComposer. Un número seguido por :: agrega un segundo cero también. Un número seguido por . también es un tiempo y debe ser seguido por milisegundos. Cualquier otro número es un componente de fecha y se agrega a DayComposer.
  • El nombre de un mes (o realmente: cualquier palabra que tenga las mismas tres primeras letras que el nombre de un mes) se registra como un mes con nombre en el Day compositor.
  • Una palabra reconocible como zona horaria se registra como tal, como (+|-)(hhmm|hh:).
  • Las fechas heredadas no permiten signos adicionales (+ o -) o sin igual ) después de haber leído un número (antes del primer número, se permite cualquier basura).
  • Cualquier cadena que satisfaga las reglas de ES5 y las reglas anteriores se analizará utilizando las reglas de ES5. Esto significa "1970-01-01" estará en la zona horaria UTC no en la zona horaria local.

Qué significa eso?

Primero tenga en cuenta que "2017-01-01" se analiza en tiempo UTC porque es una cadena de "fecha" en lugar de una cadena de "fecha y hora", y coincide con la definición de ES5 de una cadena de "fecha". Si se le asigna tiempo, entonces seguirá el estándar ISO y lo analizará en tiempo local.

Ejemplos:

  • 2017-01-01 - 1 de enero de 2017 en horario UTC
  • 2017-01-01T00:00 - 1 de enero de 2017 en horario local
  • 2017-1-1 - 1 de enero de 2017 en horario local
  • 2017-(hello)01-01 - 1 de enero de 2017 en horario local
  • may 2017-01-01 - 1 de mayo de 2017 en horario local
  • mayoooo 2017-01-01 - 1 de mayo de 2017 en horario local
  • "jan2017feb-mar01apr-may01jun" - 1 de junio de 2017 en horario local

77
2018-03-28 03:28



diferencia entre la nueva fecha ("2017-01-01") y la nueva fecha ("2017-1-1")

new Date("2017-01-01") está dentro de la especificación (más abajo). new Date("2017-1-1") no es, y por lo tanto recurre a cualquier "... heurística específica de implementación o formatos de fecha específicos de implementación" el motor de JavaScript quiere aplicar. Por ejemplo, no tiene garantía de cómo (o si) analizará correctamente y, de ser así, si se analizará como UTC o como hora local.

A pesar de que new Date("2017-01-01") está dentro de especificaciones, lamentablemente lo que se supone que los navegadores deben hacer con él ha sido un objetivo en movimiento, porque no tiene un indicador de zona horaria:

  • En ES5 (Diciembre de 2009), se suponía que las cadenas sin un indicador de zona horaria se analizaran como UTC. Pero eso está en desacuerdo con el estándar ISO-8601 en el que se basa el formato de fecha / hora, que dice que las cadenas sin un indicador de zona horaria están pensadas para ser hora local, no UTC. Entonces en ES5, new Date("2017-01-01")se analiza en UTC.
  • En ES2015 (también conocido como ES6, junio de 2015), se suponía que las cadenas sin un indicador de zona horaria eran hora local, no UTC, como ISO-8601. Entonces en ES2015, new Date("2017-01-01") se analiza como hora local.
  • Pero, eso fue cambiado nuevamente en ES2016 (Junio ​​de 2016) porque los navegadores habían estado analizando formularios de solo - en ellos como UTC durante años. A partir de ES2016, fecha-solo formas (como "2017-01-01") se analizan en UTC, pero fecha y hora formas (como "2017-01-01T00:00:00") son analizados en tiempo local.

Lamentablemente, no todos los motores de JavaScript implementan actualmente la especificación. Chrome (al momento de escribir esto, v56) analiza los formularios de fecha / hora en UTC, aunque deberían ser hora local (igual que IE9). Pero Chrome, Firefox e IE11 (no tengo IE10 o Edge a mano) manejan todos los formularios de fecha correcta (como UTC). IE8 no implementa la forma ISO-8601 en absoluto (se ha lanzado antes de que se liberara la especificación ES5).


18
2018-03-28 03:47



Al analizar fechas, JavaScript interpreta las fechas ISO como hora UTC y otros formatos como hora local.

Como Artículo de MDN sugiere,

Cuando la cadena solo tiene la fecha ISO 8601, la zona horaria UTC se usa para interpretar los argumentos.

Dada una cadena de fecha de "7 de marzo de 2014", el análisis () supone una zona horaria local, pero dado un formato ISO como "2014-03-07" asumirá una zona horaria de UTC (ES5 y ECMAScript 2015). Por lo tanto, los objetos Date producidos con esas cadenas pueden representar momentos diferentes en el tiempo, dependiendo de la versión de ECMAScript compatible, a menos que el sistema esté configurado con un huso horario local de UTC. Esto significa que dos cadenas de fechas que parecen equivalentes pueden dar como resultado dos valores diferentes según el formato de la cadena que se está convirtiendo.

// 2017-03-28 is interpreted as UTC time,
// shown as 2017-03-28 00:00:00 in UTC timezone,
// shown as 2017-03-28 06:00:00 in my timezone:
console.log("ISO dates:");
var isoDates = [new Date("2017-03-28")];
for (var dt of isoDates)
{
  console.log(dt.toUTCString() + " / " + dt.toLocaleString());
}

// Other formats are interpreted as local time, 
// shown as 2017-03-27 18:00:00 in my timezone,
// shown 2017-03-28 00:00:00 in my timezone:
console.log("Other formats:");
var otherDates = [new Date("2017-3-28"), new Date("March 28, 2017"), new Date("2017/03/28")];
for (var dt of otherDates)
{
  console.log(dt.toUTCString() + " / " + dt.toLocaleString());
}


3
2018-03-28 03:32



Este formato es Estándar Internacional (formato ISO)

new Date("2017-01-01")

Esto garantiza el mismo resultado en todos los navegadores.

Sin embargo, los otros formatos pueden cambiar según el navegador, ya que no están bien definidos.

Como puedes ver, este formato

new Date("2017-1-1")

se analiza con éxito en Chrome, pero da error en IE 11


2
2018-03-28 03:31