是否有 php 函数或更有效的方法将两个 iso 8601 时间加在一起?
Is there a php function or more efficient way to add two iso 8601 times together?
我找不到帮助我执行以下操作的方法。我得到以下两个时间值:PT1H30M 和 PT1H45M。我的目标是将两个时间值相加得到 PT2H5M.
有什么函数或更有效的写法吗?
这是我对通过的每个参数所做的:
- 从时间值中删除 PT。
- 将??H 和??M 提取到单独的变量中。
- 从这些变量中删除了 H 和 M,并确保剩余的值是 int 类型。
- 将两个小时值和两个分钟值相加。
- 如果分钟数总和超过 59,则将其分解并添加到小时数中。
- 结果作为两个时间值的总和返回。
这是我的代码示例:
//* _h is short for hours and _m is short for minutes
function iso8601TimeSum($t1 = '', $t2 = '') {
if(!$t1 && !$t2)
return '';
//remove PT
$t1 = str_replace('PT', '', $t1);
$t2 = str_replace('PT', '', $t2);
//extract ??[H|h] and ??[M|m]
$t1h_found = preg_match('/[00-59][Hh]/i', $t1, $t1_h);
$t1m_found = preg_match('/[00-59][Mm]/i', $t1, $t1_m);
$t2h_found = preg_match('/[00-59][Hh]/i', $t2, $t2_h);
$t2m_found = preg_match('/[00-59][Mm]/i', $t2, $t2_m);
//remove H|h and M|m from extracted values
if($t1h_found)
$t1_h = intval(preg_replace('/[Hh]/i', '', $t1_h[0]));
if($t1m_found)
$t1_m = intval(preg_replace('/[Mm]/i', '', $t1_m[0]));
if($t2h_found)
$t2_h = intval(preg_replace('/[Hh]/i', '', $t2_h[0]));
if($t2m_found)
$t2_m = intval(preg_replace('/[Mm]/i', '', $t2_m[0]));
//add it together
$calc_t_h = (!empty($t1_h) ? $t1_h : 0) + (!empty($t2_h) ? $t2_h : 0);
$calc_t_m = (!empty($t1_m) ? $t1_m : 0) + (!empty($t2_m) ? $t2_m : 0);
//if minutes exceeds 59 break it down and add it to the hours.
if($calc_t_m > 59) {
$calc_t_h += round($calc_t_m / 60);
$calc_t_m = $calc_t_m % 60;
}
return 'PT' . ($calc_t_h > 0 ? $calc_t_h . 'H' : '00H') . ($calc_t_m > 0 ? $calc_t_m . 'M' : '00M');
}
var_dump(iso8601TimeSum('PT1H30M', 'PT1H45M'));
//*/
你应该使用 DateTime
对象,有一些方便的函数可以根据格式解析日期:检查 http://php.net/manual/en/datetime.createfromformat.php
DateTime
对象也可以用于数学运算。我个人使用这个包装器:https://github.com/briannesbitt/Carbon
那么实现您的逻辑会容易得多
我找不到帮助我执行以下操作的方法。我得到以下两个时间值:PT1H30M 和 PT1H45M。我的目标是将两个时间值相加得到 PT2H5M.
有什么函数或更有效的写法吗?
这是我对通过的每个参数所做的:
- 从时间值中删除 PT。
- 将??H 和??M 提取到单独的变量中。
- 从这些变量中删除了 H 和 M,并确保剩余的值是 int 类型。
- 将两个小时值和两个分钟值相加。
- 如果分钟数总和超过 59,则将其分解并添加到小时数中。
- 结果作为两个时间值的总和返回。
这是我的代码示例:
//* _h is short for hours and _m is short for minutes
function iso8601TimeSum($t1 = '', $t2 = '') {
if(!$t1 && !$t2)
return '';
//remove PT
$t1 = str_replace('PT', '', $t1);
$t2 = str_replace('PT', '', $t2);
//extract ??[H|h] and ??[M|m]
$t1h_found = preg_match('/[00-59][Hh]/i', $t1, $t1_h);
$t1m_found = preg_match('/[00-59][Mm]/i', $t1, $t1_m);
$t2h_found = preg_match('/[00-59][Hh]/i', $t2, $t2_h);
$t2m_found = preg_match('/[00-59][Mm]/i', $t2, $t2_m);
//remove H|h and M|m from extracted values
if($t1h_found)
$t1_h = intval(preg_replace('/[Hh]/i', '', $t1_h[0]));
if($t1m_found)
$t1_m = intval(preg_replace('/[Mm]/i', '', $t1_m[0]));
if($t2h_found)
$t2_h = intval(preg_replace('/[Hh]/i', '', $t2_h[0]));
if($t2m_found)
$t2_m = intval(preg_replace('/[Mm]/i', '', $t2_m[0]));
//add it together
$calc_t_h = (!empty($t1_h) ? $t1_h : 0) + (!empty($t2_h) ? $t2_h : 0);
$calc_t_m = (!empty($t1_m) ? $t1_m : 0) + (!empty($t2_m) ? $t2_m : 0);
//if minutes exceeds 59 break it down and add it to the hours.
if($calc_t_m > 59) {
$calc_t_h += round($calc_t_m / 60);
$calc_t_m = $calc_t_m % 60;
}
return 'PT' . ($calc_t_h > 0 ? $calc_t_h . 'H' : '00H') . ($calc_t_m > 0 ? $calc_t_m . 'M' : '00M');
}
var_dump(iso8601TimeSum('PT1H30M', 'PT1H45M'));
//*/
你应该使用 DateTime
对象,有一些方便的函数可以根据格式解析日期:检查 http://php.net/manual/en/datetime.createfromformat.php
DateTime
对象也可以用于数学运算。我个人使用这个包装器:https://github.com/briannesbitt/Carbon
那么实现您的逻辑会容易得多