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

Haruskah MySQL mengatur zona waktunya ke UTC?

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:

  1. Mengubah zona waktu tidak akan mengubah tanggal waktu atau stempel waktu yang disimpan , tetapi akan memilih tanggal waktu yang berbeda dari kolom stempel waktu

  2. 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

  3. GMT membingungkan detik, itulah sebabnya UTC ditemukan.

  4. Peringatan! zona waktu regional yang berbeda mungkin menghasilkan nilai waktu waktu yang sama karena waktu musim panas

  5. Kolom cap waktu hanya mendukung tanggal 1970-01-01 00:00:01 hingga 2038-01-19 03:14:07 UTC, karena batasan .

  6. 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.

  7. MySQL dapat menyimpan sebagian tanggal di kolom datetime, ini terlihat seperti"2013-00-00 04:00:00"

  8. 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.

  9. Baca ini

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:

  1. pengimbangan dari UTC:'+00:00', '+10:00' atau '-6:00'
  2. 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:

Sumber:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. WEEKDAY() Contoh – MySQL

  2. MySQL di Docker - Cara Menampung Basis Data Anda :Buku Putih Baru

  3. PHP untuk menyimpan gambar di MySQL atau tidak?

  4. Prosedur Tersimpan dengan parameter WHERE opsional

  5. Cara Mengubah Kata Sandi Root MySQL atau MariaDB di Linux