2008-12-22 112 views
0

我有一個非常奇怪的錯誤出現在我得到的一些PHP代碼中。該頁面正在管理課程中的學生註冊。在頁面上是學生課程表,每一行都有許多日期:他們在何時註冊,何時完成,何時通過評估以及何時拿到證書。夏令時PHP日期問題

表數據由PHP(從數據庫中繪製數據)生成,而Javascript實際上呈現該表。從PHP的輸出是JS代碼看起來是這樣的:

var e = new Enrolment(); 
e.contactId = 5801; 
e.enrolId = 14834; 
e.courseId = 3; 
e.dateEnrolled = new Date(1219672800000); 
e.dateCompleted = new Date(-1000); // magic value meaning they haven't completed. 
e.resultDate = new Date(1223647200000); 
e.certDate = new Date(1223560800000); 
e.result = 95; 
e.passed = true; 
enrolments[14834] = e; 

在數據庫中,所有的日期字段存儲爲DATE(不DATETIME)領域。

錯誤在於日期顯示爲一天休息。我懷疑這與服務器處於夏令時的區域有很大關係,而這裏沒有任何(意味着服務器時間爲一小時)。這解釋了很多,尤其是如何在兩個不同的時區完成數據準備和渲染。即:服務器正在向客戶說明該人在8月15日午夜完工,客戶正在將其解釋爲14日晚上11點,因此在8月14日顯示。

但這是令人困惑的部分:它只對resultDate和certDate字段做這件事!我已將數據複製到本地服務器,並且發現生產服務器實際上只是爲這兩個字段發送了一個不同的時間戳(其中一個關閉了1小時),而dateEnrolled字段是相同的。

下面是一個使用完全相同的代碼和數據從數據庫輸出:

// local server (timezone GMT+1000) 
e.dateEnrolled = new Date(1219672800000); // 26 Aug 2008 00:00 +10:00 
e.dateCompleted = new Date(-1000); 
e.resultDate = new Date(1223647200000);  // 11 Oct 2008 00:00 +10:00 
e.certDate = new Date(1223560800000);  // 10 Oct 2008 00:00 +10:00 

// production server (timezone GMT+1100) 
e.dateEnrolled = new Date(1219672800000); // 26 Aug 2008 00:00 +10:00 
e.dateCompleted = new Date(-1000); 
e.resultDate = new Date(1223643600000);  // 10 Oct 2008 23:00 +10:00 ** 
e.certDate = new Date(1223557200000);  // 09 Oct 2008 23:00 +10:00 ** 

我可以理解,如果這是與夏令不被佔的問題,但要注意的dateEnrolled怎麼是一樣的嗎?

其MySQL的日期轉換爲unix時間戳的PHP代碼是這樣的:

list ($year, $month, $day) = explode ('-', $mysqlDT); 
$timestamp = mktime (0,0,0, $month, $day, $year); 

有關如何解決此問題的任何想法?

回答

3

那是因爲你使用的語言環境特定的mktime。也就是說,它會將其轉換爲格林威治標準時間1970年1月1日00:00:00之後的秒數,並用一個時區偏移1小時。

你還應該記住,JavaScript的確使用與瀏覽器相同的時區,而不是網頁。

e.resultDate = new Date(year, month - 1, day); 

這將確保每個時區的每個查看者的日期相同。

或者您可以使用gmmktime並在Date中使用UTC方法。

1

好吧,我只是想出了它爲什麼要剔除一個日期而不是另一個日期。八月份夏令時沒有生效。 捂臉

1
  1. 總是存儲在GMT/UTC日期/日期時間
  2. 採取在檢索這些值的查詢很好看,任何有關的那些不同進行調整?
  3. 如果不是,他們都是時間戳或日期或日期時間?
1

這很可能是日光節約問題。 它只爲resultDate和certDate這樣做的原因是dateEnrolled是在8月份,夏令時通常在9月底或10月初開始/結束。

0

使用apache.conf,.htaccess或ini_set()將date.timezone ini設置設置爲應用程序的時區。