Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Bidang datetime MySQL dan waktu musim panas -- bagaimana cara mereferensikan jam tambahan?

Saya sudah mengetahuinya untuk tujuan saya. Saya akan meringkas apa yang saya pelajari (maaf, catatan ini bertele-tele; itu sama pentingnya untuk rujukan saya di masa mendatang seperti yang lainnya).

Bertentangan dengan apa yang saya katakan di salah satu komentar saya sebelumnya, bidang DATETIME dan TIMESTAMP lakukan berperilaku berbeda. Bidang TIMESTAMP (seperti yang ditunjukkan oleh dokumen) ambil apa pun yang Anda kirim dalam format "YYYY-MM-DD jj:mm:dd" dan ubah 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 secara akurat menyimpan data dalam zona waktu yang mengamati DST . Jika Anda menyimpan "2009-11-01 01:30:00", kolom tersebut tidak memiliki cara untuk membedakan versi 01:30 yang Anda inginkan -- versi -04:00 atau -05:00.

Ok, jadi kita harus menyimpan data kita di zona waktu non DST (seperti UTC). Bidang TIMESTAMP tidak dapat menangani data ini secara akurat karena alasan yang akan saya jelaskan:jika sistem Anda diatur ke zona waktu DST maka apa yang Anda masukkan ke dalam TIMESTAMP mungkin bukan yang Anda dapatkan kembali. Bahkan jika Anda mengirimkannya data yang telah Anda konversi ke UTC, itu akan tetap menganggap data di zona waktu lokal Anda dan melakukan konversi lain ke UTC. Pulang pergi lokal-ke-UTC-kembali-ke-lokal yang diberlakukan TIMESTAMP ini hilang ketika zona waktu lokal Anda mengamati DST (sejak "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 dipaksa untuk melakukan konversi bolak-balik lossy yang diberikan bidang TIMESTAMP pada Anda). Jadi solusinya adalah menggunakan bidang DATETIME dan sebelum menyimpan ke bidang konversi dari zona waktu sistem Anda ke zona non-DST apa pun yang Anda inginkan untuk menyimpannya (saya pikir UTC mungkin adalah pilihan terbaik). Ini memungkinkan Anda membangun logika konversi ke dalam bahasa skrip sehingga Anda dapat secara eksplisit menyimpan UTC yang setara dengan "2009-11-01 01:30:00 -04:00" atau ""01-11-2009 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 dalam DST TZ. Jadi, semakin banyak alasan untuk menabung di UTC.

Singkatnya sekarang saya melakukan ini:

Saat mengambil data dari database:

Menginterpretasikan data dari database secara eksplisit sebagai UTC di luar MySQL untuk mendapatkan stempel waktu Unix yang akurat. Saya menggunakan fungsi strtotime() PHP atau kelas DateTime untuk ini. Itu tidak dapat dilakukan dengan andal di dalam MySQL menggunakan fungsi CONVERT_TZ() atau UNIX_TIMESTAMP() MySQL karena CONVERT_TZ hanya akan menampilkan nilai 'YYYY-MM-DD hh:mm:ss' yang mengalami masalah ambiguitas, dan UNIX_TIMESTAMP() mengasumsikannya masukan ada di zona waktu sistem, bukan zona waktu tempat data SEBENARNYA disimpan (UTC).

Saat menyimpan data ke database:

Konversikan 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" secara berbeda dari "2009-11-01 1:30:00 EDT", lalu mengonversinya ke UTC dan menyimpan waktu UTC yang benar ke bidang DATETIME Anda.

Fiuh. Terima kasih banyak atas masukan dan bantuan semua orang. Semoga ini bisa menyelamatkan orang lain dari sakit kepala.

BTW, saya melihat ini di MySQL 5.0.22 dan 5.0.27



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL Menghapus Beberapa kunci Asing

  2. Nama tabel dinamis dalam fungsi prosedur tersimpan

  3. Bagaimana cara melakukan penyisipan massal di mySQL menggunakan node.js

  4. Menyiapkan Koneksi Database MySQL Jarak Jauh

  5. Pelacakan notifikasi suka Facebook (Desain DB)