MySQL'in geçerli saat dilimini nasıl edinebilirim?


217

MySQL'de böyle bir işlev olup olmadığını bilen var mı?

GÜNCELLEME

Bu geçerli bir bilgi vermez:

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | SYSTEM              |
+--------------------+---------------------+

Ya da belki de MySQL'in kendisi tam olarak time_zonekullanılanı bilemez , bu iyi, PHPgeçerli olmayan bilgileri alabildiğim sürece buraya dahil olabiliriz SYSTEM...


3
"PHP'yi buraya dahil edebiliriz" - ve bu php örneği her zaman MySQL sunucusuyla aynı makinede olur mu?
VolkerK

Evet, aynı makinede olacaklar.
user198729

10
Aşağıdaki @@system_time_zonecevabımda belirtildiği gibi deneyin .
Andrew

Soru sorulduğu için daha fazla cevap eklendiğinden, kabul edilen yanıtı tekrar düşünün.
Timo Huovinen

1
MySQL sunucusu ve PHP aynı sunucuda olsalar da, ayarlarına göre farklı zaman dilimleri alabilirler. Ve bu süreler işletim sisteminizin gösterdiklerinden ve PHP / MySQL gösterisinden farklı olabilir.
Bimal Poudel

Yanıtlar:


227

Kılavuzdan ( bölüm 9.6 ):

Genel ve istemciye özgü saat dilimlerinin geçerli değerleri şu şekilde alınabilir:
mysql> SELECT @@global.time_zone, @@session.time_zone;

