在PHP中毫秒比较

时间:2017-04-13 10:01:40

标签: php date time

$date1 = "2017-04-13 09:09:80:300" 
$date2 = "2017-04-13 09:09:80:400"

如何检查date2是否比$date 1更多或更少100毫秒,如果不是,则检查是否为假(101 - 更多或更少)

4 个答案:

答案 0 :(得分:5)

如果您以这种格式抽出时间(我将09:09:80更改为09:09:40,因为格式不正确)

$date1 = "2017-04-13 09:09:40:300" 
$date2 = "2017-04-13 09:09:40:400"

创建自定义函数,因为strtotime不支持ms

function myDateToMs($str) {
   list($ms, $date) = array_map('strrev', explode(":", strrev($str), 2));
   $ts = strtotime($date);
   if ($ts === false) {
       throw new \InvalidArgumentException("Wrong date format");
   }
   return $ts * 1000 + $ms;
}

现在只需检查差异是否小于100

$lessOrEqual100 = abs(myDateToMs($date1) - myDateToMs($date2)) <= 100;

答案 1 :(得分:4)

你的问题,虽然看似简单,但实际上相当丑陋,因为PHP的strtotime()函数会从时间戳中截断毫秒。实际上,它甚至无法正确处理您问题中的时间戳$date1$date2。一种解决方法是修剪时间戳的毫秒部分,使用strtotime()从纪元开始获取毫秒,然后使用正则表达式获取并将毫秒部分添加到此数量。

$date1 = "2017-04-13 09:09:40:300";
$date2 = "2017-04-13 09:09:40:400";

preg_match('/^.+:(\d+)$/i', $date1, $matches);
$millis1 = $matches[1];
$ts1 = strtotime(substr($date1, 0, 18))*1000 + $millis1;
preg_match('/^.+:(\d+)$/i', $date2, $matches);
$millis2 = $matches[1];
$ts2 = strtotime(substr($date2, 0, 18))*1000 + $millis2;

if (abs($ts1 - $ts2) < 100) {
    echo "within 100 millseconds";
}
else {
    echo "not within 100 millseconds";
}

在这里演示:

Rextester

答案 2 :(得分:2)

根据允许的php manual for strtotime分数,尽管strtotime函数当前忽略了它。

这意味着您可以像2017-04-13 09:00:20.100一样表达日期,让它们通过strtotime进行解析而不会出现错误(保持它们的防范),然后使用自定义函数比较日期的毫秒部分时间戳是相同的

如果日期在100毫秒内,则以下函数将返回true,否则返回false。您可以传入金额作为参数进行比较。

<?php
date_default_timezone_set ( "UTC" );

$date1 = "2017-04-13 09:00:20.100";
$date2 = "2017-04-13 09:00:20.300";

// pass date1, date2 and the amount to compare them by
$res = compareMilliseconds($date1,$date2,100);
var_dump($res);

function compareMilliseconds($date1,$date2,$compare_amount){

  if(strtotime($date1) == strtotime($date2)){

      list($throw,$milliseond1) = explode('.',$date1);
      list($throw,$milliseond2) = explode('.',$date2);

      return ( ($milliseond2 - $milliseond1) < $compare_amount);
  }

}


?>

答案 3 :(得分:1)

PHP 7.1允许您使用DateTime对象...

请务必使用更改日期来测试所有其他答案,作为成功流程的真实指标。

Demo

代码:

$dt1 = DateTime::createFromFormat('Y-m-d H:i:s:u e', "2017-04-14 0:00:00:000 UTC");
$dt2 = DateTime::createFromFormat('Y-m-d H:i:s:u e', "2017-04-13 23:59:59:999 UTC");
var_export($dt1->format('Y-m-d H:i:s:u'));
echo "\n";
var_export($dt2->format('Y-m-d H:i:s:u'));
echo "\n";
//var_export($dt1->diff($dt2));
echo "\n";
$diff=$dt1->diff($dt2);
// cast $diff as an array so array_intersect_assoc() can be used
if(sizeof(array_intersect_assoc(['y'=>0,'m'=>0,'d'=>0,'h'=>0,'i'=>0],(array)$diff))==5){
    // years, months, days, hours, and minutes are all 0
    var_export($micro=round(abs($diff->s+$diff->f),3));
    // combine seconds with microseconds then test
    echo "\n";
    if($micro>.1){
        echo "larger than .1";
    }else{
        echo "less than or equal to .1";
    }
}else{
    echo "too large by units larger than seconds";
}

输出:

'2017-04-14 00:00:00:000000'
'2017-04-13 23:59:59:999000'

0.001
less than or equal to .1