tag property for javascript node.js date datetime v8

javascript - property - ¿Hay alguna solución para el analizador de fecha v8 roto?



title property html (3)

ES5 15.9.4.2 Date.parse: /.../ Si la cadena no cumple con ese formato, 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. Las cadenas o fechas irreconocibles que contienen valores de elementos no válidos en el formato de cadena harán que Date.parse devuelva NaN.

Así que está bien y de acuerdo con el resultado de la cita v8 anterior:

  1. new Date(''asd qw 101'') : sáb 01 de enero 101 00:00:00 GMT + 0100 (CET)
  2. new Date(''asd qw'') : fecha no new Date(''asd qw'')

El analizador de fecha V8 está roto:

> new Date(''asd qw 101'') Sat Jan 01 101 00:00:00 GMT+0100 (CET)

Puedo usar una expresión regular frágil como esta:

/d{1,2} (jan|feb|mar|may|jun|jul|aug|sep|oct|nov|dec) /d{1,4}

pero es demasiado frágil No puedo confiar en la new Date (problema en V8) y también el momento no puedo ayudarme porque el momento es deshacerse de la detección de fecha (github issue-thread) .

¿Hay alguna solución para el analizador de fecha v8 roto?

Para ser claro. Tenemos Gecko y V8, ambos tienen Date . V8 ha roto la fecha, Gecko tiene trabajo uno. Necesito la Date de en Gecko (Firefox).

Actualización: definitivamente está roto el analizador https://code.google.com/p/v8/issues/detail?id=2602
nope, Status: WorkingAsIntended


Parece que estás pidiendo una manera de analizar una cadena que podría estar en cualquier formato particular y determinar qué datos están representados. Hay muchas razones por las que esta es una mala idea en general.

Dice que moment.js es "deshacerse de la detección de fecha", pero en realidad nunca tuvo esta característica en primer lugar. La gente simplemente asumió que podía hacer eso, y en algunos casos funcionó, y en muchos casos no lo hizo.

Aquí hay un ejemplo que ilustra el problema.

var s = "01.02.03";

¿Es eso una cita? Tal vez. Tal vez no. Podría ser un encabezado de sección en un documento. Incluso si dijéramos que era una fecha, ¿qué fecha es? Podría interpretarse como cualquiera de los siguientes:

  • 2 de enero de 2003
  • 2 de enero de 0003
  • 1 de febrero de 2003
  • 1 de febrero de 0003
  • 3 de febrero de 2001
  • 3 de febrero de 0001

La única forma de desambiguar sería con el conocimiento de la configuración de la fecha de cultura actual. El objeto Date de Javascript hace exactamente eso, lo que significa que obtendrá un valor diferente dependiendo de la configuración de la máquina donde se ejecuta el código. Sin embargo, moment.js se trata de la estabilidad en todos los entornos. Los ajustes culturales son explícitos, a través de la funcionalidad local del momento. Confiar en la configuración cultural del navegador conduce a errores de interpretación.

Lo mejor que puede hacer es ser explícito sobre el formato con el que está trabajando. No permitir la entrada de basura aleatoria. Espere su entrada en un formato particular, y use una expresión regular para validar ese formato con anticipación, en lugar de intentar construir una Date y ver si es válida después del hecho.

Si no puede hacer eso, tendrá que encontrar un contexto adicional para ayudar a decidir. Por ejemplo, si está raspando algunos bits aleatorios de la web de un proceso de back-end y desea extraer una fecha del texto, debe tener algún conocimiento sobre el idioma y la configuración regional de cada página web en particular. Podrías adivinar, pero es probable que te equivoques una buena cantidad de tiempo.

Ver también: basura en, basura fuera.


Date objetos de Date se basan en un valor de tiempo que es el número de milisegundos desde el 1 de enero de 1970 UTC y tienen los siguientes constructores

new Date(); new Date(value); new Date(dateString); new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);

De los docs ,

dateString en new Date(dateString) es un valor de cadena que representa una fecha. La cadena debe estar en un formato reconocido por el método Date.parse () ( marcas de tiempo RFC 2822 compatibles con IETF y también una versión de ISO8601 ).

Ahora mirando el código fuente v8 en date.js:

function DateConstructor(year, month, date, hours, minutes, seconds, ms) { if (!%_IsConstructCall()) { // ECMA 262 - 15.9.2 return (new $Date()).toString(); } // ECMA 262 - 15.9.3 var argc = %_ArgumentsLength(); var value; if (argc == 0) { value = %DateCurrentTime(); SET_UTC_DATE_VALUE(this, value); } else if (argc == 1) { if (IS_NUMBER(year)) { value = year; } else if (IS_STRING(year)) { // Probe the Date cache. If we already have a time value for the // given time, we re-use that instead of parsing the string again. var cache = Date_cache; if (cache.string === year) { value = cache.time; } else { value = DateParse(year); <- DOES NOT RETURN NaN if (!NUMBER_IS_NAN(value)) { cache.time = value; cache.string = year; } } } ...

parece que DateParse() no devuelve un NaN para una cadena como ''asd qw 101'' y por lo tanto el error. Puede realizar una comprobación cruzada de la misma forma con Date.parse(''asd qw 101'') tanto en Chrome (v8) [que devuelve -58979943000000 ] como en Gecko (Firefox) [que devuelve una NaN]. Sat Jan 01 101 00:00:00 produce cuando se agrega una new Date() con una marca de tiempo de -58979943000000 (en ambos navegadores)

¿Hay alguna solución para el analizador de fecha v8 roto?

No diría que el analizador de fecha V8 está roto. Solo intenta satisfacer una cadena contra el estándar RFC 2822 de la mejor manera posible, pero también lo hace gecko y ambas rupturas dan resultados diferentes en ciertos casos.

Pruebe la new Date(''Sun Ma 10 2015'') tanto en Chrome (V8) como en Firefox (Gecko) por otra anomalía similar. Aquí, Chrome no puede decidir si el tiempo ''Ma'' significa ''marzo'' o ''mayo'' y da una fecha no válida mientras Firefox no.

Solución:

Puede crear su propio envoltorio alrededor de Date() para filtrar aquellas cadenas que el propio analizador de V8 no puede. Sin embargo, la subclasificación incorporada en ECMA-5 no es factible. En ECMA-6, será posible crear subclases de constructores integrados (Array, Fecha y Error) - reference

Sin embargo, puede utilizar una expresión regular más robusta para validar cadenas según RFC 2822 / ISO 8601

^(?:(?:31(//|-|/. |/s)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))/1|(?:(?:29|30)(//|-|/.|/s)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))/2))(?:(?:1[6-9]|[2-9]/d)?/d{2})$|^(?:29(//|-|/.|/s)(?:0?2|(?:Feb))/3(?:(?:(?:1[6-9]|[2-9]/d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1/d|2[0-8])(//|-|/.|/s)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))/4(?:(?:1[6-9]|[2-9]/d)?/d{2})$

Imagen generada desde debuggex

Entonces, parece que v8 no está roto, simplemente funciona de manera diferente.

¡Espero eso ayude!