Tampaknya tidak masalah apa zona waktu di server selama Anda memiliki waktu yang tepat untuk zona waktu saat ini, mengetahui zona waktu kolom datetime yang Anda simpan, dan menyadari masalah dengan waktu musim panas.
Di sisi lain, jika Anda memiliki kendali atas zona waktu server tempat Anda bekerja, maka Anda dapat mengatur semuanya ke UTC secara internal dan tidak perlu khawatir tentang zona waktu dan DST.
Berikut adalah beberapa catatan yang saya kumpulkan tentang cara bekerja dengan zona waktu sebagai bentuk lembar contekan untuk diri saya sendiri dan orang lain yang mungkin memengaruhi zona waktu yang akan dipilih seseorang untuk servernya dan bagaimana dia akan menyimpan tanggal dan waktu.
Lembar Curang Zona Waktu MySQL
Catatan:
-
Mengubah zona waktu tidak akan mengubah tanggal waktu atau stempel waktu yang disimpan , tetapi akan memilih tanggal waktu yang berbeda dari kolom stempel waktu
-
Peringatan! UTC memiliki detik kabisat, ini terlihat seperti '30-06-2012 23:59:60' dan dapat ditambahkan secara acak, dengan pemberitahuan 6 bulan sebelumnya, karena perlambatan rotasi bumi
-
GMT membingungkan detik, itulah sebabnya UTC ditemukan.
-
Peringatan! zona waktu regional yang berbeda mungkin menghasilkan nilai waktu waktu yang sama karena waktu musim panas
-
Kolom cap waktu hanya mendukung tanggal 1970-01-01 00:00:01 hingga 2038-01-19 03:14:07 UTC, karena batasan .
-
Secara internal kolom stempel waktu MySQL disimpan sebagai UTC tetapi ketika memilih tanggal, MySQL akan secara otomatis mengonversinya ke zona waktu sesi saat ini.
Saat menyimpan tanggal dalam stempel waktu, MySQL akan menganggap bahwa tanggal tersebut berada dalam zona waktu sesi saat ini dan mengubahnya menjadi penyimpanan UTC.
-
MySQL dapat menyimpan sebagian tanggal di kolom datetime, ini terlihat seperti"2013-00-00 04:00:00"
-
MySQL menyimpan "0000-00-00 00:00:00" jika Anda menyetel kolom tanggal waktu sebagai NULL, kecuali jika Anda secara khusus menyetel kolom tersebut untuk mengizinkan null saat Anda membuatnya.
Untuk memilih kolom stempel waktu dalam format UTC
tidak peduli apa zona waktu sesi MySQL saat ini:
SELECT
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
Anda juga dapat mengatur zona waktu sesi pemutusan atau global atau saat ini ke UTC dan kemudian pilih stempel waktu seperti ini:
SELECT `timestamp_field` FROM `table_name`
Untuk memilih waktu saat ini dalam UTC:
SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');
Contoh hasil:2015-03-24 17:02:41
Untuk memilih waktu saat ini dalam zona waktu sesi
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();
Untuk memilih zona waktu yang ditetapkan saat server diluncurkan
SELECT @@system_time_zone;
Mengembalikan "MSK" atau "+04:00" untuk waktu Moskow misalnya, ada (atau dulunya) bug MySQL di mana jika diatur ke offset numerik, itu tidak akan menyesuaikan waktu musim panas
Untuk mendapatkan zona waktu saat ini
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
Ini akan mengembalikan 02:00:00 jika zona waktu Anda adalah +2:00.
Untuk mendapatkan stempel waktu UNIX saat ini (dalam detik):
SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();
Untuk mendapatkan kolom stempel waktu sebagai stempel waktu UNIX
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
Untuk mendapatkan kolom tanggal waktu UTC sebagai stempel waktu UNIX
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`
Dapatkan tanggal waktu zona waktu saat ini dari bilangan bulat stempel waktu UNIX positif
SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
Dapatkan tanggal waktu UTC dari stempel waktu UNIX
SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00')
FROM `table_name`
Dapatkan tanggal waktu zona waktu saat ini dari bilangan bulat stempel waktu UNIX negatif
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
Ada 3 tempat di mana zona waktu dapat diatur di MySQL:
Catatan:Zona waktu dapat diatur dalam 2 format:
- pengimbangan dari UTC:'+00:00', '+10:00' atau '-6:00'
- sebagai zona waktu bernama:'Europe/Helsinki', 'US/Eastern', atau 'MET'
Zona waktu yang diberi nama hanya dapat digunakan jika tabel informasi zona waktu dalam database mysql telah dibuat dan diisi.
di file "my.cnf"
default_time_zone='+00:00'
atau
timezone='UTC'
@@global.time_zone variabel
Untuk melihat nilai yang disetel ke
SELECT @@global.time_zone;
Untuk menetapkan nilai, gunakan salah satu:
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET @@global.time_zone='+00:00';
@@session.time_zone variabel
SELECT @@session.time_zone;
Untuk mengaturnya gunakan salah satu:
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";
baik "@@global.time_zone variabel" dan "@@session.time_zone variabel" mungkin mengembalikan "SYSTEM" yang berarti mereka menggunakan zona waktu yang ditetapkan di "my.cnf".
Agar nama zona waktu berfungsi (bahkan untuk zona waktu default), Anda harus menyiapkan tabel informasi zona waktu yang harus diisi: http://dev.mysql.com/doc /refman/5.1/en/time-zone-support.html
Catatan:Anda tidak dapat melakukan ini karena akan mengembalikan NULL:
SELECT
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime`
FROM `table_name`
Mengatur tabel zona waktu mysql
Untuk CONVERT_TZ
untuk bekerja, Anda memerlukan tabel zona waktu untuk diisi
SELECT * FROM mysql.`time_zone` ;
SELECT * FROM mysql.`time_zone_leap_second` ;
SELECT * FROM mysql.`time_zone_name` ;
SELECT * FROM mysql.`time_zone_transition` ;
SELECT * FROM mysql.`time_zone_transition_type` ;
Jika kosong, isi dengan menjalankan perintah ini
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
jika perintah ini memberi Anda kesalahan "data terlalu panjang untuk kolom 'singkatan' di baris 1 ", maka itu mungkin disebabkan oleh karakter NULL yang ditambahkan di akhir singkatan zona waktu
cara mengatasinya adalah menjalankan ini
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
(if the above gives error "data too long for column 'abbreviation' at row 1")
mysql_tzinfo_to_sql /usr/share/zoneinfo > /tmp/zut.sql
echo "SET SESSION SQL_MODE = '';" > /tmp/mysql_tzinfo_to.sql
cat /tmp/zut.sql >> /tmp/mysql_tzinfo_to.sql
mysql --defaults-file=/etc/mysql/my.cnf --user=verifiedscratch -p mysql < /tmp/mysql_tzinfo_to.sql
(pastikan aturan dst server Anda terbaru zdump -v Europe/Moscow | grep 2011
https://chrisjean.com/updating-daylight-saving-time- di-linux/
)
Lihat riwayat transisi DST (Daylight Saving Time) lengkap untuk setiap zona waktu
SELECT
tzn.Name AS tz_name,
tztt.Abbreviation AS tz_abbr,
tztt.Is_DST AS is_dst,
tztt.`Offset` AS `offset`,
DATE_ADD('1970-01-01 00:00:00',INTERVAL tzt.Transition_time SECOND) AS transition_date
FROM mysql.`time_zone_transition` tzt
INNER JOIN mysql.`time_zone_transition_type` tztt USING(Time_zone_id, Transition_type_id)
INNER JOIN mysql.`time_zone_name` tzn USING(Time_zone_id)
-- WHERE tzn.Name LIKE 'Europe/Moscow' -- Moscow has weird DST changes
ORDER BY tzt.Transition_time ASC
CONVERT_TZ
juga menerapkan perubahan DST yang diperlukan berdasarkan aturan dalam tabel di atas dan tanggal yang Anda gunakan.
Catatan:
Menurut dokumen , nilai yang Anda tetapkan untuk zona_waktu tidak berubah, jika Anda menetapkannya sebagai "+01:00" misalnya, maka zona_waktu akan ditetapkan sebagai offset dari UTC, yang tidak mengikuti DST, sehingga akan tetap sama semua sepanjang tahun.
Hanya zona waktu yang bernama akan mengubah waktu selama waktu musim panas.
Singkatan seperti CET
akan selalu menjadi waktu musim dingin dan CEST
akan menjadi waktu musim panas sementara +01:00 akan selalu menjadi UTC
waktu + 1 jam dan keduanya tidak akan berubah dengan DST.
system
zona waktu akan menjadi zona waktu mesin host tempat mysql diinstal (kecuali mysql gagal menentukannya)
Anda dapat membaca lebih lanjut tentang bekerja dengan DST di sini
Kapan tidak menggunakan UTC oleh Jon Skeet yang legendaris:https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/ (Misalnya acara terjadwal di masa depan yang mewakili waktu, bukan waktu instan)
pertanyaan terkait:
- Bagaimana cara menyetel zona waktu MySQL?
- MySql - PILIH Kolom TimeStamp dalam format UTC
- Cara dapatkan stempel waktu Unix di MySQL dari waktu UTC?
- Mengonversi TimeStamp Server MySQL Ke UTC
- https://dba. stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp
- Bagaimana caranya Saya mendapatkan zona waktu MySQL saat ini?
- Bidang tanggal waktu MySQL dan waktu musim panas -- bagaimana cara mereferensikan jam "ekstra"?
- Mengonversi nilai negatif dari FROM_UNIXTIME
Sumber:
- https://bugs.mysql.com/bug.php?id=68861
- http://dev. mysql.com/doc/refman/5.0/en/date-and-time-functions.html
- http://dev.mysql.com/doc/ refman/5.1/en/datetime.html
- http://en.wikipedia.org/wiki/Coordinated_Universal_Time
- http://shafiqissani.wordpress.com/2010/09/30/how-to-get-the-current-epoch-time-unix-timestamp/
- https://web.ivy.net/~carton/ rant/MySQL-timezones.txt