【问题标题】:Difference with microseconds precision between two DateTime in PHPPHP中两个DateTime之间的微秒精度差异
【发布时间】:2013-08-15 15:43:06
【问题描述】:

我可以在 PHP 中获得一个微秒的日期时间,解决方法如下:

list($usec, $sec) = explode(" ", microtime());
echo date("Y-m-d\TH:i:s", $sec) . "." . floatval($usec)*pow(10,6);

我需要两个日期时间之间的微秒差异,无法解决:

$datetime1 = new DateTime('2013-08-14 18:49:58.606');
$datetime2 = new DateTime('2013-08-14 22:27:19.272');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%h hours %i minutes %s seconds %u microseconds');

DateInterval::format 没有格式字符 %u 或微秒的等效字符。

有人知道解决方法吗?

【问题讨论】:

  • DateInterval 不支持微秒。而且DateTime 也不支持它们。您必须手动进行所有相关计算才能达到这样的精度。
  • DateTime::createFromFormat() 最近添加了 u 格式(PHP 5.5?),但我找不到任何证据表明它受 DAteInterval 支持
  • @Baldrs 我知道,但是使用时间函数很容易出错,我要求一种解决方法,一种非标准解决方案。
  • @MarkBaker 我正在使用 PHP 5.5.1 %u 是这样打印的
  • 作为参考,PHP 7.1 已将 Ff 添加到 DateInterval::format 微秒(分别带有和不带前导零)。

标签: php precision datediff


【解决方案1】:
/**
 * returns the difference in seconds.microseconds(6 digits) format between 2 DateTime objects 
 * @param DateTime $date1
 * @param DateTime $date2
 */
function mdiff($date1, $date2){
    return number_format(abs((float)$date1->format("U.u") - (float)$date2->format("U.u")), 6);
}

【讨论】:

  • 效果很好,对于这些数据:2021-01-27 11:56:19.198768 和 2021-01-27 11:56:20.199023 ,返回 1.000255
【解决方案2】:

手动创建一个带微秒的 DateTime 对象:

$d = new DateTime("15-07-2014 18:30:00.111111");

以微秒为单位获取当前时间的 DateTime 对象:

$d = date_format(new DateTime(),'d-m-Y H:i:s').substr((string)microtime(), 1, 8);

两个 DateTime 对象之间的差异(以微秒为单位)(例如返回:2.218939)

//Returns the difference, in seconds, between two datetime objects including
//the microseconds:

function mdiff($date1, $date2){
//Absolute val of Date 1 in seconds from  (EPOCH Time) - Date 2 in seconds from (EPOCH Time)
$diff = abs(strtotime($date1->format('d-m-Y H:i:s.u'))-strtotime($date2->format('d-m-Y H:i:s.u')));

//Creates variables for the microseconds of date1 and date2
$micro1 = $date1->format("u");
$micro2 = $date2->format("u");

//Absolute difference between these micro seconds:
$micro = abs($micro1 - $micro2);

//Creates the variable that will hold the seconds (?):
$difference = $diff.".".$micro;

return $difference;
}

本质上,它使用 strtotime 找到 DateTime 对象的差异,然后添加额外的微秒。

【讨论】:

  • 你为什么使用 strtotime($date1->format('d-m-Y H:i:s.u')) 而不是 strtotime($date1->format('d-m-Y H:i:s' ))?
  • 我想这并没有什么不同,因为 u 值总是相同的
  • 您的代码有错误,对于这些数据:2021-01-27 11:56:19.198768 和 2021-01-27 11:56:20.199023,返回 1.255,但更正为:1.000255
【解决方案3】:

自 PHP 7.1 (2016-12-01) 以来,%f and %F 的精度为微秒,但仅从 7.2 (2017-11-30) 开始,由于 7.1 中的关键日期错误(已测试),它可以安全使用)

工作示例:

<?php
$datetime1 = new DateTime('2013-08-14 18:49:58.800');
$datetime2 = new DateTime('2013-08-14 22:27:19.900');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%h hours %i minutes %s seconds %f microseconds');

PD:回答我在 %f 存在前 4 年发布的问题

【讨论】:

    【解决方案4】:

    我不得不更换这个

    $micro = abs($micro1 - $micro2);
    

    有了这个

    str_pad(abs($micro1 - $micro2), 6, '0', STR_PAD_LEFT);
    

    出于某种原因获得正确的微时间。

    【讨论】:

      【解决方案5】:
      function mdiff($date1, $date2){
        //Absolute val of Date 1 in seconds from  (EPOCH Time) - Date 2 in seconds from (EPOCH Time)
        $diff = abs(strtotime($date1->format('d-m-Y H:i:s.u'))-strtotime($date2->format('d-m-Y H:i:s.u')));
      
        //Creates variables for the microseconds of date1 and date2
        $micro1 = $date1->format("u");
        $micro2 = $date2->format("u");
      
        //Difference between these micro seconds:
        $diffmicro = $micro1 - $micro2;
      
        list($sec,$micro) = explode('.',((($diff) * 1000000) + $diffmicro )/1000000);
      
        //Creates the variable that will hold the seconds (?):
        $difference = $sec . "." . str_pad($micro,6,'0');
      
        return $difference;
      }
      

      这个函数返回正确的差值

      Example:
          Start:"2016-10-27 17:17:52.576801"
          End:"2016-10-27 17:18:00.385801"
          Difference:"7.809000"
      
          Old Function:
          Difference:"8.191000"
      

      【讨论】:

      • 您的代码有错误,对于这些数据:2021-01-27 11:56:19.198768 和 2021-01-27 11:56:20.199023,返回 0.998759,但更正为:1.000255
      【解决方案6】:

      返回浮点的较短版本

      function diff(\DateTimeInterface $a, \DateTimeInterface $b): float
      {
          return ($a->getTimestamp() - $b->getTimestamp()) + ($a->format("u") - $b->format("u")) / 1000000;
      }
      

      【讨论】:

      • 对于这些数据:2021-01-27 11:56:19.198768 和 2021-01-27 11:56:20.199023 ,返回 -1.000255 ,我认为返回正数更好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-15
      相关资源
      最近更新 更多