2017-04-13 122 views
6
$date1 = "2017-04-13 09:09:80:300" 
$date2 = "2017-04-13 09:09:80:400" 

比較我怎麼能檢查date2或多或少是100毫秒,則在$date 1和虛假如果不是(101 - 或多或少)毫秒PHP

回答

4

你的問題,雖然看似出現簡單,實際上相當難看,因爲PHP的strtotime()函數從時間戳中截斷毫秒。實際上,它甚至不會正確處理您的問題中的時間戳$date1$date2。一種解決方法是修剪時間戳的毫秒部分,使用strtotime()從紀元開始獲取毫秒數,然後使用正則表達式獲取並將毫秒部分添加到該數量。

$date1 = "2017-04-13 09:09:40:300"; 
$date2 = "2017-04-13 09:09:40:400"; 

preg_match('/^.+:(\d+)$/i', $date1, $matches); 
$millis1 = $matches[1]; 
$ts1 = strtotime(substr($date1, 0, 18))*1000 + $millis1; 
preg_match('/^.+:(\d+)$/i', $date2, $matches); 
$millis2 = $matches[1]; 
$ts2 = strtotime(substr($date2, 0, 18))*1000 + $millis2; 

if (abs($ts1 - $ts2) < 100) { 
    echo "within 100 millseconds"; 
} 
else { 
    echo "not within 100 millseconds"; 
} 

演示在這裏:

Rextester

+0

否否否不能那麼容易! +1 –

+0

@HankyPanky如果這是Postgres中的同一個問題,我已經在運行:-) –

+0

你試過了嗎?這個不成立。毫秒被剝離到秒比較......如果差值爲999,它將返回true – Peter

5

如果您將自己的這種格式的時間(我改變09:09:8009:09:40,因爲它是不正確的格式)

$date1 = "2017-04-13 09:09:40:300" 
$date2 = "2017-04-13 09:09:40:400" 

創建自定義功能,因爲strtotime不支持ms

function myDateToMs($str) { 
    list($ms, $date) = array_map('strrev', explode(":", strrev($str), 2)); 
    $ts = strtotime($date); 
    if ($ts === false) { 
     throw new \InvalidArgumentException("Wrong date format"); 
    } 
    return $ts * 1000 + $ms; 
} 

現在只是檢查確實差小於100

$lessOrEqual100 = abs(myDateToMs($date1) - myDateToMs($date2)) <= 100; 
+1

你的答案比我的+1更清潔。 –

1

根據第二的php manual for strtotime餾分是允許的,但目前由strtotime函數忽略。

這意味着你可以表達你的日期,這樣2017-04-13 09:00:20.100讓他們通過的strtotime沒有錯誤解析(讓他們futureproofed),然後使用自定義功能進行比較公正的日期的毫秒部分。如果時間戳相同

如果日期在100毫秒內,下面的函數將返回true,否則返回false。你可以通過數量來比較它們作爲參數。

<?php 
date_default_timezone_set ("UTC"); 

$date1 = "2017-04-13 09:00:20.100"; 
$date2 = "2017-04-13 09:00:20.300"; 

// pass date1, date2 and the amount to compare them by 
$res = compareMilliseconds($date1,$date2,100); 
var_dump($res); 

function compareMilliseconds($date1,$date2,$compare_amount){ 

    if(strtotime($date1) == strtotime($date2)){ 

     list($throw,$milliseond1) = explode('.',$date1); 
     list($throw,$milliseond2) = explode('.',$date2); 

     return (($milliseond2 - $milliseond1) < $compare_amount); 
    } 

} 


?> 
0

PHP 7.1,您可以用datetime對象做到這一點...

一定要與天的變化,以作爲成功過程的真實指標測試所有其他的答案。

Demo

代碼:

$dt1 = DateTime::createFromFormat('Y-m-d H:i:s:u e', "2017-04-14 0:00:00:000 UTC"); 
$dt2 = DateTime::createFromFormat('Y-m-d H:i:s:u e', "2017-04-13 23:59:59:999 UTC"); 
var_export($dt1->format('Y-m-d H:i:s:u')); 
echo "\n"; 
var_export($dt2->format('Y-m-d H:i:s:u')); 
echo "\n"; 
//var_export($dt1->diff($dt2)); 
echo "\n"; 
$diff=$dt1->diff($dt2); 
// cast $diff as an array so array_intersect_assoc() can be used 
if(sizeof(array_intersect_assoc(['y'=>0,'m'=>0,'d'=>0,'h'=>0,'i'=>0],(array)$diff))==5){ 
    // years, months, days, hours, and minutes are all 0 
    var_export($micro=round(abs($diff->s+$diff->f),3)); 
    // combine seconds with microseconds then test 
    echo "\n"; 
    if($micro>.1){ 
     echo "larger than .1"; 
    }else{ 
     echo "less than or equal to .1"; 
    } 
}else{ 
    echo "too large by units larger than seconds"; 
} 

輸出:

'2017-04-14 00:00:00:000000' 
'2017-04-13 23:59:59:999000' 

0.001 
less than or equal to .1