DüzenleSYSTEM MySQL, sistemin saat dilimine yardımcı olacak şekilde ayarlanmışsa, yukarıdaki değer döndürülür . PHP kullanarak konum beri MySQL gelen cevap ise, SYSTEMo zaman ne zaman dilimi sistemini sorabilirsiniz o oluyor aracılığı ile date_default_timezone_get. VolkerK belirttiği gibi (Elbette, PHP farklı bir sunucuda çalışıyor olabilir, ancak varsayımlar giderken, web sunucusu ve edilmektedir konuşuyor sunucusunun DB varsayarak ayarlı [değilse aslında içinde ] Aynı zaman dilimi bir değil büyük bir sıçrama.) Ancak dikkat edin (MySQL'de olduğu gibi), PHP'nin kullandığı zaman dilimini ayarlayabilirsiniz (date_default_timezone_set) anlamına gelir. Bu, işletim sisteminin kullandığından farklı bir değer rapor edebileceği anlamına gelir. PHP kodunu kontrol ediyorsanız, bunu yapıp yapmadığınızı bilmeli ve iyi olmalısınız.

Ancak MySQL sunucusunun hangi saat dilimini kullandığına dair tüm soru teğet olabilir, çünkü sunucuya hangi saat diliminde olduğunu sormak , veritabanındaki veriler hakkında kesinlikle hiçbir şey söylemez . Ayrıntılar için okumaya devam edin:

Daha fazla tartışma :

Sunucuyu kontrol ediyorsanız, elbette saat diliminin bilinen bir miktar olduğundan emin olabilirsiniz. Sunucunun kontrolü sizde değilse, bağlantınız tarafından kullanılan saat dilimini şu şekilde ayarlayabilirsiniz :

set time_zone = '+00:00';

Bu, saat dilimini GMT'ye ayarlar, böylece diğer işlemler (gibi now()) GMT'yi kullanır.

Not olsa da, o zaman ve tarih değerleri vardır değil MySQL zaman dilimi bilgileri ile saklanır:

mysql> create table foo (tstamp datetime) Engine=MyISAM;
Query OK, 0 rows affected (0.06 sec)

mysql> insert into foo (tstamp) values (now());
Query OK, 1 row affected (0.00 sec)

mysql> set time_zone = '+01:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select tstamp from foo;
+---------------------+
| tstamp              |
+---------------------+
| 2010-05-29 08:31:59 |
+---------------------+
1 row in set (0.00 sec)

mysql> set time_zone = '+02:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select tstamp from foo;
+---------------------+
| tstamp              |
+---------------------+
| 2010-05-29 08:31:59 |      <== Note, no change!
+---------------------+
1 row in set (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2010-05-29 10:32:32 |
+---------------------+
1 row in set (0.00 sec)

mysql> set time_zone = '+00:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2010-05-29 08:32:38 |      <== Note, it changed!
+---------------------+
1 row in set (0.00 sec)

Sunucunun dilimini bilerek hemen zaman olsun fonksiyonları açısından yalnızca önemlidir Yani örneğin now(), unix_timestamp()vb .; veritabanı verilerindeki tarihlerin saat dilimini ne kullandığına dair hiçbir şey söylemez. Sunucunun saat dilimini kullanarak yazıldığını varsaymayı seçebilirsiniz , ancak bu varsayım hatalı olabilir. Verilerde depolanan herhangi bir tarih veya saatin saat dilimini bilmek için, saat dilimi bilgileriyle birlikte depolandıklarından veya (yaptığım gibi) her zaman GMT'de olduklarından emin olmalısınız.

Verilerin neden sunucunun saat dilimi hatalı yazıldığını varsayalım? Bir kere, veriler farklı bir saat dilimi ayarlayan bir bağlantı kullanılarak yazılmış olabilir. Veritabanı bir sunucudan diğerine taşınmış olabilir, burada sunucular farklı zaman dilimlerinde idi (Teksas'tan Kaliforniya'ya taşınan bir veritabanını devraldığımda buna rastladım). Ancak veriler sunucuda, geçerli saat dilimiyle yazılsa bile , yine de belirsizdir. Geçen yıl, Amerika Birleşik Devletleri'nde, Yaz Saati Uygulaması 1 Kasım günü saat 02: 00'de kapatıldı. Sunucumun Pasifik saat dilimini kullanarak Kaliforniya'da olduğunu ve2009-11-01 01:30:00veritabanında. Ne zamandı? Bu 1 Kasım 1 Kasım PDT mi, 1:30 am 1 Kasım PST miydi (bir saat sonra)? Kesinlikle bilmenin yolu yok. Ahlaki: Tarihleri ​​/ saatleri her zaman GMT'de (DST yapmayan) saklayın ve gerektiğinde / istediğiniz zaman dilimine dönüştürün.


5
@ user198729: Anlamsız değil , umduğum kadar faydalı değil. Bunun anlamı şudur: İşletim sistemine sorun, MySQL buna köledir.
TJ Crowder

Sadece merak ediyorum, neden saat dilimini kendimiz ayarlayıp sonra geri almalıyız? Bu tür yenilgiler amacı değil mi? Yani, cevabını bilmediğim için MySQL'den saat dilimini sormak istiyorum. Belki kafam karıştı ve işler yanlış gitti. Birisi açıklayabilir mi?
Senthil

1
@Senthil mySQL DATETIMEtürü saat dilimi bilgisi içermiyor. Bu nedenle, burada amaçlanan temel felsefenin mySQL için olabildiğince zaman dilimi kör olması olduğunu düşünüyorum - bu, kullanıcının UTC veya sunucunun bulunduğu saat dilimi olan bir saat dilimine bağlı kalması, o bölgedeki her şeyi depolaması ve Uygulama düzeyinde veya kullanarak herhangi bir dönüşüm gerçekleştirin CONVERT_TZ()( dev.mysql.com/doc/refman/5.0/en/… ) En azından, mySQL'in bu alanda sağladığı seyrek seçeneklere bakarak bunun nasıl çalışması gerektiğini hep anladım.
Pekka

Teşekkürler ama bu hala çözülmedi, now()PHP'de tz bilgisini nasıl alabilirim ?
user198729

Ben tamamen "zaman damgası kaydederken bir zaman dilimi sopa" parçası ile katılıyorum .. Ama bu-> ".. ya da sunucunun içinde bulunduğu zaman dilimi .." bunu nasıl bulabilirsiniz? Tüm zaman damgası değerlerini UTC olarak kaydettiğinizi varsayalım. Ancak sunucunuz bir saat diliminde ve zaman damgası değerlerini bu saat dilimine göre göstermek istiyorsunuz . Peki sunucunuzun hangi saat diliminde olduğunu nasıl bileceksiniz? Sadece o zaman doğru dönüştürmek için CONVERT_TZ () bir değer aktarabilirsiniz?
Senthil

196

Aşağıdaki sorgu, geçerli oturumun saat dilimini döndürür.

select timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00'));

6
Bu gerçekten doğru cevaptır, çünkü 'SİSTEM'in' dönüşümde bir saat dilimi olarak kabul edildiğini gösterir;
nilskp

5
Teşekkürler, bunu kullanarak istediğim formatı elde edebildim:select time_format(timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00')),'%H%i');
jordanbtucker

97
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP)daha basit.
Jakub Vrána

3
Veya SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP);saniyeler içinde farkı elde etmek için.
philfreo

106

basitçe SELECT @@system_time_zone;

İade PST(veya sisteminizle alakalı olan her şey).

Oturum saat dilimini belirlemeye çalışıyorsanız bu sorguyu kullanabilirsiniz:
SELECT IF(@@session.time_zone = 'SYSTEM', @@system_time_zone, @@session.time_zone);

Bu, sistem saat diliminden farklıysa oturum saat dilimini döndürür.


6
Tek dezavantajı, Yaz Saati uygulaması nedeniyle saat dilimi değişirse, sunucunun başlatıldığı sırada "hatırlanan" olanı bildirmeye devam edeceğidir
Mark

72

As Jakub Vrána (yaratıcısı veya Adminer ve NotORM ) yorumlardaki bahisler de ofset akım dilimini seçmek için TIMEkullanım:

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

Bu döndürür: 02:00:00saat dilimi 2 ise: 00 Bu tarihten için

Burada bir hile sayfası yaptım: MySQL'in saat dilimi UTC olarak ayarlanmış mı?


Veya SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP);saniyeler içinde farkı elde etmek için.
philfreo

