php中的时差计算,以毫秒为单位

时间:2014-01-17 05:45:37

标签: php time milliseconds

我有一个用PHP编写的日志阅读程序。我想计算任何给定的两个日志行的时间差。 我发现很多代码用于计算时间差,如果两次给出的话就像

那样

$ TIME1 = '10:15:30' ;和$ time2 = '10:15:35';。这里的时差是5秒。

但是我的输入时间将采用以下格式 $ TIME1 = '10:15:30:300' ;和$ time2 = '11:15:35:450';

我想要一个能够接收这个时间作为输入的函数,并以毫秒为单位给出时间差。

是否有可用于此目的的内置PHP功能?或者我们应该编写我们的自定义逻辑来分割这个时间然后计算差异?

5 个答案:

答案 0 :(得分:0)

我的建议是找出忽略毫秒部分的2次之间的差异。

所以说,你有

$ TIME1 = '10:15:30:300' ; $ TIME2 = '11:15:35:450' ;

在这种情况下,您将看到秒差= 3605秒。 现在计算毫秒差异,并将其格式化为3605.150

如果毫秒差异为负,则将秒减1。

答案 1 :(得分:0)

可以帮助您进行与时间相关的开发和计算的两个函数如下

function find_time_diff($t1, $t2) {
    $a1 = explode(":", $t1);
    $a2 = explode(":", $t2);
    $time1 = (($a1[0] * 60 * 60) + ($a1[1] * 60) + ($a1[2]));
    $time2 = (($a2[0] * 60 * 60) + ($a2[1] * 60) + ($a2[2]));
    $diff = abs($time1 - $time2);
    return $diff;
}

和我最喜欢的......这可以在几分钟,几天,几年等时间内返回

 function find_date_diff($start_date, $end_date, $formatreturn = 'minutes') {
    list($date, $time) = explode(' ', $start_date);
    if ($time == null) {
        $time = '00:00:00';
    }
    if ($date == null) {
        $date = date("Y-m-d");
    }
    $startdate = explode("-", $date);
    $starttime = explode(":", $time);
    list($date, $time) = explode(' ', $end_date);
    if ($time == null) {
        $time = '00:00:00';
    }
    if ($date == null) {
        $date = date("Y-m-d");
    }
    $enddate = explode("-", $date);
    $endtime = explode(":", $time);

    $secons_dif = mktime($endtime[0], $endtime[1], $endtime[2], $enddate[1], $enddate[2], $enddate[0]) - mktime($starttime[0], $starttime[1], $starttime[2], $startdate[1], $startdate[2], $startdate[0]);
    switch ($formatreturn) {
        //In Seconds:
        case 'seconds':
            $choice = $secons_dif;
            break;
        //In Minutes:
        case 'minutes':
            $choice = floor($secons_dif / 60);
            break;
        //In Hours:
        case 'hours':
            $choice = floor($secons_dif / 60 / 60);
            break;
        //In days:
        case 'days':
            $choice = floor($secons_dif / 60 / 60 / 24);
            break;
        //In weeks:
        case 'weeks':
            $choice = floor($secons_dif / 60 / 60 / 24 / 7);
            break;
        //In Months:
        case 'months':
            $choice = floor($secons_dif / 60 / 60 / 24 / 7 / 4);
            break;
        //In years:
        case 'years':
            $choice = floor($secons_dif / 365 / 60 / 60 / 24);
            break;
    }
    $choice;
    return $choice;
}

答案 2 :(得分:0)

尝试此功能:

function mtime_difference($t1, $t2) {
    $t1 = DateTime::createFromFormat('H:i:s:u', $t1, new DateTimezone('UTC'));
    $t2 = DateTime::createFromFormat('H:i:s:u', $t2, new DateTimezone('UTC'));
    $diff = $t2->diff($t1);
    $seconds = $diff->h * 3600 + $diff->i * 60 + $diff->s;
    $u = $t1->format('u') - $t2->format('u');

    if ($u < 0) {
        $seconds--;
        $u = 1000000 - abs($u);
    }

    $u = substr(sprintf('%06d', $u), 0, 3);
    return $seconds . '.' . $u;
}

echo mtime_difference('11:15:35:450', '10:15:30:300');
# 3605.150

demo

答案 3 :(得分:0)

@Glavic - 你方法中的小错误,这一行:

$u = $t1->format('u') - $t2->format('u');

应该是:

$u = $t2->format('u') - $t1->format('u');

答案 4 :(得分:0)

起初,你的时间写错了。在毫秒之前应该有小数点。

