Saya sudah memikirkannya untuk tujuan saya. Saya akan meringkas apa yang saya pelajari (maaf, catatan ini bertele-tele; itu sama pentingnya dengan referensi saya di masa mendatang).
Bertentangan dengan apa yang saya katakan di salah satu komentar saya sebelumnya, bidang DATETIME dan TIMESTAMP jangan berperilaku berbeda. Kolom TIMESTAMP (seperti yang ditunjukkan oleh dokumen) mengambil apa pun yang Anda kirimkan dalam format "TTTT-BB-HH jj: mm: dd" dan mengubahnya dari zona waktu Anda saat ini ke waktu UTC. Kebalikannya terjadi secara transparan setiap kali Anda mengambil data. Bidang DATETIME tidak melakukan konversi ini. Mereka mengambil apa pun yang Anda kirimkan dan langsung menyimpannya.
Baik jenis bidang DATETIME maupun TIMESTAMP tidak dapat menyimpan data secara akurat dalam zona waktu yang mengamati DST . Jika Anda menyimpan "2009-11-01 01:30:00", kolom tidak memiliki cara untuk membedakan versi jam 1:30 mana yang Anda inginkan - versi -04: 00 atau -05: 00.
Ok, jadi kita harus menyimpan data kita di zona waktu non DST (seperti UTC). Kolom TIMESTAMP tidak dapat menangani data ini secara akurat karena alasan yang akan saya jelaskan: jika sistem Anda disetel ke zona waktu DST, apa yang Anda masukkan ke TIMESTAMP mungkin bukan yang Anda dapatkan kembali. Meskipun Anda mengirimkan data yang telah Anda ubah ke UTC, data tersebut akan tetap diasumsikan dalam zona waktu lokal Anda dan melakukan konversi lagi ke UTC. Perjalanan pulang pergi lokal-ke-UTC-kembali-ke-lokal yang diberlakukan TIMESTAMP ini merugikan saat zona waktu lokal Anda mengamati DST (karena "2009-11-01 01:30:00" memetakan ke 2 kemungkinan waktu yang berbeda).
Dengan DATETIME Anda dapat menyimpan data Anda di zona waktu mana pun yang Anda inginkan dan yakin bahwa Anda akan mendapatkan kembali apa pun yang Anda kirimkan (Anda tidak akan dipaksa melakukan konversi bolak-balik yang merugikan yang ditimbulkan oleh bidang TIMESTAMP pada Anda). Jadi solusinya adalah dengan menggunakan bidang DATETIME dan sebelum menyimpan ke bidang, ubah dari zona waktu sistem Anda menjadi zona non-DST apa pun yang Anda inginkan untuk menyimpannya (menurut saya UTC mungkin adalah opsi terbaik). Ini memungkinkan Anda untuk membuat logika konversi ke dalam bahasa skrip Anda sehingga Anda dapat secara eksplisit menyimpan UTC yang setara dengan "2009-11-01 01:30:00 -04: 00" atau "" 2009-11-01 01:30: 00 -05: 00 ".
Hal penting lainnya yang perlu diperhatikan adalah bahwa fungsi matematika tanggal / waktu MySQL tidak berfungsi dengan baik di sekitar batas DST jika Anda menyimpan tanggal Anda di DST TZ. Jadi semakin banyak alasan untuk menabung di UTC.
Singkatnya, sekarang saya melakukan ini:
Saat mengambil data dari database:
Tafsirkan secara eksplisit data dari database sebagai UTC di luar MySQL untuk mendapatkan stempel waktu Unix yang akurat. Saya menggunakan fungsi strtotime () PHP atau kelas DateTime untuk ini. Ini tidak dapat dilakukan dengan andal di dalam MySQL menggunakan fungsi MySQL CONVERT_TZ () atau UNIX_TIMESTAMP () karena CONVERT_TZ hanya akan mengeluarkan nilai 'YYYY-MM-DD hh: mm: ss' yang mengalami masalah ambiguitas, dan UNIX_TIMESTAMP () mengasumsikannya masukan dalam zona waktu sistem, bukan zona waktu tempat data SEBENARNYA disimpan dalam (UTC).
Saat menyimpan data ke database:
Ubah tanggal Anda ke waktu UTC tepat yang Anda inginkan di luar MySQL. Misalnya: dengan kelas DateTime PHP Anda dapat menentukan "2009-11-01 1:30:00 EST" dengan jelas dari "2009-11-01 1:30:00 EDT", lalu mengubahnya menjadi UTC dan menyimpan waktu UTC yang benar ke bidang DATETIME Anda.
Fiuh. Terima kasih banyak atas masukan dan bantuan semua orang. Mudah-mudahan ini bisa membuat orang lain sakit kepala di kemudian hari.
BTW, saya melihat ini di MySQL 5.0.22 dan 5.0.27