【问题标题】:Milliseconds compare in phpphp中的毫秒比较
【发布时间】:2017-04-13 10:01:40
【问题描述】:
$date1 = "2017-04-13 09:09:80:300" 
$date2 = "2017-04-13 09:09:80:400"

我如何检查 date2 是否或多或少 100 毫秒然后 $date 1 in 和 false 如果不是(101 - 或多或少)

【问题讨论】:

    标签: php date time


    【解决方案1】:

    您的问题虽然看似简单,但实际上相当难看,因为 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

    【讨论】:

    • 不不不,不可能这么简单! +1
    • @HankyPanky 如果这是 Postgres 中的同一个问题,我已经在运行了 :-)
    • 你试过了吗?这没有道理。毫秒被剥离到秒比较...如果毫秒差为 999,它将返回 true
    • @HankyPanky 不是
    • @TimBiegeleisen 编辑后仍然错误。 1990-04-13 09:09:80:3002017-04-13 09:09:80:300 将返回 true
    【解决方案2】:

    如果您以这种格式获取时间(我将 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干净。
    【解决方案3】:

    根据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);
      }
    
    }
    
    
    ?>
    

    【讨论】:

      【解决方案4】:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多