Ответ 1
Date
объекты основаны на значении времени, которое составляет миллисекунды с 1 января 1970 года по UTC и имеют следующие конструкторы
new Date();
new Date(value);
new Date(dateString);
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);
Из docs,
dateString в
new Date(dateString)
- это строковое значение, представляющее дату. Строка должна быть в формат, распознаваемый методом Date.parse() (IETF-совместимый RFC 2822 timestamps, а также версию ISO8601).
Теперь посмотрим исходный код v8 в 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;
}
}
}
...
похоже, что DateParse()
не возвращает NaN для строки типа 'asd qw 101'
и, следовательно, ошибки. Вы можете перекрестно проверить то же самое с Date.parse('asd qw 101')
в Chrome (v8) [который возвращает -58979943000000
] и Gecko (Firefox) [который возвращает NaN]. Sat Jan 01 101 00:00:00
появляется при посеве new Date()
с отметкой времени -58979943000000 (в обоих браузерах)
есть ли какое-либо временное решение для разбитого синтаксического анализатора v8?
Я бы не сказал, что парсер даты V8 сломан. Он просто пытается удовлетворить строку RFC 2822 standard наилучшим образом, но так же делает gecko и обе break дает разные результаты в определенных случаях.
Попробуйте new Date('Sun Ma 10 2015')
в Chrome (V8) и Firefox (Gecko) для другой такой аномалии.
Здесь хром не может решить, что погода "Ма" означает "март" или "май" и дает недопустимую дату, пока Firefox не делает.
Обход проблемы:
Вы можете создать свою собственную оболочку вокруг Date()
, чтобы отфильтровать те строки, которые не поддерживает собственный парсер V8. Однако подклассификация встроенных модулей ECMA-5 невозможна. В ECMA-6 возможно подклассы встроенных конструкторов (Array, Date и Error) - ссылка
Однако вы можете использовать более надежное регулярное выражение для проверки строк по 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})$
Изображение, созданное с помощью debuggex
Итак, похоже, что v8 aint сломан, он просто работает по-другому.
Надеюсь, что это поможет!