2016-03-24 47 views
1

我試圖在保存數據庫中的記錄後4小時後用cron執行php腳本。我的問題不在於cron,所有在這裏都可以正常工作(我確信這是因爲我每4個小時就會收到來自守護進程cron的測試郵件)。爲什麼時間戳unix time和time()不正確之間的區別?

問題是當我計算時間戳,轉換爲unix和當前時間之間的差異,然後執行一些腳本。

但是,這兩個時間差異是他們增加了3個小時,我不知道爲什麼,但我的腳本執行7小時後,而不是4小時。任何人都可以幫助我嗎?

我的代碼如下所示:

<?php 
require_once('some-path/wp-load.php'); 
global $wpdb; 
    $constant= 4*3600; 
    $table = 'notifications'; 
    $data = $wpdb->get_results("SELECT * FROM $table WHERE status = 'pending'"); 
    $time = time(); 

foreach ($data as $r){ 
    $temp_data = strtotime($r->date_created); 
    if ($time - $temp_data > $constant){ 
     $email = $r->email; 
     $message = 'test'; 
     $subject = 'test'; 
     $headers = 'From: test <[email protected]>' . "\r\n"; 
     $headers .= 'Content-type: text/html; charset=utf-8' . "\r\n"; 
     $mail_client = wp_mail($email, $subject, $message, $headers); 
     if($mail_client){ 
      $wpdb->update($tabel, array('status' => 'sent'), array('id_raport'=>$r->id_raport), array('%s'), array('%d')); 
     } 
    } 
} 

從數據庫Using strtotime(): 1458814621, Directly from database "2016-03-24 10:17:01"

現在最新的例子,我知道我可以做這樣的事情來獲得真正的本地時間:

date_default_timezone_set('Europe/Bucharest'); 
    $date = date('m/d/Y h:i:s a', time()); 
    $time = strtotime($date); 

更新。 但是這會返回與time()方法相同的結果。

+0

你能否提供數據庫返回的date_created的幾個版本? –

+4

您的時區距UTC有3小時嗎? –

+0

@LiamSorsby,我在問題的結尾添加了你問的內容。希望能幫助到你。謝謝。 – Ionut

回答

3

現在,我知道我可以做這樣的事情來獲得真正的本地時間:

date_default_timezone_set('Europe/Bucharest'); 
$date = date('m/d/Y h:i:s a', time()); 
$time = strtotime($date); 

Unix時間戳不是「本地」。 UNIX時間戳在全世界都是一樣的。你在這段代碼中所做的只是將時間戳(time())轉換爲可讀格式,然後將其重新解釋爲時間戳;結果與原始的time()值相同(或者至少應該是!)。

一個人類可讀的日期/時間的格式,如你從MySQL(2016-03-24 10:17:01)接收是不全沒有時區。 「2016-03-24 10:17:01」在世界各地有以上有超過24個不同的絕對時間點。時間戳本身並不意味着太多。
當您使用strtotime將其轉換爲UNIX時間戳時,它必須獲取附加信息以將這種不明確的相對時間格式轉換爲絕對時間點。這些信息來自date_default_timezone_set,或者任何在php.ini中設置的等價信息。

你的問題幾乎可以肯定歸結爲當PHP做的strtotime與你的MySQL日期時間字符串實際上不是相同的時區時。例如,如果您的MySQL日期時間表示UTC的時間,但strtotime將布加勒斯特假定爲使用時區,您將在所得到的絕對時間點上看到幾小時的差異。

只需在PHP代碼中設置/使用正確的時區;想想/意識到/決定什麼時區你的MySQL日期實際上是存儲英寸

另見Does PHP time() return a GMT/UTC Timestamp?

+0

是的,你是對的,時間()和我有什麼回報完全相同的UNIX值。 – Ionut

+0

那麼我還有什麼替代方法? – Ionut

+0

你需要什麼選擇? 1)找出/決定/考慮/冥想你的時間戳在MySQL中的時區。2)使用'date_default_timezone_set'設置該時區。 3)使用'strtotime'將MySQL時間戳轉換爲正確的UNIX時間戳。 - 這不適合你嗎? – deceze

1

time()(時間戳)返回的值是多少秒自1970年1月1日,00 :UTC時間00:00。這是一個絕對值。

從數據庫中檢索的值(2016-03-24 10:17:01)是相對值。它可以表示不同的時間戳,具體取決於您使用的時區。

如何使用DateTimeDateTimeZone類:

// Timestamp generated from PHP code 
// Current time 
$date1 = new DateTime(); // it uses the default timezone set in php.ini 
          // or by a previous call to date_default_timezone_set() 
// be more specific 
$date2 = new DateTime('now', new DateTimeZone('US/Eastern')); 
// $date1 and $date2 represent the same moment in time ("now") 
echo(($date1 == $date2) ? 'Yes' : 'No'); // It displays "Yes" 
// Display them as timestamps 
echo($date1->format('U'));  // 1458816551 
echo($date2->format('U'));  // also 1458816551 
// Display $date1 as human-readable format: 
echo($date1->format('Y-m-d H:i:s e')); 
// It displays: 2016-03-24 12:49:11 Europe/Bucharest 
// Change $date1 to use the same timezone as $date2 
$date1->setTimezone(new DateTimeZone('US/Eastern')); 
echo($date1->format('Y-m-d H:i:s e')); 
// Now it displays: 2016-03-24 06:49:11 US/Eastern 

// It provides easy ways to generate another date: 
$date3 = clone $date1;  // create a duplicate 
$date3->add(new DateInterval('P2D')); // modify the duplicate 
// $date3 is 2 days in the future 
echo($date3->format('Y-m-d H:i:s e')); 
// It displays: 2016-03-26 06:49:11 US/Eastern 

// Get the difference between $date3 and $date1 
$diff = $date3->diff($date1) 
// you get the difference in date components (days, hours, minutes etc). 
print_r($diff); 

一個你從數據庫中提取日期時間值是不完整的。它缺乏時區。如果您在過去將數據存儲在數據庫中,那麼您應該知道它使用的是什麼時區。如果使用SELECT NOW()從數據庫中獲取日期時間,則時區是服務器使用的默認時區。它存儲在system_time_zone服務器變量,可以與SELECT @@system_time_zone

查詢查詢:

SELECT NOW() AS now, @@system_time_zone AS tz 

返回本地日期和時間,由MySQL服務器使用的時區。

您可以使用它們來創建一個DateTime對象來使用,如上面提供的示例代碼。

作爲一般規則,對於在數據庫中存儲爲datetime的值,始終使用單個時間。我建議使用UTC,因爲一切都是相對的,它不會遵守DST。或者,您可以使用TIMESTAMP類型的列(絕對時間戳不關心時區和DST),但它們更難處理。

相關問題