PHP:如何将字符串持续时间转换为ISO 8601持续时间格式?(即"30分钟"到"PT30M")

Chr*_*ris 11 php duration iso8601 dateinterval

有很多问题要求如何以另一种方式执行此操作(从此格式转换),但我无法找到有关如何在PHP中以ISO 8601持续时间格式输出的任何内容.

所以我有一堆人类可读格式的持续时间字符串 - 我想在运行时将它们转换为ISO 8601格式,以打印HTML5微数据的持续时间.下面是一些字符串的示例,以及它们应如何格式化

"1 hour 30 minutes" --> PT1H30M
"5 minutes" --> PT5M
"2 hours" --> PT2H
Run Code Online (Sandbox Code Playgroud)

你明白了.

我可以将字符串推送到PHP中的间隔对象:

date_interval_create_from_date_string("1 hour 30 minutes");
Run Code Online (Sandbox Code Playgroud)

但似乎没有ISO 8601输出选项 - 我该如何处理?

谢谢大家.

Eri*_*ric 13

我首先将它转换为数字,然后使用它.

首先,使用strtotime():

$time = strtotime("1 hour 30 minutes", 0);
Run Code Online (Sandbox Code Playgroud)

然后你可以解析它的持续时间,并以PnYnMnDTnHnMnS格式输出.我将使用以下方法(受http://csl.sublevel3.org/php-secs-to-human-text/启发):

function time_to_iso8601_duration($time) {
    $units = array(
        "Y" => 365*24*3600,
        "D" =>     24*3600,
        "H" =>        3600,
        "M" =>          60,
        "S" =>           1,
    );

    $str = "P";
    $istime = false;

    foreach ($units as $unitName => &$unit) {
        $quot  = intval($time / $unit);
        $time -= $quot * $unit;
        $unit  = $quot;
        if ($unit > 0) {
            if (!$istime && in_array($unitName, array("H", "M", "S"))) { // There may be a better way to do this
                $str .= "T";
                $istime = true;
            }
            $str .= strval($unit) . $unitName;
        }
    }

    return $str;
}
Run Code Online (Sandbox Code Playgroud)

结果:http://codepad.org/1fHNlB6e


Kar*_*lis 6

这是Eric time_to_iso8601_duration()函数的简化版本。它不会降低精度(一年大约365天),并且快大约5倍。根据页面,输出结果不太漂亮,但仍与ISO 8601兼容。

function iso8601_duration($seconds)
{
    $days = floor($seconds / 86400);
    $seconds = $seconds % 86400;

    $hours = floor($seconds / 3600);
    $seconds = $seconds % 3600;

    $minutes = floor($seconds / 60);
    $seconds = $seconds % 60;

    return sprintf('P%dDT%dH%dM%dS', $days, $hours, $minutes, $seconds);
}
Run Code Online (Sandbox Code Playgroud)