简体   繁体   English

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

[英]Time difference calculation in milliseconds in php

I Have a log reading program written in PHP. 我有一个用PHP编写的日志阅读程序。 I want to calculate the time difference of any given two log lines. 我想计算任何给定的两个日志行的时间差。 I found lot of code for calculating the time difference if the two times are give like 我发现很多代码用于计算时间差,如果两次给出的话

$time1='10:15:30'; $ TIME1 = '10:15:30' ; and $time2='10:15:35';. 和$ time2 = '10:15:35';。 here the time difference will be 5 seconds. 这里的时差是5秒。

But here my input times will be as in the following format $time1='10:15:30:300'; 但是在这里我的输入时间将是以下格式:$ time1 = '10:15:30:300'; and $time2='11:15:35:450'; 和$ time2 = '11:15:35:450';

I want a function which will receive this times as inputs and give the time difference in milliseconds. 我想要一个函数,它将接收这个时间作为输入,并给出时间差,以毫秒为单位。

Is there any inbuilt php function that can be utilized for this purpose ? 是否有任何内置的PHP功能可以用于此目的? or should we write our custom logic to split this time and then calculate the difference ? 或者我们应该编写我们的自定义逻辑来分割这个时间然后计算差异?

My suggestion would be to find the difference in seconds first between the 2 times ignoring the milliseconds part. 我的建议是找出忽略毫秒部分的2次之间的差异。

So say, you have 所以说,你有

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

In this case you will see that the seconds difference = 3605 seconds. 在这种情况下,您将看到秒差= 3605秒。 Now calculate the milliseconds difference and maybe format it as 3605.150 现在计算毫秒差异,并将其格式化为3605.150

If the milliseconds difference is negative, reduce the second by 1. 如果毫秒差异为负,则将秒减1。

Two functions which may help you with your time related development and calculations are the following 可以帮助您进行与时间相关的开发和计算的两个功能如下

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;
}

and my favorite... this can return in minutes, days,years and so on 而我最喜欢的......这可以在几分钟,几天,几年等时间内返回

 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;
}

Try this function: 试试这个功能:

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 演示

@Glavic - small typo in your method, this line: @Glavic - 你方法中的小错字,这一行:

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

should be: 应该:

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

At first, your times are written wrong. 起初,你的时间写错了。 There should be decimal dot before milliseconds. 在毫秒之前应该有小数点。

It means there will be times 这意味着有时会

10:15:30.300 and 11:15:35.450 10:15:30.300和11:15:35.450

instead 代替

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

But in class written below you could improve pattern to it would fit your time formatting. 但是在下面写的课程中你可以改进模式,以适应你的时间格式。 Or change whole checking. 或者改变整个检查。

For similar case I had to solve very recently (reading of csv files created by smartphone/tablet app IoTools and counting milliseconds differences between times), and based on question How to get time difference in milliseconds , I prepared class that does it - but only within range of one day (24 hours). 对于类似的情况,我最近必须解决(阅读由智能手机/平板电脑应用程序 IoTools创建的csv文件并计算毫秒之间的毫秒差异),并根据问题如何获得以毫秒为单位的时间差 ,我准备了这样做的类 - 但仅限于在一天(24小时)的范围内。

It is not perfect (as it could get some more options) but it computes well (I hope that it does well, I have not tested it much). 它并不完美(因为它可以获得更多选项),但它计算得很好(我希望它做得好,我没有测试过多)。

For this answer, I deleted details of exceptions throwing and rewrote some constants by their values. 对于这个答案,我删除了抛出异常的细节,并通过它们的值重写了一些常量。 Also I deleted annotations to make code shorter, but replaced them with descripting texts. 我还删除了注释以使代码更短,但用描述文本替换它们。

class DayTimeCount
{

Times are converted into milliseconds. 时间转换为毫秒。 So, these two variables may be typed as integer . 因此,这两个变量可以输入为integer

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

Also time scale may be as integer. 时间尺度也可以是整数。 Name of this variable may be a bit unfortunate, as it is not fully correctly saying for what purpose it is used. 这个变量的名称可能有点不幸,因为它没有完全正确地说出它的用途。

    protected $Time_Scale = 1;

This variable could be a constant. 这个变量可以是常数。 Its content is not changed at all. 它的内容根本没有改变。

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

This function is for setting of start time (time when starts interval you need to count). 此功能用于设置开始时间(需要计数的启动间隔时间)。 After checking if time is set in correct pattern (as string corresponding pattern writen above, not integer), time is converted into milliseconds. 检查时间是否设置为正确的模式(如上面写的字符串对应模式,而不是整数),时间转换为毫秒。

    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'];
    }

This function is similar to previous, but for setting of end time (time when ends interval you need to count). 此功能与之前类似,但用于设置结束时间(需要计算结束间隔的时间)。

    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'];
    }

This function is for setting of time scale . 此功能用于设置时间刻度 It helps to convert milliseconds to seconds (with precision of milliseconds) or minutes or hours. 它有助于将毫秒转换为秒(精度为毫秒)或分钟或小时。

Static function Check_IsTimeScale is my own function that works as in_array() . 静态函数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;
    }

And finally, function is for own counting of time difference. 最后,功能是自己计算时差。 It has only three steps. 它只有三个步骤。

    public function Execute()
    {

The first one is own counting. 第一个是自己的计数。 If difference between end and start is positive number (greater than zero), it is taken as it is. 如果结束和开始之间的差异是正数(大于零),则按原样采用。

But if difference between end and start is negative (as end is after midnight and start is before midnight, for example 00:00:00.658 and 23:59:59:354), then it is needed to use additional counting. 但如果结束和开始之间的差异是负的(因为结束是在午夜之后并且开始是在午夜之前,例如00:00:00.658和23:59:59:354),则需要使用额外的计数。 To make difference between start and full time of day - and add end time. 在一天的开始时间和全天时间之间做出区别 - 并添加结束时间。

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

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

The second step, application of time scale . 第二步,应用时间尺度 Time in milliseconds is divided by time scale . 以毫秒为单位的时间除以时间刻度 If it is divided by 1, result is (of course) the same as original number and it is no rounded. 如果除以1,结果(当然)与原始数字相同,并且没有舍入。 If it is divided by larger number (1000 or greater from allowed options), it is rounded to length of number used to divide it. 如果它除以较大的数字(允许选项中的1000或更大),则将其四舍五入为用于除以它的数字的长度。

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

Third step is returning of final result. 第三步是返回最终结果。 Probably it could be merged with previous step, but now it is (at least) better readable. 可能它可以与前一步合并,但现在它(至少)更好的可读性。

        return $Diff;
    }
}

Function ExceptionWarning is also my function, and can be replaced by your own one. 函数ExceptionWarning也是我的函数,可以用你自己的函数代替。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM