PHP проверяет строку даты ISO 8601

Как вы проверяете строку даты ISO 8601 (например: 2011-10-02T23: 25: 42Z).

Я знаю, что существует несколько возможных представлений о датах ISO 8601, но я заинтересован только в подтверждении формата, который я дал в качестве примера выше.

Благодаря!

Это сработало для меня, оно использует регулярное выражение, чтобы убедиться, что дата находится в нужном формате, а затем пытается проанализировать дату и воссоздать ее, чтобы убедиться, что результат соответствует вводу:

<?php $date = '2011-10-02T23:25:42Z'; var_dump(validateDate($date)); $date = '2011-17-17T23:25:42Z'; var_dump(validateDate($date)); function validateDate($date) { if (preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/', $date, $parts) == true) { $time = gmmktime($parts[4], $parts[5], $parts[6], $parts[2], $parts[3], $parts[1]); $input_time = strtotime($date); if ($input_time === false) return false; return $input_time == $time; } else { return false; } } 

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

Изменить: самым простым способом является просто попытаться создать объект DateTime с помощью строки, например

 $dt = new DateTime($dateTimeString); 

Если конструктор DateTime не может проанализировать строку, он выдает исключение, например

DateTime :: __ construct (): Не удалось проанализировать строку времени (2011-10-02T23: 25: 72Z) в позиции 18 (2): Неожиданный символ

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

Второй самый простой способ – использовать регулярное выражение. Что-то вроде этого должно его покрыть

 if (preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|(\+|-)\d{2}(:?\d{2})?)$/', $dateString, $parts)) { // valid string format, can now check parts $year = $parts[1]; $month = $parts[2]; $day = $parts[3]; // etc } 

См. http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/ . Он дает этому регулярному выражению:

 ^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$ 

Я полагаю, что это точно не отвечает на ваш вопрос, так как он будет соответствовать любой действительной дате ISO 8601, но если это хорошо, тогда это работает отлично.

Я хочу поделиться своим легким решением. Это не идеально, но может быть полезно для кого-то.

 function validISO8601Date($value) { if (!is_string($value)) { return false; } $dateTime = \DateTime::createFromFormat(\DateTime::ISO8601, $value); if ($dateTime) { return $dateTime->format(\DateTime::ISO8601) === $value; } return false; } 

ВНИМАНИЕ!

Некоторые действительные даты ISO8601 не будут выполнены. Посмотрите на список ниже

 NOT VALID --> '' // Correct NOT VALID --> 'string' // Correct VALID --> '2000-01-01T01:00:00+1200' // This is the only format function returns as valid NOT VALID --> '2015-01 first' // Correct NOT VALID --> '2000-01-01T01:00:00Z' // Must be valid! NOT VALID --> '2000-01-01T01:00:00+01' // Must be valid! 

Это функция, которую я использую. Он похож на ответ drew010, но работает также для временных меток, заканчивающихся «+01: 00» или «-01: 00».

 function isTimestampIsoValid($timestamp) { if (preg_match('/^'. '(\d{4})-(\d{2})-(\d{2})T'. // YYYY-MM-DDT ex: 2014-01-01T '(\d{2}):(\d{2}):(\d{2})'. // HH-MM-SS ex: 17:00:00 '(Z|((-|\+)\d{2}:\d{2}))'. // Z or +01:00 or -01:00 '$/', $timestamp, $parts) == true) { try { new \DateTime($timestamp); return true; } catch ( \Exception $e) { return false; } } else { return false; } }