@philfreo eklentisi - parametrelerin TIMESTAMPDIFF içinde TIMEDIFF ile ters çevrilmesi gerektiğini unutmayın. Bu cevapta verilen örneği almak için, TIMEDIFF dönerse 02:00:00, -2ünite HOUR -120ise, ünite MINUTE vb. İse karşılık gelen TIMESTAMPDIFF dönecektir. İşaretin saat dilimine karşılık gelmesini sağlamak için parametreleri değiştirin: saat dilimi SELECT TIMESTAMPDIFF(MINUTE, UTC_TIMESTAMP, NOW())için beklenen değeri döndürür 1202: 00. Dakika belirtmenin nedeni, 30 veya 45 dakika ofset olan birkaç zaman dilimi olmasıdır, bkz. En.wikipedia.org/wiki/Time_zone
ToolmakerSteve

1
bu, soruyu doğrudan cevapladığı ve sadece teori yerine bir çözüm verdiği için kabul edilen cevaptan çok daha iyi bir cevaptır.
supersan

10

MySQL'in geçerli saat dilimini almak için aşağıdakileri yapabilirsiniz:

 1. SELECT @@system_time_zone;   //from this you can get the system timezone 
 2. SELECT IF(@@session.time_zone = 'SYSTEM', @@system_time_zone, @@session.time_zone) //This will give you time zone if system timezone is different from global timezone

Şimdi mysql saat dilimini değiştirmek istiyorsanız:

 1. SET GLOBAL time_zone = '+00:00'   //this will set mysql timezone in UTC
 2. SET @@session.time_zone = "+00:00";  //by this you can chnage the timezone only for your particular session 

6
SELECT EXTRACT(HOUR FROM (TIMEDIFF(NOW(), UTC_TIMESTAMP))) AS `timezone`

Bu, zaman dilimini -6pozitif veya negatif zamanları işleyerek bir tamsayı (örneğin :) olarak döndürür (işte burada EXTRACTdevreye girer: HOURtek başına işlev negatif zaman dilimlerini pozitif olarak döndürür).


6

Herkes mysql db saat dilimi bulmak için geliyor.

Bu sorgu ile geçerli saat dilimi alabilirsiniz:

mysql> SELECT @@system_time_zone as tz;
+-------+
|  tz   |
+-------+
|  CET  |
+-------+

4

Açıklamadaki komut, sunucunun saat dilimini aldığını belirten "SYSTEM" değerini döndürür. Hangi bizim sorgu için yararlı değildir.

Aşağıdaki sorgu saat dilimini anlamanıza yardımcı olacaktır

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP) as GMT_TIME_DIFF;

Yukarıdaki sorgu size Koordineli Evrensel Zaman (UTC) ile ilgili zaman aralığını verecektir. Böylece saat dilimini kolayca analiz edebilirsiniz. veritabanı saat dilimi IST ise çıktı 5:30 olur

UTC_TIMESTAMP

MySQL'de UTC_TIMESTAMP, geçerli UTC tarih ve saatini işlevin kullanımına bağlı olarak bir dize veya sayısal bağlamda bir değer olarak döndürür.

NOW ()

NOW () işlevi. MySQL NOW (), işlevin içeriğine (sayısal veya dize) bağlı olarak geçerli tarih ve saatin değerini 'YYYY-AA-GG SS: AA: SS' biçiminde veya YYYYMMDDHHMMSS.uuuuuu biçiminde döndürür. CURRENT_TIMESTAMP, CURRENT_TIMESTAMP (), LOCALTIME, LOCALTIME (), LOCALTIMESTAMP, LOCALTIMESTAMP (), NOW () kelimesinin eş anlamlılarıdır.


2

MySQL Server Saat Dilimi Desteğine ve system_time_zonesistem değişkenine göz atın . Bu yardımcı olur mu?


@ kullanıcı, sorunuzun tam olarak hangi bilgiyi aradığınızı (sunucunun saat dilimi? Müşterinin?) ve hangi araçların kullanımınıza sunulduğunu lütfen söyleyebilir misiniz? PHP'den bahsediyorsun. Komut satırına erişebiliyor musunuz?
Pekka

5
@ kullanıcı, ben de yardımcı olmaya çalışıyoruz ve tam olarak yanlış değil insanların bir dick downvoting cevaplar biraz rastlamak buluyorum. Oyu ne de puan kaybını önemsemiyorum, ancak tutumunuz bir çözüm bulmak için daha fazla cesaret verici değil.
Pekka

3
Dediğim gibi, tutumunuz beni, özellikle sağladığınız yetersiz bilgiler ışığında, sizin için daha fazla cevap aramaya motive etmiyor. Afedersiniz.
Pekka

3
@ user198729: Vay canına, tutumu kaybet. Pekka insanlara gerçekten yardım edecek türden bir adam. Yalnızca nezaket sizi motive etmek için yeterli değilse, kişisel çıkarları deneyin.
TJ Crowder

2
Sadece düşüncelerim: Kullanıcı gönderime aynı şeyi yapsaydı rahatsız olmazdım. Yani, son tarih baskısı ya da hayal kırıklığı insanların etrafına sert kenarlar ekliyor, ancak bence bir dereceye kadar izin vermeliyiz. Belki çok affediyorum: |
Senthil

1

PHP çerçevemin kullandığı

SET LOCAL time_zone='Whatever'

bağlandıktan sonra açık, burada 'Whatever' == date_default_timezone_get ()

Benim çözümüm değil, ama bu SYSTEMMySQL sunucusunun saat diliminin her zaman PHP'ninkiyle aynı olmasını sağlar

Yani, evet, PHP şiddetle dahil edilmiştir ve onu etkileyebilir


1

