phpdatetimeiso8601dateinterval

Format DateInterval as ISO8601


I am currently working on a php project and need to format a DateInterval as ISO8601 (something like this):

P5D

This format can be used to create DateTime and DateInterval objects, but I can't figure out a way to format a DateInterval into this format. Is there any? If not, what might be a lightweight solution to that?


Solution

  • Well, if you look at the spec for the format when you construct one:

    Y years

    M months

    D days

    W weeks. These get converted into days, so can not be combined with D.

    H hours

    M minutes

    S seconds

    Then look at what you have to work with (http://php.net/manual/en/dateinterval.format.php), it seems like what you would do is:

    $dateInterval = new DateInterval( /* whatever */ );
    $format = $dateInterval->format("P%yY%mM%dD%hH%iM%sS");
    //P0Y0M5D0H0M0S
    //now, we need to remove anything that is a zero, but make sure to not remove
    //something like 10D or 20D
    $format = str_replace(["M0S", "H0M", "D0H", "M0D", "Y0M", "P0Y"], ["M", "H", "D", "M", "Y0M", "P"], $format);
    echo $format;
    //P0M5D
    

    Now, the one thing I did differently is I always include the months, even if it is 0. The reason for this is that minutes and months are both represented by M - if we always include the month, then if there is a minute we know it is minutes. Otherwise we have to do a bunch of logic to see if we need to change the P to PT so it knows that the a M in this instance stands for Minute.

    For example:

    // For 3 Months
    new DateInterval("P3M");
    // For 3 Minutes
    new DateInterval("PT3M"));
    

    But instead we do:

    // For 3 Months
    new DateInterval("P3M");
    // For 3 Minutes
    new DateInterval("P0M3M"));