我有一个用PHP编写的日志阅读程序。我想计算任何给定的两个日志行的时间差。 我发现很多代码用于计算时间差,如果两次给出的话就像
那样$ TIME1 = '10:15:30' ;和$ time2 = '10:15:35';。这里的时差是5秒。
但是我的输入时间将采用以下格式 $ TIME1 = '10:15:30:300' ;和$ time2 = '11:15:35:450';
我想要一个能够接收这个时间作为输入的函数,并以毫秒为单位给出时间差。
是否有可用于此目的的内置PHP功能?或者我们应该编写我们的自定义逻辑来分割这个时间然后计算差异?
答案 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
答案 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
也是我的函数,可以用你自己的函数代替。