当前位置: 首页 > 知识库问答 >
问题:

如何将字符串持续时间转换为ISO 8601持续时间格式?(例如“30 分钟”到“PT30M”)

王飞虎
2023-03-14

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

所以我有一堆可读格式的持续时间字符串——我想动态地将它们转换成ISO 8601格式,以打印HTML5微数据的持续时间。下面是一些输入字符串的示例,以及它们应该如何格式化

"1 hour 30 minutes" --> PT1H30M
"5 minutes" --> PT5M
"2 hours" --> PT2H

我可以在PHP中将字符串推入间隔对象

date_interval_create_from_date_string("1 hour 30 minutes");

但似乎没有ISO 8601输出选项

我应该如何处理这个问题?

共有3个答案

慎俊雄
2023-03-14

另一种方法是基于DateInterval对象编写函数。ISO 8601持续时间格式被很好地描述了。

这种方法的优点是,它只输出相关(当前)表示,并且支持空持续时间(通常表示为<code>的‘PT0S’)。

function dateIntervalToISO860Duration(\DateInterval $d) {
    $duration = 'P';
    if (!empty($d->y)) {
        $duration .= "{$d->y}Y";
    }
    if (!empty($d->m)) {
        $duration .= "{$d->m}M";
    }
    if (!empty($d->d)) {
        $duration .= "{$d->d}D";
    }
    if (!empty($d->h) || !empty($d->i) || !empty($d->s)) {
        $duration .= 'T';
        if (!empty($d->h)) {
            $duration .= "{$d->h}H";
        }
        if (!empty($d->i)) {
            $duration .= "{$d->i}M";
        }
        if (!empty($d->s)) {
            $duration .= "{$d->s}S";
        }
    }
    if ($duration === 'P') {
        $duration = 'PT0S'; // Empty duration (zero seconds)
    }
    return $duration;
}

例如:

echo dateIntervalToISO860Duration(
    date_diff(
        new DateTime('2017-01-25 18:30:22'), 
        new DateTime('2019-03-11 07:12:17')
    )
);

输出:P2Y1M13DT12H41M55S

陆星文
2023-03-14

以下是Eric的<code>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);
}
咸昀
2023-03-14

我会先把它转换成一个数字,然后再处理它。

首先,使用strotime():

$time = strtotime("1 hour 30 minutes", 0);

然后您可以解析它的持续时间,并以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;
}

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

 类似资料:
  • 我正在寻找一种从“ISO 8601持续时间格式”(P0DT0H0M0S)转换为小时的便捷方法。 到目前为止,我想到了这个: 如您所见,我的方法是将数字拆分并乘以24、1、1/60、1/3600以得到小时。我可以减少代码量吗? 样本数据和所需结果 输入: 'P1DT2H3M44S' (1 天 2 小时 3 分 44 秒) 期望输出: 26.062222222222222 (这是小时)

  • 我有ISO8601格式的持续时间值,我将其转换为时间值为整数秒,如下所示: ISO8601格式的持续时间值=“P1Y”。 我将该值存储在“时间-单位-秒”中。因此,当我检索的值将是在int,我想转换回ISO8601持续时间格式,所以我应该得到“P1Y”转换后回来。 有没有快速的方法可以做到这一点?或者我必须把时间的int值转换成float,然后通过某种方法把它转换成ISO8601持续时间。

  • 目前,当您获得youtube持续时间时,您会获得类似的内容。 下面的代码将其更改为。然而,我希望只获得SECONDS,因此将是输出。

  • 问题内容: 我需要将持续时间字符串解析为毫秒形式。 我希望像这样的持续时间相等,但是我什么也找不到。有人会建议为此目的使用或支持SDF吗? 我目前的计划是使用正则表达式来匹配数字并做类似的事情 然后使用TimeUnit将它们放在一起并转换为毫秒。 我想我的问题是,这似乎有点过头了,它可以轻松完成吗?出现了很多有关日期和时间戳的问题,但这也许有些不同。 问题答案: 使用a 是一种合理的方法。但是,为

  • 在ISO 8601中,持续时间的格式为PT5M(5分钟)或PT2H5M(2小时5分钟)。我有一个JSON文件,其中包含这种格式的值。我想知道spark是否可以提取分钟的持续时间。我尝试将其读取为“DateType”,并使用“minutes”函数获取分钟数,结果返回空值。 示例json 目前,我正在将其作为字符串读取并使用“regex_extract”函数。我想知道一种更有效的方法。 https:/

  • 问题内容: 我想使用H:MM:SS之类的格式以秒为单位格式化持续时间。Java中的当前实用程序旨在格式化时间而不是持续时间。 问题答案: 如果你使用的Java版本早于8 …,则可以使用Joda Time和PeriodFormatter。如果你确实有持续时间(例如,经过的时间量,没有参考日历系统),那么你可能应该大部分时间都在使用-然后可以致电(指定要反映25小时是否变为25小时) 1天1小时与否,