Home > Blockchain >  ISO8601 Format without Y-M-D
ISO8601 Format without Y-M-D

Time:12-08

I have a date formatted in ISO8601 that I want to use and compare against different times. For example if it's between 18:00 and 21:00, return true. Else return false. But I don't want to compare the Y-M-D portion of it. I want it to be any day, but those times.

public function compareTimes($time) {
        $dateTime = DateTime::createFromFormat("Y-m-d\TH:i:s ", $time);
        $begin = new DateTime('18:00');
        $end = new DateTime('22:00');
        if($dateTime >= $begin && $dateTime <= $end) {
            return true;
        } else {
            return false;
        }
    }

I have this code, however it compares it vs the Y-m-d as well so if it happened on a different day it wouldn't work. So I don't want to compare it against those 3 things. However if I ommit them, it's not a valid DateTime and won't work

CodePudding user response:

As your input is a string in ISO format, I would suggest working with strings directly: strip the date part from the input string and then perform a string comparison:

function compareTimes($time) {
    $time = substr($time, 11); // Strip date part from ISO formatted input
    $begin = "18:00";
    $end = "22:00";
    return $time > $begin && $time < $end;
}

CodePudding user response:

Just treat it as a number:

public function compareTimes($time): boolean
{
    // $dateTime becomes something like 2200
    $dateTime = DateTime::createFromFormat("Y-m-d\TH:i:s ", $time)->format("Gi");
    $begin = 1800;
    $end = 2200;
    return $dateTime >= $begin && $dateTime <= $end;
}

CodePudding user response:

One way to do this would be to parse the string with a format specifier that discards the parts you don't want. Looking at the available formats in the manual, the ? specifier matches any single byte, so you could write:

$timeOnly = DateTime::createFromFormat("????-??-??\TH:i:s ", $time);

By default, specifying just a time uses today's date; it might make more sense to reset everything to the Unix Epoch (1st Jan 1970) using the ! specifier, giving this:

$timeOnly = DateTime::createFromFormat("!????-??-??\TH:i:s ", $time);
$begin = DateTime::createFromFormat('!H:i', '18:00');
$end = DateTime::createFromFormat('!H:i', '22:00');

[Live demo]


Alternatively, you could parse the date as normal, and then use the setDate method to reset the date part to a fixed value (e.g. the Unix epoch):

$timeOnly = DateTime::createFromFormat("Y-m-d\TH:i:s ", $time)->setDate(1970, 1, 1);
$begin = (new DateTime('18:00'))->setDate(1970, 1, 1);
$end = (new DateTime('22:00'))->setDate(1970, 1, 1);

[Live demo]

  • Related