使 if 语句了解哪个 "time-left" 格式更大

Make an if-statement understand which "time-left" format is bigger

我正在尝试创建一个 IF 语句来计算哪个 "time-left" 更大。 这是我的代码。

if('6h : 27m : 45s' > '6h : 27m : 15s') {
    echo 'Timer to the left is bigger';
}

这段代码工作正常,它实际上打印了左边的计时器更大

但是,当任何时间值(小时、分钟或秒)只有一位而不是两位时。它不起作用。像这样:

if('6h : 27m : 45s' > '6h : 27m : 5s') {
    echo 'Timer to the left is bigger';
}

这次它没有打印出左边的计时器更大。这是因为右边的定时器只剩下5s,比15s少了,但是因为只有一位,而不是二,IF 语句不理解。

如何将其解析为 if 语句的可理解格式?

注意字符串来自API,无论如何我都无法编辑它。

这不是最漂亮的方法,但由于您从 API 中获取返回的数据,因此您无法修改,因此您必须使用获取的数据。

有几种方法可以做到这一点。一种方法是将时间转换为秒,然后进行比较。另一个是将它们转换为对象 - 并使用它。 "gruntwork" 是一样的;您必须将数据拆分为小时、分钟和秒,然后使用它——这比格式 Xh : Ym : Zs.

更有用

这里我们用分隔符 : 将每次分成三个部分。这让我们得到了各个部分 - 但我们仍然需要获取整数值,这是我们感兴趣的。我们可以通过使用 inval() 来获取它,因为数字在前。一旦我们有了这三部分,我们可以将它们放入 HH:mm:ss 格式,或者您可以将它们乘以所有以秒为单位的内容,然后将它们相加(第一个是小时,第二个是分钟,第三个是秒) .这里我们不这样做,我们以可读的格式将它们粘合在一起,并使用 strtotime() 将它们转换为时间戳 - 经过所有这些工作,我们终于可以比较它了!

$time_left = '6h : 27m : 45s';
$time_right = '6h : 27m : 5s';
$parts_left = explode(":", $time_left);
$parts_right = explode(":", $time_right);

$left = intval($parts_left[0]).":".intval($parts_left[1]).":".intval($parts_left[2]);
$right = intval($parts_right[0]).":".intval($parts_right[1]).":".intval($parts_right[2]);

if (strtotime($left) > strtotime($right)) {
    echo 'Timer to the left is bigger';
}

根据您编辑的评论,小时可以大于 24 - 在这种情况下,您需要将小时和分钟转换为秒,然后求和。

$time_left = '6h : 27m : 45s';
$time_right = '6h : 27m : 5s';
$parts_left = explode(":", $time_left);
$parts_right = explode(":", $time_right);

$left = intval($parts_left[0]) * 60*60 + intval($parts_left[1])*60 + intval($parts_left[2]);
$right = intval($parts_right[0]) * 60*60 + intval($parts_right[1])*60 + intval($parts_right[2]);

if ($left > $right) {
    echo "Timer to the left is bigger";
}

您的 post 建议所有三个时间单位始终可用。因此,只需根据需要创建两个数字数组即可。 PHP7的飞船运算符在处理两个数值时会进行数值比较。它将根据您的需要从左到右比较元素。

不需要时间解析,因为时间单位是从大到小排列的。

代码:(Demo)

$left = '6h : 27m : 5s';
$right = '6h : 27m : 15s';

$lookup = [
    -1 => 'less',
    0 => 'equal',
    1 => 'more'
];

$lArray = preg_split('/\D+/', $left, 0, PREG_SPLIT_NO_EMPTY);
$rArray = preg_split('/\D+/', $right, 0, PREG_SPLIT_NO_EMPTY);

$comparison = $lArray <=> $rArray;
echo $comparison . ' -> ' . $lookup[$comparison];

输出:

-1 -> less

如果这就是您所需要的,您可以为 -1 写一个条件检查。查找纯粹是为了澄清演示。

换句话说:

if ((preg_split('/\D+/', $left, 0, PREG_SPLIT_NO_EMPTY) <=> preg_split('/\D+/', $right, 0, PREG_SPLIT_NO_EMPTY)) == -1) {
    // left is less than right
}

或者使用非正则表达式替代方法,将每个匹配的数字转换为整数,然后比较两个生成的数组,每个数组包含三个整数。 (Demo)

$format = '%dh : %dm %ds';
$comparison = sscanf($left, $format) <=> sscanf($right, $format);

我刚刚注意到 Wiimm 的开箱即用调用 version_compare() 来解析您的时间表达式。 (来自我的+1,但我想我需要更多地解释它)虽然不是它的预期用途,但它是一种聪明可靠的非正则表达式技术,因为你的时间单位子字符串(hm , s) 未在具有特殊含义的开发阶段子字符串列表中找到 在两个字符串中统一定位。这意味着即使您有具有特殊含义的非数字子字符串,仍然可以仅根据数值正确评估比较。

特殊子字符串顺序:

  • dev
  • alphaa
  • betab
  • RCrc
  • #
  • plp

这个功能是一个三向比较工具——就像宇宙飞船操作员一样。它还接受第三个参数来命令它 return 是一个布尔响应。如果第一个字符串“大于”第二个字符串,则使用 gt 将 return true。虽然第三个参数是缩写,但我发现它比检查 -1.

更直观

代码:(Demo)

if (version_compare($left, $right, 'gt')) {
    echo 'left is greater than right';
} else {
    echo 'left is less than or equal to right';
}

输出:

left is less than or equal to right

php 函数 version_compare() 类似于 strcmp(),但将数字作为单个单位进行比较。由于(实际上)转换字符,它有一些副作用,但我认为这里无关紧要:

所以

if('6h : 27m : 45s' > '6h : 27m : 15s')

变成

if( version_compare('6h : 27m : 45s','6h : 27m : 15s') > 0 )