¿Cuáles son las cadenas de fecha y hora válidas en JavaScript?
string date (2)
Entonces, ¿qué formatos de fecha y hora debo usar?
La recomendación general es no usar el analizador incorporado ya que no es confiable, por lo que la respuesta a "debería" es "ninguna". Ver ¿Por qué Date.parse da resultados incorrectos?
Sin embargo, como dice str, probablemente pueda usar el formato especificado en ECMA-262 con una zona horaria:
YYYY-MM-DDTHH:mm:ss.sssZ
o
YYYY-MM-DDTHH:mm:ss.sss±HH:mm
, don No confíes en ningún otro formato.
¿Todos los navegadores soportan los mismos formatos?
No.
¿Cómo manejan Mozilla Firefox, Google Chrome, Microsoft Internet Explorer, Microsoft Edge y Apple Safari las cadenas de fecha y hora?
Diferentemente. Cualquier otra cosa que no sea el formato en ECMA-262 depende de la implementación, y hay errores en el análisis del formato ECMA-262.
¿Qué pasa con Node.js?
Probablemente diferente de nuevo, ver más arriba.
¿Tiene en cuenta el formato de fecha local? Por ejemplo, si vivo en Suiza y el formato de fecha es 30.07.2018, ¿puedo usar la nueva Fecha (''30 .07.2018 '')?
Tal vez. Dado que no es el formato estándar, el análisis depende de la implementación, así que tal vez, tal vez no.
¿Tiene en cuenta la zona horaria local?
Utiliza el desplazamiento de la zona horaria del host donde la cadena se analiza como local y para generar la cadena que se muestra utilizando los tiempos locales. De lo contrario, utiliza UTC (y el valor de tiempo interno es UTC).
¿Cómo puedo obtener una cadena de fecha y hora de un objeto de fecha?
Date.prototype.toString() , o vea ¿Dónde puedo encontrar documentación sobre cómo formatear una fecha en JavaScript?
¿Cómo puedo detectar cadenas de fecha y hora no válidas?
Una de las primeras 3 respuestas here debería responder eso.
¿Cómo manejan las bibliotecas de fechas como Moment.js las cadenas de fecha?
Los analizan en función de un formato predeterminado o proporcionado. Lea la fuente (por ejemplo, fecha.js es un analizador y formateador simple con un código bien escrito y fácil de seguir).
Un analizador no es difícil de escribir, pero tratar de adivinar el formato de entrada (como tienden a hacer los analizadores integrados) es complicado, poco fiable e inconsistente en todas las implementaciones. Por lo tanto, el analizador debe requerir que se proporcione el formato a menos que la cadena de entrada esté en el formato predeterminado del analizador.
PD
Hay cambios en los formatos de cadenas que las implementaciones deben admitir para el análisis y el formato en ECMAScript 2019 (actualmente en borrador), pero creo que el consejo general para evitar el analizador incorporado se mantendrá durante algún tiempo todavía.
Cuando
Date.parse
new Date
o
Date.parse
en JavaScript, no puedo pasar formatos de fecha arbitrarios.
Dependiendo del formato, obtengo una fecha diferente de la que quería o incluso
Invalid Date
lugar de un objeto de fecha.
Algunos formatos de fecha funcionan en un navegador pero no en otros.
Entonces, ¿qué formatos de fecha y hora debo usar?
Preguntas adicionales:
-
¿Todos los navegadores soportan los mismos formatos? ¿Cómo manejan Mozilla Firefox, Google Chrome, Microsoft Internet Explorer, Microsoft Edge y Apple Safari las cadenas de fecha y hora? ¿Qué pasa con Node.js?
-
¿Tiene en cuenta el formato de fecha local? Por ejemplo, si vivo en Suiza y el formato de fecha es 30.07.2018, ¿puedo usar la
new Date(''30.07.2018'')
? -
¿Tiene en cuenta la zona horaria local?
-
¿Cómo puedo obtener una cadena de fecha y hora de un objeto de fecha?
-
¿Cómo puedo detectar cadenas de fecha y hora no válidas?
-
¿Cómo manejan las bibliotecas de fechas como Moment.js las cadenas de fecha?
En caso de que no te hayas dado cuenta, respondí mi propia pregunta ( why? ).
Lo escencial
JavaScript admite oficialmente una
simplificación
del formato extendido ISO 8601.
El formato es el siguiente:
YYYY-MM-DDTHH:mm:ss.sssZ
.
La letra
T
es el separador de fecha / hora y
Z
es el desplazamiento de zona horaria especificado como
Z
(para UTC) o bien
+
o
-
seguido de una expresión de hora
HH:mm
.
Algunas partes (por ejemplo, la hora) de ese formato pueden omitirse.
Tenga en cuenta que los años
deben
tener al menos cuatro dígitos, mes / día / horas / minutos / segundos
deben
tener exactamente dos dígitos, y los milisegundos
deben
tener exactamente tres dígitos.
Por ejemplo,
99-1-1
no es una cadena de fecha válida.
Estos son algunos ejemplos de cadenas de fecha (hora) válidas:
-
2018-12-30
-
2018-12-30T20:59
-
2018-12-30T20:59:00
-
2018-12-30T20:59:00.000Z
-
2018-12-30T20:59:00.000+01:00
-
2018-12-30T20:59:00.000-01:00
Cuando se omite el desplazamiento de zona horaria, las fechas y las fechas se interpretan como la hora local del usuario. Cuando se omite el tiempo completo, las fechas se interpretan como UTC.
Importante
: todos los navegadores e implementaciones modernos y razonablemente antiguos admiten el formato de fecha y hora de
longitud completa de
acuerdo con la especificación.
Sin embargo
, existen diferencias en el manejo de las cadenas de fecha (hora) sin una zona horaria (consulte la sección "Desviación de la zona horaria perdida" más adelante).
No debe usar cadenas de fecha y hora sin un huso horario (Estado 2018).
En su lugar, pase una
marca de tiempo de Unix en milisegundos o argumentos separados para diferentes partes de la fecha
al constructor
Date
.
La mayoría de los navegadores también admiten algunos otros formatos, pero no están especificados y, por lo tanto, no funcionan en todos los navegadores de la misma manera. Si es así, solo debe utilizar los formatos de cadena de fecha y hora explicados anteriormente. Todos los demás formatos pueden romperse en otros navegadores o incluso en otras versiones del mismo navegador.
Si se encuentra con una fecha no válida en lugar de un objeto de fecha, lo más probable es que esté utilizando una cadena de fecha y hora no válida.
Y ahora con un poco más de detalle.
Formato de cadena de fecha y hora
ECMAScript (la especificación que implementa el lenguaje JavaScript) ha sido compatible con cadenas de fecha en la
new Date
(
specification
) y
Date.parse
(
specification
) desde su inicio.
Sin embargo, las primeras versiones no especificaron realmente un formato de fecha y hora.
Esto cambió en 2009 cuando se introdujo ES5 con una especificación de un formato de fecha y hora.
Los basicos
ECMAScript especifica el
formato de cadena de fecha y hora
como una
simplificación
del
formato extendido ISO 8601
.
El formato es el siguiente:
YYYY-MM-DDTHH:mm:ss.sssZ
.
YYYY
son los dígitos decimales del año 0000 a 9999 en el proleptico calendario gregoriano.-
(guión) aparece literalmente dos veces en la cadena.MM
es el mes del año de 01 (enero) a 12 (diciembre).DD
es el día del mes del 01 al 31.T
aparece literalmente en la cadena, para indicar el comienzo del elemento de tiempo.HH
es el número de horas completas que han pasado desde la medianoche como dos dígitos decimales de 00 a 24.:
(dos puntos) aparece literalmente dos veces en la cadena.mm
es el número de minutos completos desde el inicio de la hora como dos dígitos decimales de 00 a 59.ss
es el número de segundos completos desde el comienzo del minuto como dos dígitos decimales de 00 a 59..
(punto) aparece literalmente en la cadena.sss
es el número de milisegundos completos desde el comienzo del segundo como tres dígitos decimales.Z
es el desplazamiento de zona horaria especificado como "Z" (para UTC) o bien "+" o "-" seguido de una expresión de horaHH:mm
No se han especificado otros formatos de fecha y hora. ECMAScript no tiene en cuenta los formatos de hora local de ningún usuario, lo que significa que no puede utilizar los formatos de fecha y hora específicos del país o región.
La especificación también mentions que si "la Cadena no se ajusta al formato [especificado], la función puede recurrir a cualquier heurística específica de la implementación o formatos de fecha específicos de la implementación", lo que podría dar lugar a fechas diferentes en diferentes navegadores.
Formas de fecha corta (y hora)
La especificación también incluye formatos más cortos de la siguiente manera.
Este formato incluye formularios de solo fecha:
YYYY
YYYY-MM
YYYY-MM-DD
También incluye formularios de "fecha y hora" que consisten en uno de los formularios de solo fecha arriba mencionados inmediatamente seguidos por uno de los siguientes formularios de tiempo con un desplazamiento opcional de zona horaria adjunto:
THH:mm
THH:mm:ss
THH:mm:ss.sss
Valores de retroceso
[...] Si los campos
MM
oDD
están ausentes, se utiliza"01"
como valor. Si los camposHH
,mm
oss
están ausentes, se utiliza"00"
como valor y el valor de un camposss
ausente es"000"
. Cuando el desplazamiento de zona horaria está ausente, los formularios de solo fecha se interpretan como una hora UTC y los formularios de fecha y hora se interpretan como una hora local.
Consulte "Desfase de zona horaria que falta" a continuación para obtener más información sobre la falta de compatibilidad con el navegador.
Valores fuera de los límites
Los valores ilegales (fuera de los límites así como los errores de sintaxis) en una cadena de formato significan que la cadena de formato no es una instancia válida de este formato.
Por ejemplo, la
new Date(''2018-01-32'')
y la
new Date(''2018-02-29'')
darán como resultado una
Invalid Date
new Date(''2018-02-29'')
.
Años Extendidos
El formato de fecha y hora de ECMAScript también especifica
años extendidos
que son valores de año de seis dígitos.
Un ejemplo de tal formato de cadena de año extendido se ve como
+287396-10-12T08:59:00.992Z
que denota una fecha en el año 287396 AD Los años extendidos pueden ser positivos o negativos.
API de fecha
ECMAScript especifica una amplia gama de
propiedades de objetos
de
fecha
.
Dado un objeto de fecha válido, puede usar
Date.prototype.toISOString()
para obtener una cadena de fecha y hora válida.
Tenga en cuenta que la zona horaria siempre es UTC.
new Date().toISOString() // "2018-08-05T20:19:50.905Z"
También es posible detectar si un objeto de fecha es válido o una
Invalid Date
válida mediante la siguiente función.
function isValidDate(d) {
return d instanceof Date && !isNaN(d);
}
La fuente y más información se pueden encontrar en Detección de una fecha de "fecha no válida" en JavaScript .
Ejemplos
Formatos de fecha y hora válidos
Los siguientes formatos de fecha y hora son todos válidos de acuerdo con la especificación y deben funcionar en todos los navegadores, Node.js u otra implementación que admita ES2016 o superior.
2018
2018-01
2018-01-01
2018-01-01T00:00
2018-01-01T00:00:00
2018-01-01T00:00:00.000
2018-01-01T00:00:00.000Z
2018-01-01T00:00:00.000+01:00
2018-01-01T00:00:00.000-01:00
+002018-01-01T00:00:00.000+01:00
Formatos de fecha y hora no válidos
Tenga en cuenta que los siguientes ejemplos no son válidos según la especificación. Sin embargo, eso no significa que ningún navegador u otra implementación los interprete a una fecha. No utilice ninguno de los formatos de fecha y hora a continuación, ya que no son estándar y pueden fallar en algunos navegadores o versiones del navegador.
2018-1-1 // month and date must be two digits
2018-01-01T0:0:0.0 // hour/minute/second must be two digits, millisecond must be three digits
2018-01-01 00:00 // whitespace must be "T" instead
2018-01-01T00 // shortest time part must have format HH:mm
2018-01-01T00:00:00.000+01 // time zone must have format HH:mm
Soporte del navegador
Hoy en día,
todos los navegadores modernos y razonablemente antiguos admiten el formato de fecha y hora
que se introdujo con la especificación ES5 en 2009. Sin embargo, incluso hoy en día (Estado 2018) existen diferentes implementaciones para las cadenas de fecha y hora sin una zona horaria (consulte "Desviación de la zona horaria perdida "abajo).
Si necesita admitir navegadores más antiguos o usar cadenas sin una zona horaria, no debe usar cadenas de fecha y hora
.
En su lugar, pase una
cantidad de milisegundos desde el 1 de enero de 1970, 00:00:00 UTC
o
dos o más argumentos que representan las diferentes partes de fecha
al constructor
Date
.
Desfase de zona horaria que falta
ES5.1 indica
incorrectly
que el valor de un desplazamiento de zona horaria ausente es
“Z”
que contradice ISO 8601. Este error se corrigió en
ES6 (ES2015)
y se extendió en
ES2016
(consulte "Cambios en las Especificaciones de ECMAScript" a continuación).
A partir de ES2016, las cadenas de fecha y hora sin una zona horaria se analizan como hora local, mientras que las cadenas de solo fecha se analizan como UTC.
De acuerdo con
esta respuesta
, algunas implementaciones nunca implementaron el comportamiento especificado en ES5.1.
Uno de ellos parece ser Mozilla Firefox.
Otros navegadores que parecen cumplir con la especificación de ES2016 (y superior) son Google Chrome 65+, Microsoft Internet Explorer 11 y Microsoft Edge.
La versión actual de Apple Safari (11.1.2)
no
es compatible ya que analiza erróneamente las cadenas de fecha y hora sin una zona horaria (por ejemplo,
2018-01-01T00:00
) como UTC en lugar de la hora local.
Formatos de fecha y hora heredados
ES5 introdujo una especificación para las cadenas de fecha y hora en 2009. Antes de eso, no había formatos específicos que fueran compatibles con todos los navegadores. Como resultado, cada proveedor de navegadores agregó soporte para diferentes formatos que a menudo no funcionaban en diferentes navegadores (y versiones). Para un pequeño ejemplo de historia antigua, vea date-formats .
La mayoría de los navegadores aún admiten esos formatos heredados para no romper la compatibilidad con versiones anteriores de sitios web más antiguos. Pero no es seguro confiar en esos formatos no estándar, ya que pueden ser inconsistentes o eliminarse en cualquier momento.
Date.prototype.toString()
y
Date.prototype.toUTCString()
ES2018 especificó por primera vez el formato de fecha que devuelve
Date.prototype.toString()
y
Date.prototype.toUTCString()
.
Ya antes de eso, la Especificación ECMA requería que el constructor
Date
y
Date.parse
analizaran correctamente los formatos devueltos por esos métodos (aunque no especificó un formato antes de 2018).
Un valor de retorno de ejemplo de
Date.prototype.toString()
puede tener este aspecto:
Sun Feb 03 2019 14:27:49 GMT+0100 (Central European Standard Time)
Tenga en cuenta que el nombre de la zona horaria entre paréntesis es opcional y el nombre exacto es "dependiente de la implementación".
Date.prototype.toUTCString()
devuelve una fecha en un formato similar a
Date.prototype.toString()
pero con un desplazamiento de zona horaria cero.
Un formato de ejemplo puede verse así:
Sun, 03 Feb 2019 13:27:49 GMT
Tenga en cuenta que hay una coma
,
después de que el día de la semana y el mes se inviertan en comparación con
Date.prototype.toUTCString()
.
Dado que esos formatos solo se han especificado en 2018, no debe confiar en que funcionen por igual en diferentes implementaciones (especialmente en navegadores antiguos).
Node.js
Node.js se ejecuta en el motor de JavaScript V8 que también se usa en Google Chrome. Así que se aplica la misma especificación con respecto al formato de cadena de fecha y hora. Sin embargo, como el código se ejecuta en el backend, la hora local del usuario no influye en las zonas horarias, pero sí lo hace la configuración del servidor. El proveedor de la mayoría de las plataformas como servicio (PaaS) que aloja las aplicaciones Node.js utiliza UTC como su zona horaria predeterminada.
Bibliotecas de fecha y hora
Moment.js
Moment.js es una biblioteca muy popular para ayudar con el manejo de fechas en JavaScript y también admite más formatos de los que especifica ECMAScript. Además, Moment.js también admite la creación de objetos de fecha basados en una cadena y un formato arbitrario .
Luxon
Luxon admite el parsing de ISO 8601, HTTP, RFC2822, SQL y formatos arbitrarios. Pero solo usa diferentes funciones para diferentes formatos de fecha y hora.
Cambios en las especificaciones de ECMAScript
Una lista de cambios notables en las especificaciones de ECMAScript con respecto a los formatos de cadena de fecha y hora.
Cambios en ES2018
Introduce una especificación para los formatos de fecha devueltos por
Date.prototype.toString()
y
Date.prototype.toUTCString()
.
Cambios en ES2017
No hay cambios notables.
Cambios en ES2016
Si el desplazamiento de la zona horaria está ausente, la fecha y la hora se interpretan como una hora local.Cuando el desplazamiento de zona horaria está ausente, los formularios de solo fecha se interpretan como una hora UTC y los formularios de fecha y hora se interpretan como una hora local.
Cambios en ES6 (ES2015)
El valor de un desplazamiento de zona horaria ausente es“Z”
.Si el desplazamiento de la zona horaria está ausente, la fecha y la hora se interpretan como una hora local.
De incorrectly :
Si un desplazamiento de zona horaria no está presente, se utiliza la zona horaria local. La edición 5.1 declaró incorrectamente que una zona horaria faltante debe interpretarse como
"z"
.
Consulte Fecha Formato de la cadena de tiempo: la diferencia de zona horaria predeterminada de ES5 no es compatible con la web para obtener más detalles sobre ese cambio.
Cambios en ES5.1
Si los campos
MM
oDD
están ausentes, se utiliza“01”
como valor. Si los camposHH
,mm
oss
están ausentes, se utiliza“00”
como valor y el valor de un camposss
ausente es“000”
. El valor de un desplazamiento de zona horaria ausente es“Z”
.
Cambios en ES5
Primera introducción de un formato de cadena de fecha y hora a la especificación ECMAScript.
ECMAScript define un formato de intercambio de cadena para las fechas y los tiempos basándose en una simplificación del formato extendido ISO 8601. El formato es el siguiente:
YYYY-MM-DDTHH:mm:ss.sssZ
También introduce
Date.prototype.toISOString()
que devuelve una cadena de fecha y hora en ese formato especificado.
Cambios en ES3
Date.prototype.toGMTString()
y lo reemplaza con
Date.parse(x.toUTCString())
en la sección que menciona que el formato devuelto por estos métodos debe ser analizable correctamente por las implementaciones de
Date.parse
.
Tenga en cuenta que el formato devuelto por
Date.parse(x.toUTCString())
es "dependiente de la implementación".
Cambios en ES2
No hay cambios notables.
Especificación inicial: ES1
ES1 introdujo las cadenas de fecha y hora que se utilizarán en la
new Date(value)
y
Date.parse(value)
.
Sin embargo, no especificó un formato de fecha (hora) real, incluso indica que
[...] el valor producido por
Date.parse
es dependiente de la implementación [...]
La especificación también menciona que
Si
x
es un objeto Date [...], entonces todas las siguientes expresiones deberían producir el mismo valor numérico en esa implementación [...]:
- [...]
Date.parse(x.toString())
Date.parse(x.toGMTString())
Sin embargo, el valor devuelto de
Date.prototype.toString()
y
Date.prototype.toGMTString()
se especificaron como "dependientes de la implementación".