Исчерпывающий набор регулярных выражений для валидации ISO8601-строк в том числе неполных

Рейтинг: 0Ответов: 1Опубликовано: 07.08.2025

Задача заключается в том, чтобы валидировать ISO8601-строки, с помощью которых выражаются даты и иногда время. "Иногда" означает, что время может быть опущено (как в "2005-08-09"), более того, иногда и дата может быть указана не полностью (например, "2005-08"). В то же время, не всё так либерально: такие строки как "2005-8" или "2005-" невалидны.

Допускаю, что регулярные выражения - не самый лучший способ решения задачи, но и такой способ как new Date(targetDateAndPossiblyTimeDefinition).toString() !== "Invalid Date" тоже является неверным, потому что "1970-1-01" будет расценено так верная дата, что не так с точки зрения ISO8601.

Если создание единого регулярного выражения и возможно, то оно будет слишком громоздким, потому думаю что лучше будет проверка на набор регулярных выражений:

if (
  [
    /^\d{4}$/gu,
    /^\d{4}-\d{2}$/gu,
    /^\d{4}-\d{2}-\d{2}$/gu,
    /^\d{4}-\d{2}-\d{2}T\d{2}$/gu,
    /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/gu,
    /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/gu
  ].some(
    (regularExpression: RegExp): boolean => regularExpression.test(targetDateAndPossiblyTimeDefinition)
  );
) {
  console.log("Valid!")
}

Какие ещё регулярные выражения актуальны для JavaScript (и вообще ECMAScript)? Не все примеры, представленные в статье из Википедии считаются в JavaScript валидными определениями ISO8601: например new Date("20050809T183142+03").toString() вернёт "Invalid date".

Ответы

▲ 1Принят

JS открыто не поддерживал ISO с самого начала. Позднее поддерживаются те же строчки, что выводятся с помощью Date.prototype.toISOString() (доки). "Военные" и специализированные форматы и указание не в UTC не рассматриваются. Причина одна - это инструмент для браузеров и излишняя гибкость там не нужна. Строчка на входе в Datе - свой собственный формат, похожий на RFC.

regex почти не пригоден на определения полного соответствия стандарту.

Есть библиотеки, заполняющие эту нишу, для преобразований (например Day.js) или для работы с периодами времени (например, iso8601-duration).

Т.к. нужно определять является ли строка частичной и отвергать подобные, стоит задуматься над проверкой длины строки сразу, и на проверку, не является она просто временем. Самое хитрое - с временными зонами и с тем что время в ISO может быть задано в дробной форме.