0

私が持っているいくつかの PHP コードで、非常に奇妙なバグが発生しました。このページでは、コースへの学生の登録を管理しています。このページには学生のコースの表があり、各行にはいくつかの日付があります: 入学日、修了日、評価に合格した日、証明書を受け取った日です。

テーブル データは PHP によって生成され (DB からデータを引き出します)、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) フィールドとして保存されます。

バグは、日付が 1 日オフとして表示されていることです。これは、サーバーが夏時間のある地域にあることに大きく関係していると思われますが、ここでは夏時間はありません (つまり、サーバー時間は 1 時間ずれています)。これは、特にデータの準備とレンダリングが 2 つの異なるタイムゾーンでどのように行われているかを説明しています。つまり、サーバーは、8 月 15 日の午前 0 時に完了したことをクライアントに伝え、クライアントはそれを 14 日の午後 11 時と解釈し、8 月 14 日を表示します。

しかし、ここで紛らわしい部分があります。これは、resultDate および certDate フィールドに対してのみ行っていることです。データをローカル サーバーにコピーしたところ、本番サーバーが実際にはこれら 2 つのフィールドに対して異なるタイムスタンプ (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);

これを修正する方法についてのアイデアはありますか?

4

5 に答える 5

3

これは、ロケール固有の mktime を使用しているためです。つまり、00:00:00 1970-1-1 GMT からの秒数に変換され、1 つのタイムゾーンで 1 時間オフセットされます。

また、JavaScript は Web ページではなくブラウザと同じタイムゾーンを使用することにも注意してください。

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

これにより、すべてのタイムゾーンのすべての視聴者の日付が同じになります。

または、gmmktime を使用して、Date で UTC メソッドを使用することもできます。

于 2008-12-22T03:05:01.850 に答える
1
  1. 日付/日時は常にGMT/UTCで保存してください
  2. これらの値を取得するクエリをよく見てください。調整されている値について何か違いはありますか?
  3. そうでない場合、それらはすべてタイムスタンプですか、それとも日付ですか、それとも日時ですか?
于 2008-12-22T01:34:30.130 に答える
1

夏時間の問題である可能性が高いです。resultDateとcertDateに対してのみ実行する理由は、dateEnrolledが8月であり、夏時間が通常9月下旬または10月上旬に開始/終了するためです。

于 2008-12-22T01:39:41.680 に答える
1

わかりました、なぜそれが一方の日付を台無しにしているのに、もう一方の日付を台無しにしていないのかを理解しました。8 月はサマータイムが実施されていませんでした。顔やし

于 2008-12-22T01:33:44.390 に答える
0

apache.conf、.htaccess、または ini_set() を使用して、date.timezone ini 設定をアプリのタイムゾーンに設定します。

于 2008-12-22T02:29:45.773 に答える