这意味着会有时间

  

10:15:30.300和11:15:35.450

代替

  

10:15:30:300和11:15:35:450

但是在下面写的课程中你可以改进模式,以适应你的时间格式。或者改变整个检查。

对于类似的情况我最近必须解决(阅读由智能手机/平板电脑 app IoTools创建的csv文件并计算时间间隔内的毫秒差异),并基于问题How to get time difference in milliseconds,我准备好的课程 - 但只能在一天(24小时)的范围内。

它并不完美(因为它可以获得更多选项),但它计算得很好(我希望它做得很好,我还没有测试过很多)。

对于这个答案,我删除了抛出异常的细节,并按其值重写了一些常量。我还删除了注释以缩短代码,但用描述性文本替换它们。

class DayTimeCount
{

时间转换为毫秒。因此,这两个变量可以输入为integer

    protected $Time_Start = 0;
    protected $Time_End = 0;

时间刻度也可以是整数。这个变量的名称可能有点不幸,因为它没有完全正确地说出它的用途。

    protected $Time_Scale = 1;

此变量可以是常量。它的内容根本没有改变。

    private $TimePattern = '/(?<Hours>[0-9]{2})\:(?<Minutes>[0-9]{2})\:(?<Seconds>[0-9]{2}).(?<Milliseconds>[0-9]{0,3})/';

此功能用于设置开始时间(需要计数的开始间隔时间)。检查时间是否设置为正确的模式(如上面写的字符串对应模式,而不是整数),时间转换为毫秒。

    public function Set_StartTime($Time = NULL)
    {
        try
        {
            if( !preg_match($this -> TimePattern, $Time, $TimeUnits) )
            {
                throw new Exception(/* some code */);
            }
        }
        catch( Exception $Exception )
        {
            $Exception -> ExceptionWarning(/* some code */);
        }

        $this -> Time_Start = ($TimeUnits['Hours'] * 60 * 60 * 1000) + ($TimeUnits['Minutes'] * 60 * 1000) + ($TimeUnits['Seconds'] * 1000) + $TimeUnits['Milliseconds'];
    }

此功能与之前类似,但用于设置结束时间(需要计算结束间隔的时间)。

    public function Set_EndTime($Time = NULL)
    {
        try
        {
            if( !preg_match($this -> TimePattern, $Time) )
            {
                throw new Exception(/* some code */);
            }
        }
        catch( Exception $Exception )
        {
            $Exception -> ExceptionWarning(/* some code */);
        }

        $this -> Time_End = ($TimeUnits['Hours'] * 60 * 60 * 1000) + ($TimeUnits['Minutes'] * 60 * 1000) + ($TimeUnits['Seconds'] * 1000) + $TimeUnits['Milliseconds'];
    }

此功能用于设置时间刻度。它有助于将毫秒转换为秒(精度为毫秒)或分钟或小时。

静态函数Check_IsTimeScale是我自己的函数,可用作in_array()

    public function Set_TimeScale($Scale = 1)
    {
        try
        {
            if( !Core::Check_IsTimeScale($Scale) )
            {
                throw new Exception(/* some code */);
            }
        }
        catch( Exception $Exception )
        {
            $Exception -> ExceptionWarning(/* some code */);
        }

        $this -> Time_Scale = $Scale;
    }

最后,功能是自己计算时差。它只有三个步骤。

    public function Execute()
    {

第一个是自己的计数。如果结束和开始之间的差异是正数(大于零),则按原样采用。

但是如果结束和开始之间的差异为负(因为结束是在午夜之后并且开始是在午夜之前,例如00:00:00.658和23:59:59:354),则需要使用额外的计数。在一天的开始时间和全天时间之间做出区别 - 并添加结束时间。

    $Diff = $this -> Time_End - $this -> Time_Start;

    if( $Diff < 0 )
    {
        $Diff = $this -> Time_End + (86400000 - $this -> Time_Start);
    }

第二步,应用时间刻度。以毫秒为单位的时间除以时间刻度。如果除以1,结果(当然)与原始数字相同,并且没有舍入。如果它除以较大的数字(允许选项中的1000或更大),则将其四舍五入为用于除以它的数字的长度。

        $Diff = round($Diff / $this -> Time_Scale, strlen($this -> Time_Scale));

第三步是返回最终结果。可能它可以与之前的步骤合并,但现在它(至少)更好的可读性。

        return $Diff;
    }
}

函数ExceptionWarning也是我的函数,可以用你自己的函数代替。