Skip to content

Format constraint and date-time with fractions #145

Closed
@jenschude

Description

@jenschude

The date-time is not handling the fraction part of a datetime string correctly

To the FormatTest::getValidFormats should be added following cases:

        array('2000-05-01T12:12:12.123Z', 'date-time'),
        array('2000-05-01T12:12:12.123+01:00', 'date-time'),
        array('2000-05-01T12:12:12.123+0100', 'date-time'),
        array('2000-05-01T12:12:12.123456+01:00', 'date-time'),
        array('2000-05-01T12:12:12.123456+0100', 'date-time'),

And in the function FormatConstraint::check the case 'date-time' should be changed to:

        case 'date-time':
            if (!$this->validateDateTime($element, 'Y-m-d\TH:i:sT') &&
                !$this->validateDateTime($element, 'Y-m-d\TH:i:s.uT') &&
                !$this->validateDateTime($element, 'Y-m-d\TH:i:sP') &&
                !$this->validateDateTime($element, 'Y-m-d\TH:i:s.uP') &&
                !$this->validateDateTime($element, 'Y-m-d\TH:i:sO') &&
                !$this->validateDateTime($element, 'Y-m-d\TH:i:s.uO')
            ) {
                $this->addError($path, sprintf('Invalid date-time %s, expected format YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss+hh:mm', json_encode($element)));
            }
            break;

The T is better than \Z because this way the timezone part from the string will be correctly read. Important if the script is not running with UTC timezone. And the FormatConstraint::validateDateTime can now be changed to this, so that the tests will work:

protected function validateDateTime($datetime, $format)
{
    $dt = \DateTime::createFromFormat($format, $datetime);

    if (!$dt) {
        return false;
    }
    if (strpos($format, '.u') > 0 ) {
        $dtTest = new \DateTime($datetime);
        return $dt == $dtTest;
    }
    return $datetime === $dt->format($format);
}

So that when a fraction is included in the datetime string, it will be checked if reading from format and just a plain DateTime instance will have the same value.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions