Geçerli saat dilimi için doğru zaman ayarladığınız, depoladığınız tarih saat sütunlarının saat dilimini bildiğiniz ve yaz saati uygulamasıyla ilgili sorunların farkında olduğunuz sürece, sunucuda saat diliminin ne olduğu önemli değildir.
Öte yandan, birlikte çalıştığınız sunucuların zaman dilimlerini kontrol ediyorsanız, her şey dahili olarak UTC'ye ayarlanmış olabilir ve zaman dilimleri ve DST hakkında asla endişelenmeyebilirsiniz.
İşte kendim ve diğerleri için kişinin sunucu için hangi saat dilimini seçeceğini ve tarih ve saati nasıl saklayacağını etkileyebilecek zaman çizelgeleri ile bir hile sayfası olarak nasıl çalışacağına dair topladığım bazı notlar.
MySQL Saat Dilimi Hileleri
Notlar:
- Saat dilimini değiştirmek, depolanan tarih saatini veya zaman damgasını değiştirmez , ancak zaman damgası sütunlarından farklı bir tarih saati seçer
- Uyarı! UTC'nin artık saniye sayısı var, bunlar '2012-06-30 23:59:60' gibi görünüyor ve dünya dönmesinin yavaşlaması nedeniyle 6 ay önceden bildirimde bulunarak rastgele eklenebilir.
GMT saniyeler karıştırır, bu yüzden UTC icat edildi.
Uyarı! Farklı bölgesel saat dilimleri, gün ışığından yararlanma saati nedeniyle aynı tarih saatini üretebilir
- Zaman damgası sütunu, bir sınırlama nedeniyle yalnızca 1970-01-01 00:00:01 - 2038-01-19 03:14:07 UTC tarihlerini destekler .
Dahili olarak bir MySQL zaman damgası sütunu UTC olarak depolanır ancak bir tarih seçildiğinde MySQL bunu otomatik olarak geçerli oturum saat dilimine dönüştürür.
Bir tarihi bir zaman damgasında saklarken, MySQL, tarihin geçerli oturum saat diliminde olduğunu varsayar ve saklama için UTC'ye dönüştürür.
- MySQL, kısmi tarihleri datetime sütunlarında saklayabilir, bunlar "2013-00-00 04:00:00" gibi görünür
- MySQL, bir datetime sütununu NULL olarak ayarlarsanız, özellikle sütunu oluştururken null değerine izin verecek şekilde ayarlamadıysanız "0000-00-00 00:00:00" değerini depolar.
- Oku bunu
UTC biçiminde bir zaman damgası sütunu seçmek için
Geçerli MySQL oturumunun hangi saat diliminde olursa olsun:
SELECT
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
Sunucu veya global veya geçerli oturum saat dilimini UTC olarak ayarlayabilir ve ardından zaman damgasını şu şekilde seçebilirsiniz:
SELECT `timestamp_field` FROM `table_name`
UTC'de geçerli tarih saatini seçmek için:
SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');
Örnek sonuç: 2015-03-24 17:02:41
Oturum saat diliminde geçerli tarih saatini seçmek için
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();
Sunucu başlatıldığında ayarlanan saat dilimini seçmek için
SELECT @@system_time_zone;
Örneğin, Moskova zamanı için "MSK" veya "+04: 00" değerini döndürür, sayısal bir ofsete ayarlanırsa Yaz Saati uygulamasını ayarlamayacağı bir MySQL hatası vardır (ya da olmuştur)
Geçerli saat dilimini almak için
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
Saat diliminiz +2: 00 ise 02:00:00 döndürecektir.
Geçerli UNIX zaman damgasını almak için (saniye cinsinden):
SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();
Zaman damgası sütununu UNIX zaman damgası olarak almak için
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
UTC tarih / saat sütununu UNIX zaman damgası olarak almak için
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`
Olumlu bir UNIX zaman damgası tamsayısından geçerli saat dilimi tarih saatini alma
SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
UNIX zaman damgasından UTC tarih saati alma
SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00')
FROM `table_name`
Negatif UNIX zaman damgası tamsayısından geçerli saat dilimi tarih saatini alma
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
MySQL'de saat diliminin ayarlanabileceği 3 yer vardır:
Not: Bir saat dilimi 2 biçimde ayarlanabilir:
- UTC'den bir uzaklık: '+00: 00', '+10: 00' veya '-6: 00'
- adlandırılmış bir saat dilimi olarak: 'Avrupa / Helsinki', 'ABD / Doğu' veya 'MET'
Adlandırılmış saat dilimleri yalnızca mysql veritabanındaki saat dilimi bilgi tabloları oluşturulmuş ve doldurulmuşsa kullanılabilir.
"my.cnf" dosyasında
default_time_zone='+00:00'
veya
timezone='UTC'
@@ global.time_zone değişkeni
Hangi değere ayarlandıklarını görmek için
SELECT @@global.time_zone;
Bunun için bir değer ayarlamak için birini kullanın:
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET @@global.time_zone='+00:00';
@@ session.time_zone değişkeni
SELECT @@session.time_zone;
Ayarlamak için birini kullanın:
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";
hem "@@ global.time_zone değişkeni" hem de "@@ session.time_zone değişkeni", "SİSTEM" i döndürebilir, bu da "my.cnf" içinde ayarlanan saat dilimini kullandıkları anlamına gelir.
Saat dilimi adlarının çalışması için (varsayılan saat dilimi için bile) saat dilimi bilgi tablolarınızın doldurulması gerekir: http://dev.mysql.com/doc/refman/5.1/en/time-zone-support. html
Not: NULL döndüreceği için bunu yapamazsınız:
SELECT
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime`
FROM `table_name`
MySQL saat dilimi tablolarını ayarlama
İçin CONVERT_TZ
işe, sen saat dilimi tabloları doldurulması gerekmektedir
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` ;
Boşlarsa, bu komutu çalıştırarak doldurun
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
Bu komut size " satır 1'deki 'kısaltma' sütunu için çok uzun veri " hatasını veriyorsa, bunun nedeni saat dilimi kısaltmasının sonuna bir NULL karakterin eklenmesi olabilir.
düzeltme bunu çalıştırmak için
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
(sunucularınızın ilk kurallarının güncel olduğundan emin olun zdump -v Europe/Moscow | grep 2011
https://chrisjean.com/updating-daylight-saving-time-on-linux/ )
Her saat dilimi için tam DST (Yaz Saati Uygulaması) geçiş geçmişine bakın
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
yukarıdaki tablolardaki kurallara ve kullandığınız tarihe göre gerekli DST değişikliklerini de uygular.
Not: Dokümanlara
göre , time_zone için ayarladığınız değer değişmez, örneğin "+01: 00" olarak ayarlarsanız, time_zone DST'yi takip etmeyen UTC'den ofset olarak ayarlanır, bu nedenle tüm yıl boyunca aynı kalacaktır.
Yaz saati uygulaması sırasında yalnızca belirtilen saat dilimleri değişecektir.
Gibi kısaltmalar CET
her zaman kış ve CEST
yaz saati, +01: 00 her zamanUTC
zaman + 1 saat olacak ve her ikisi de DST ile değişmeyecek.
Saat system
dilimi, mysql'nin kurulu olduğu ana makinenin saat dilimi olacaktır (mysql bunu belirleyemezse)
DST ile çalışma hakkında daha fazla bilgiyi buradan edinebilirsiniz.
ilgili sorular:
Kaynaklar: