JavaScript regex дата и время ISO

у кого-либо есть хороший regex шаблон для соответствия ISO datetimes?

т.е.: 2010-06-15T00:00:00

48
задан Scott Klarenbach 29 June 2010 в 06:13
поделиться

3 ответа

Для строгого, полного datetime, включая миллисекунды, согласно W3C, взявшему за основу спецификацию .:

//-- Complete precision:
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/

//-- No milliseconds:
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z)/

//-- No Seconds:
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z)/

//-- Putting it all together:
/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/

.
Дополнительные вариации, разрешенные фактическим документом ISO 8601: 2004 (E) :

/********************************************
**    No time-zone varients:
*/
//-- Complete precision:
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+/

//-- No milliseconds:
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d/

//-- No Seconds:
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d/

//-- Putting it all together:
/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+)|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d)|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d)/

ПРЕДУПРЕЖДЕНИЕ: все это быстро становится беспорядочным, и по-прежнему допускает определенную ерунду, такую ​​как 14-й месяц. Кроме того, ISO 8601: 2004 (E) допускает несколько других вариантов.

.
«2010-06-15T00: 00: 00» недопустимо, потому что в нем нет обозначения часового пояса.

86
ответ дан 7 November 2019 в 12:22
поделиться

Не уверен, относится ли это к основной проблеме, которую вы пытаетесь решить, но вы можете передать строку даты ISO в качестве аргумента конструктора в Date () и получить из нее объект. Конструктор на самом деле очень гибкий с точки зрения преобразования строки в Date.

-1
ответ дан 7 November 2019 в 12:22
поделиться

Спецификация ISO 8601 допускает большое разнообразие форматов даты. Есть посредственное объяснение того, как это сделать здесь . Существует довольно незначительное несоответствие между форматированием ввода даты в Javascript и форматированием ISO для простых дат, в которых не указаны часовые пояса, и его можно легко устранить с помощью подстановки строки . Полная поддержка спецификации ISO-8601 нетривиальна.

Вот справочный пример, полнота которого я не гарантирую, хотя он анализирует непродолжительные даты с вышеупомянутой страницы Википедии.

Ниже приведен пример, и вы также можете увидеть его вывод на ideone . К сожалению, это не работает в соответствии со спецификацией, так как не реализует недели должным образом. Определение номера недели 01 в ISO-8601 нетривиально и требует некоторого просмотра календаря, чтобы определить, где начинается первая неделя, и что именно она означает с точки зрения количества дней в указанном году. Это, вероятно, довольно легко исправить (я просто устал с этим играть).

function parseISODate (input) {
    var iso = /^(\d{4})(?:-?W(\d+)(?:-?(\d+)D?)?|(?:-(\d+))?-(\d+))(?:[T ](\d+):(\d+)(?::(\d+)(?:\.(\d+))?)?)?(?:Z(-?\d*))?$/;

    var parts = input.match(iso);

    if (parts == null) {
        throw new Error("Invalid Date");
    }

    var year = Number(parts[1]);

    if (typeof parts[2] != "undefined") {
        /* Convert weeks to days, months 0 */
        var weeks = Number(parts[2]) - 1;
        var days  = Number(parts[3]);

        if (typeof days == "undefined") {
            days = 0;
        }

        days += weeks * 7;

        var months = 0;
    }
    else {
        if (typeof parts[4] != "undefined") {
            var months = Number(parts[4]) - 1;
        }
        else {
            /* it's an ordinal date... */
            var months = 0;
        }

        var days   = Number(parts[5]);
    }

    if (typeof parts[6] != "undefined" &&
        typeof parts[7] != "undefined")
    {
        var hours        = Number(parts[6]);
        var minutes      = Number(parts[7]);

        if (typeof parts[8] != "undefined") {
            var seconds      = Number(parts[8]);

            if (typeof parts[9] != "undefined") {
                var fractional   = Number(parts[9]);
                var milliseconds = fractional / 100;
            }
            else {
                var milliseconds = 0
            }
        }
        else {
            var seconds      = 0;
            var milliseconds = 0;
        }
    }
    else {
        var hours        = 0;
        var minutes      = 0;
        var seconds      = 0;
        var fractional   = 0;
        var milliseconds = 0;
    }

    if (typeof parts[10] != "undefined") {
        /* Timezone adjustment, offset the minutes appropriately */
        var localzone = -(new Date().getTimezoneOffset());
        var timezone  = parts[10] * 60;

        minutes = Number(minutes) + (timezone - localzone);
    }

    return new Date(year, months, days, hours, minutes, seconds, milliseconds);
}

print(parseISODate("2010-06-29T15:33:00Z-7"))
print(parseISODate("2010-06-29 06:14Z"))
print(parseISODate("2010-06-29T06:14Z"))
print(parseISODate("2010-06-29T06:14:30.2034Z"))
print(parseISODate("2010-W26-2"))
print(parseISODate("2010-180"))
3
ответ дан 7 November 2019 в 12:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: