Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP validate ISO 8601 date string

Tags:

How do you validate ISO 8601 date string (ex: 2011-10-02T23:25:42Z).

I know that there are several possible representations of ISO 8601 dates, but I'm only interested in validating the format I gave as an example above.

Thanks!

like image 775
titel Avatar asked Nov 03 '11 23:11

titel


2 Answers

This worked for me, it uses a regular expression to make sure the date is in the format you want, and then tries to parse the date and recreate it to make sure the output matches the input:

<?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;
    }
}

You could expand further to use checkdate to make sure the month day and year are valid as well.

like image 200
drew010 Avatar answered Sep 22 '22 11:09

drew010


Edit: By far the easiest method is to simply try to create a DateTime object using the string, eg

$dt = new DateTime($dateTimeString);

If the DateTime constructor cannot parse the string, it will throw an exception, eg

DateTime::__construct(): Failed to parse time string (2011-10-02T23:25:72Z) at position 18 (2): Unexpected character

Note that if you leave off the time zone designator, it will use the configured default timezone.

Second easiest method is to use a regular expression. Something like this aught to cover it

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
}
like image 27
Phil Avatar answered Sep 19 '22 11:09

Phil