Geçerli saati saat diliminize göre almak için aşağıdakileri kullanabilirsiniz (benim durumumda '+5: 30')

DATE_FORMAT (convert_tz (şimdi (), @@ session.time_zone, '+ 05:30'), '% Y-% m-% d') seçin


0

Sistem saat dilimini değiştirdikten sonra mysqld'i yeniden başlatmanız yeterlidir.

MySQL'in global saat dilimi Sistemin saat dilimini alır. Böyle bir sistem özniteliğini değiştirdiğinizde, Mysqld'ın yeniden başlatılması yeterlidir.


işletim sistemindeki saat dilimini değiştirdikten sonra, mysql ekler yeni saat dilimini kullanacak, ancak şimdi (); ve current_timestamp öğesini seçin; komutları eski saat dilimini kullanmaya devam eder. Tüm bunları senkronize etmek için mysql hizmetinin yeniden başlatılması gerekir.
Manoj Kumar G

0

Zaman damgası olan veritabanlarınızdan birine sahte bir kayıt ekleme Bu kaydı seçin ve zaman damgasının değerini alın. Bu kaydı silin. Sunucunun veri yazmak için kullandığı saat dilimini kesin olarak alır ve PHP saat dilimlerini yok sayar.


0

Aşağıdakileri deneyebilirsiniz:

select sec_to_time(TIME_TO_SEC( curtime()) + 48000);

Burada zaman farkınızı saniye olarak belirleyebilirsiniz


1
ofset eklememeli ve çıkarmamalısınız. gün ışığı söyleyerek kuralları vb ile bir mayın tarlası
eweb

0

Kullanabileceğiniz LPAD(TIME_FORMAT(TIMEDIFF(NOW(), UTC_TIMESTAMP),’%H:%i’),6,’+')MySQL'in saat dilimi biçiminde bir değer elde etmek için kullanın CONVERT_TZ(). Aldığınız saat dilimi ofsetinin yalnızca ifadenin değerlendirildiği zamanda geçerli olduğunu unutmayın, çünkü gün ışığından yararlanma süreniz varsa ofset zaman içinde değişebilir. Bununla birlikte, ifade, NOW()ofseti yerel zamanla birlikte depolamak için yararlıdır , bu da neyin NOW()verimini belirsizleştirir . (DST zaman dilimlerinde, NOW()yılda bir saat geri atlar, bu nedenle zaman içindeki farklı noktalar için bazı yinelenen değerler vardır).


0

Olabilir

select timediff(current_time(),utc_time())

Saat dilimi değerini doğrudan bu şekilde elde edemezsiniz.

@@global.time_zonedeğişken olduğu için kullanılamaz ve değeri döndürür 'SYSTEM'.

Sorgunuzu kullanarak saat dilimi değiştirilmiş bir oturumda kullanmanız gerekiyorsa session SET TIME_ZONE =, bunu alırsınız @@session.time_zone. Eğer sorgu yaparsanız @@global.time_zone, o zaman olsun 'SYSTEM'.

Eğer denerseniz datediff, date_subya timediffile now()ve utc_time()daha sonra muhtemelen dönüşüm sorunları çalıştırmak gerekir.

Ancak yukarıda önerilenler muhtemelen en azından bazı sunucu sürümlerinde çalışacaktır. Sürümüm 5.5.43-37 ve barındırılan bir çözüm.


Bu soruya açıkça cevap vermiyor. Belki de sorulan soruya odaklanmak için düzenleyebilirsiniz .
Mogsdad

-3

Aşağıdaki kodu kullanmayı deneyin:

//ASP CLASSIC
Set dbdate = Server.CreateObject("ADODB.Recordset")
dbdate.ActiveConnection = MM_connection
dbdate.Source = "SELECT NOW() AS currentserverdate "
dbdate.Open()
currentdate = dbdate.Fields("currentserverdate").Value
response.Write("Server Time is "&currentdate)
dbdate.Close()
Set dbdate = Nothing
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.