【问题标题】:Time difference calculation in milliseconds in phpphp中以毫秒为单位的时差计算
【发布时间】:2014-02-06 08:39:27
【问题描述】:

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

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

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

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

是否有任何内置的 php 函数可用于此目的?还是我们应该编写我们的自定义逻辑来拆分这个时间然后计算差异?

【问题讨论】:

标签: php time milliseconds


【解决方案1】:

我的建议是先找出两次之间的秒差,忽略毫秒部分。

这么说,你有

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 这里你没有考虑毫秒部分。我修改了第一个函数并在下面发布
    • 我使用的修改函数如下。感谢提供的支持。 $t1="12:24:58:301"; $t2="12:25:30:302";函数 find_time_diff($t1, $t2) { $a1 = explode(":", $t1); $a2 = explode(":", $t2); $time1 = ((($a1[0] * 60 * 60) + ($a1[1] * 60) + ($a1[2]))*1000)+$a1[3]; $time2 = ((($a2[0] * 60 * 60) + ($a2[1] * 60) + ($a2[2]))*1000)+$a2[3]; $diff = abs($time1 - $time2);返回$差异; //这将返回以毫秒为单位的时间差 } 计算出的差值为 32001 毫秒 谢谢
    • 谢谢,我也会从你的帖子中受益:).. 如果我的帖子有帮助,请确保将其标记为已回答
    • 如果您有足够新的 PHP 版本,请使用 microtime(true) 以避免将秒和毫秒放在一起。
    【解决方案3】:

    试试这个功能:

    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

    【讨论】:

      【解决方案4】:

      @Glavic - 你的方法中有一个小错字,这一行:

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

      应该是:

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

      【讨论】:

        【解决方案5】:

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

        这意味着会有时间

        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()
            {
        

        第一个是自己的计数。如果 end 和 start 之间的差为正数(大于零),则按原样处理。

        但是如果 end 和 start 之间的差异是负数(因为 end 在午夜之后,而 start 在午夜之前,例如 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也是我的函数,可以换成你自己的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-22
          • 1970-01-01
          相关资源
          最近更新 更多