我有一些PHP代碼發送警告並自動關閉服務,如果源數據文件已過期。在夏令時變化時,filemtime可以與strtotime進行比較嗎?
警告: filemtime($file_location) < strtotime('-15 minute')
考慮服務下來: filemtime($file_location) < strtotime('-1 hour')
1小時,上午3:00開始CDT夏令時開始時,這錯誤地報告這是使用下面的做比較文件超過15分鐘。即將結束的時候,它也會錯誤地報告文件已超過1個小時。凌晨4點,CDT事情恢復正常。
有什麼我不知道可以解釋這種行爲的filemtime()或strtotime()函數嗎?這是我的理解,都返回UNIX時間戳,並且時間戳由UTC定義,所以我不知道是什麼會導致此問題。
基於答案爲止,我跑了我們的服務器在這個測試:
`
for($i = 1; $i <=4; $i++){
// let's say current time is this:
date_default_timezone_set('America/Winnipeg');
$current_timestamp = strtotime('2016-03-13 0'.$i.':00:00'); // 1457856060
// DST start at 03:00 that day, so 60 minutes before the time should be 01:01
$ts = $current_timestamp - 1*60*60;
echo '-3600s: ', $ts, ", ", date('Y-m-d H:i:s', $ts), "\n";
// 1457852460, 2016-10-30 02:59:00, correct
// now let's test strtotime with -1 hour
$ts = strtotime('-1 hour', $current_timestamp);
echo '-1 hour: ', $ts, ", ", date('Y-m-d H:i:s', $ts), "\n";
// 1457856060, 2016-10-30 03:01:00, completely wrong
// DateTime implementation seems smarter:
$dt = new DateTime();
$dt->setTimestamp($current_timestamp);
$dt->sub(new DateInterval('PT1H'));
echo 'sub PT1H: ', $dt->getTimestamp(), ", ", $dt->format('Y-m-d H:i:s'), "\n";
// 1457856060, 2016-10-30 03:01:00, correct
echo "\n\n";
echo 'TS ', $current_timestamp, ", ", date('Y-m-d H:i:s', $current_timestamp), "\n";
echo "\n\n";
}
`
-3600s:1457848800,2016年3月13日0點00分: 00
-1小時:1457848800,2016年3月13日〇點00分00秒
子PT1H:1457848800,2016-03 -13 0時00分○○秒
TS 1457852400,2016年3月13日1點00分00秒
-3600s:1457852400,2016年3月13日1點00分00秒
-1小時:1457856000,2016年3月13日三點00分00秒
子PT1H:1457856000,2016年3月13日三點00分00秒
TS 1457856000,2016年3月13日三點00分00秒
-3600s:1457852400,2016-03-13 01:00:00
-1小時:1457856000,2016年3月13日3點00分00秒
子PT1H:1457856000,2016年3月13日3點00分00秒
TS 1457856000,2016-03- 13 3時00分00秒
-3600s:1457856000,2016年3月13日3時00分00秒
-1小時:1457856000,2016年3月13日3時00分00秒
子PT1H:1457856000,2016-03-13 03:00:00
TS 1457859600,2016-03-13 04:00:00
開放的PHP錯誤可能是問題的根源,儘管我仍然不明白髮生了什麼。 – flergl
在上面的進一步測試中,通過從時間戳中減去3600得到的答案是正確的,而其他答案在從DT中的時間減去足夠的時間以將其帶回ST後是錯誤的。因此1am -1h總是午夜,4am -1h總是凌晨3點。凌晨2點和凌晨3點是**同一時間**。時間戳-3600正確返回1am,而在兩種情況下使用strtotime或DateInterval都不正確地返回3am(即沒有時間被減去)。 –