क्या MySQL को UTC के लिए अपना टाइमज़ोन सेट करना चाहिए?


149

Https://serverfault.com/questions/191331/should-servers-have-their-timezone-set-to-gmt-utc के प्रश्न का अनुसरण करें

क्या MySQL टाइमज़ोन को UTC पर सेट किया जाना चाहिए या सर्वर या PHP के सेट होने पर इसे उसी टाइमज़ोन के लिए सेट किया जाना चाहिए? (यदि यह यूटीसी नहीं है)

पक्ष और विपक्ष क्या होते हैं?


stackoverflow.com/a/1650406/175071 यूटीसी का उपयोग करने के लिए अच्छे कारण हैं
तिमो हुओवेनन

यूटीसी एक समयक्षेत्र नहीं है। यूटीसी एक मानक है, जीएमटी एक समयक्षेत्र है। zachholman.com/talk/utc-is-enough-for-everyone-right
agoldev

जवाबों:


533

ऐसा लगता है कि इससे कोई फर्क नहीं पड़ता कि सर्वर पर टाइमज़ोन क्या है जब तक आपके पास वर्तमान टाइमज़ोन के लिए सही समय निर्धारित है, आपके द्वारा संग्रहित डेटाइम कॉलम के टाइमज़ोन को जानें, और डेलाइट बचत समय के साथ मुद्दों के बारे में जानते हैं।

दूसरी ओर यदि आपके पास उन सर्वरों के टाइमज़ोन का नियंत्रण है, जिनके साथ आप काम करते हैं, तो आपके पास यूटीसी को आंतरिक रूप से सेट करने के लिए सब कुछ हो सकता है और कभी भी टाइमज़ोन और डीएसटी के बारे में चिंता न करें।

यहां कुछ नोट हैं जिन्हें मैंने अपने और दूसरों के लिए एक प्रकार की चीटशीट के रूप में टाइमज़ोन के साथ काम करने के तरीके के रूप में एकत्र किया है जो यह प्रभावित कर सकते हैं कि व्यक्ति अपने सर्वर के लिए किस समयक्षेत्र का चयन करेगा और वह दिनांक और समय को कैसे संग्रहीत करेगा।

MySQL Timezone धोखा देती है

टिप्पणियाँ:

  1. टाइमजोन बदलने से संग्रहित डेटाटाइम या टाइमस्टैम्प नहीं बदलेगा , लेकिन यह टाइमस्टैम्प कॉलम से एक अलग डेटाटाइम का चयन करेगा
  2. चेतावनी! UTC के पास लीप सेकंड हैं, ये '2012-06-30 23:59:60' जैसे दिखते हैं और पृथ्वी के घूमने की गति के कारण 6 महीने पूर्व सूचना के साथ, यादृच्छिक रूप से जोड़े जा सकते हैं
  3. GMT सेकंड को भ्रमित करता है, यही वजह है कि UTC का आविष्कार किया गया था।

  4. चेतावनी! विभिन्न क्षेत्रीय टाइमज़ोन दिन के समय की बचत समय के कारण समान डेटाइम मूल्य का उत्पादन कर सकते हैं

  5. टाइमस्टैम्प कॉलम केवल एक सीमा के कारण दिनांक 1970-01-01 00:00:01 से 2038-01-19 03:14:07 UTC का समर्थन करता है ।
  6. आंतरिक रूप से एक MySQL टाइमस्टैम्प कॉलम को UTC के रूप में संग्रहीत किया जाता है, लेकिन एक तारीख का चयन करते समय MySQL स्वचालित रूप से इसे वर्तमान सत्र टाइमज़ोन में बदल देगा।

    जब एक टाइमस्टैम्प में एक तारीख संग्रहीत करते हैं, तो MySQL यह मान लेगा कि यह तिथि वर्तमान सत्र टाइमज़ोन में है और इसे स्टोरेज के लिए UTC में बदल देगा।

  7. MySQL डेटाइम कॉलम में आंशिक तिथियां संग्रहीत कर सकता है, ये "2013-00-00 04:00:00" जैसे दिखते हैं
  8. MySQL स्टोर "0000-00-00 00:00:00" यदि आप एक डेटाटाइम कॉलम NULL के रूप में सेट करते हैं, जब तक कि आप विशेष रूप से इसे बनाते समय नल की अनुमति देने के लिए कॉलम सेट नहीं करते हैं।
  9. इसे पढ़ें

UTC प्रारूप में टाइमस्टैम्प कॉलम का चयन करने के लिए

कोई बात नहीं है कि वर्तमान MySQL सत्र किस समयक्षेत्र में है:

SELECT 
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime` 
FROM `table_name`

आप UTC को गंभीर या वैश्विक या वर्तमान सत्र का समय भी सेट कर सकते हैं और फिर टाइमस्टैम्प का चयन कर सकते हैं:

SELECT `timestamp_field` FROM `table_name`

UTC में वर्तमान डेटाटाइम का चयन करने के लिए:

SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');

उदाहरण परिणाम: 2015-03-24 17:02:41

सत्र टाइमज़ोन में वर्तमान डेटाटाइम का चयन करने के लिए

SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();

उस समयक्षेत्र का चयन करने के लिए जब सर्वर लॉन्च किया गया था

SELECT @@system_time_zone;

मॉस्को समय के लिए "MSK" या "+04: 00" रिटर्न, उदाहरण के लिए, वहाँ (या था) एक MySQL बग जहां एक संख्यात्मक ऑफसेट पर सेट किया जाता है, तो यह डेलाइट बचत समय को समायोजित नहीं करेगा

वर्तमान समयक्षेत्र प्राप्त करने के लिए

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

यदि आपका टाइमज़ोन +2: 00 है तो यह 02:00:00 पर वापस आ जाएगा।

वर्तमान UNIX टाइमस्टैम्प प्राप्त करने के लिए (सेकंड में):

SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();

टाइमस्टैम्प कॉलम को UNIX टाइमस्टैम्प के रूप में प्राप्त करने के लिए

SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`

यूनिक्स टाइमस्टैम्प के रूप में एक यूटीसी डेटाइम कॉलम प्राप्त करने के लिए

SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`

एक सकारात्मक UNIX टाइमस्टैम्प पूर्णांक से एक वर्तमान समयक्षेत्र डेटाइम प्राप्त करें

SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`

UNIX टाइमस्टैम्प से UTC डेटाटाइम प्राप्त करें

SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00') 
FROM `table_name`

एक नकारात्मक UNIX टाइमस्टैम्प पूर्णांक से एक वर्तमान समयक्षेत्र डेटाटाइम प्राप्त करें

SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND) 

ऐसे 3 स्थान हैं जहाँ MySQL में समयक्षेत्र सेट किया जा सकता है:

नोट: एक समयक्षेत्र 2 स्वरूपों में सेट किया जा सकता है:

  1. UTC से एक ऑफसेट: '+00: 00', '+10: 00' या '-6: 00'
  2. नामित समय क्षेत्र के रूप में: 'यूरोप / हेलसिंकी', 'यूएस / पूर्वी', या 'मेट'

नामांकित समय क्षेत्रों का उपयोग केवल तभी किया जा सकता है जब mysql डेटाबेस में टाइम ज़ोन सूचना तालिकाओं को बनाया और आबाद किया गया हो।

"my.cnf" फ़ाइल में

default_time_zone='+00:00'

या

timezone='UTC'

@@ Global.time_zone चर

यह देखने के लिए कि वे किस मूल्य पर सेट हैं

SELECT @@global.time_zone;

इसके लिए एक मान सेट करने के लिए या तो एक का उपयोग करें:

SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET @@global.time_zone='+00:00';

@@ session.time_zone चर

SELECT @@session.time_zone;

इसे सेट करने के लिए या तो एक का उपयोग करें:

SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";

दोनों "@@ Global.time_zone चर" और "@@ session.time_zone चर" "सिस्टम" को वापस कर सकते हैं जिसका अर्थ है कि वे "my.cnf" में समयक्षेत्र सेट का उपयोग करते हैं।

समय-क्षेत्र के नाम (यहां तक ​​कि डिफ़ॉल्ट-टाइम-ज़ोन के लिए) के लिए आपको अपने टाइमज़ोन सूचना तालिकाओं को पॉप्युलेट करने की आवश्यकता होगी: http://dev.mysql.com/doc/refman/5.1/en/time-zone-support। एचटीएमएल

नोट: आप ऐसा नहीं कर सकते क्योंकि यह NULL लौटेगा:

SELECT 
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime` 
FROM `table_name`

सेट mysql timezone टेबल

के लिए CONVERT_TZकाम करने के लिए, आप की जरूरत समय क्षेत्र टेबल आबादी होने के लिए

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` ;

यदि वे खाली हैं, तो इस कमांड को चलाकर उन्हें भरें

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql

यदि यह कमांड आपको " पंक्ति 1 पर कॉलम 'संक्षिप्त नाम' के लिए त्रुटि" लंबे समय तक डेटा देता है , तो यह एक NULL वर्ण द्वारा समयक्षेत्र संक्षिप्त नाम के अंत में संलग्न किए जाने के कारण हो सकता है

इसे चलाने के लिए ठीक किया जा रहा है

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

(सुनिश्चित करें कि आपके सर्वर dst नियम अद्यतित हैं zdump -v Europe/Moscow | grep 2011 https://chrisjean.com/updating-daylight-saving-time-on-linux/ )

हर टाइमज़ोन के लिए पूर्ण DST (डेलाइट सेविंग टाइम) संक्रमण इतिहास देखें

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 उपरोक्त तालिकाओं में नियमों और आपके द्वारा उपयोग की जाने वाली तारीख के आधार पर कोई भी आवश्यक डीएसटी परिवर्तन लागू करता है।

नोट: डॉक्स के
अनुसार , आपने time_zone के लिए जो मूल्य निर्धारित किया है, वह नहीं बदलता है, यदि आप इसे उदाहरण के लिए "+01: 00" के रूप में सेट करते हैं, तो time_zone को UTC से ऑफसेट के रूप में सेट किया जाएगा, जो DST का पालन नहीं करता है, इसलिए यह पूरे वर्ष एक ही रहेगा।

केवल नामित टाइमज़ोन दिन के समय की बचत के समय में परिवर्तन करेंगे।

जैसे संकेतन CETहमेशा सर्दियों का समय CESTहोगा और गर्मियों का समय होगा जबकि +01: 00 हमेशा UTCसमय + 1 घंटा होगा और दोनों डीएसटी के साथ नहीं बदलेंगे।

systemटाइमज़ोन होस्ट मशीन का टाइमज़ोन होगा जहां mysql स्थापित है (जब तक कि mysql इसे निर्धारित करने में विफल नहीं होता)

आप यहां डीएसटी के साथ काम करने के बारे में अधिक पढ़ सकते हैं

संबंधित सवाल:

सूत्रों का कहना है:


इसलिए अगर मेरे पास टाइमस्टैम्प पर मेरा कॉलम टाइप सेट है। और मेरा time_zone +12: 00 है, और मैं utc आधारित दिनांक / समय का उपयोग करके एक कॉलम अपडेट करना चाहता हूं, क्या अपडेट स्टेटमेंट में टाइमज़ोन शामिल करने का कोई तरीका है, या क्या मुझे Convert_tz का उपयोग करना चाहिए। उदाहरण के लिए। अपडेट tableसेट modified= '2016-07-07 08:10 +00: 00'
बम्परबॉक्स

2
@bumperbox mysql हमेशा मानता है कि आप जिस समय को टाइमस्टैम्प कॉलम दे रहे हैं, वह mysql सर्वर के समान टाइमज़ोन में है, इसलिए आपको अपडेट के लिए अपने mysql सर्वर टाइमज़ोन पर अपने दिनांक को अपने +12: 00 टाइमज़ोन से परिवर्तित करने की आवश्यकता है। यही कारण है कि मैं mysql सर्वर पर UTC का उपयोग करता हूं और इसे संग्रहीत करने से पहले UTC को जो भी दिनांक परिवर्तित करता हूं।
टिमो हुओवेंन

5
एसओ का उपयोग करने के वर्षों में सबसे अच्छा, सबसे अधिक जानकारीपूर्ण उत्तर मैं आया हूं। धन्यवाद।
मिटी

चेतावनी !!! दिन के उजाले की बचत के अंत में, एक घंटे में एक घंटे के लिए डीएसटी समयक्षेत्र में स्थानीय उपयोग, या रूपांतरणों में से कोई भी समय गलत होगा। यह UNIX_TIMESTAMP(NOW());आपके सभी उपयोगों को प्रभावित करता है CONVERT_TZ()जहां मापदंडों में से एक `@@ session.time_zone है। UTC डेटासेट को UNIX टाइमस्टैम्प में मज़बूती से परिवर्तित करने के लिए, आपको मूल रूप से सत्र time_zone सेट करना होगा।
चल रहा

1
@ पूरी तरह से सही, मैं कुछ समय पहले ठीक करना भूल गया।
टिमो हुओवेंन

3

यह एक कार्य उदाहरण है:

jdbc:mysql://localhost:3306/database?useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Europe/Moscow

2

PHP और MySQL के अपने डिफ़ॉल्ट टाइमज़ोन कॉन्फ़िगरेशन हैं। आपको अपने डेटा बेस और वेब एप्लिकेशन के बीच समय को सिंक्रनाइज़ करना चाहिए, अन्यथा आप कुछ मुद्दों को चला सकते हैं।

इस ट्यूटोरियल को पढ़ें: अपने PHP और MySQL Timezones को कैसे सिंक्रोनाइज़ करें


यह मूल रूप से कोड की दो लाइनें हैं: date_default_timezone_set("America/Los_Angeles");और mysql_query("SET time_zone='" . date('P', time()) . "'");बहुत ही सुरुचिपूर्ण ढंग से काम किया है!
नूमेनन

3
@ नौमेनन उस के साथ सावधान! मैं आज सुबह अपना सिर खुजला रहा हूं क्योंकि मैं वही कर रहा था, और मेरे कुछ समय अब ​​एक घंटे के लिए बंद हैं। मुझे संदेह है कि डीएसटी के शामिल होने पर नामांकित समयक्षेत्र का उपयोग करना अधिक सटीक है। यदि आप अमेरिका / New_York का उपयोग करते हैं, तो MySQL DST के बारे में जानता है और उचित रूप से तारीखों को संग्रहीत करेगा। यदि आप इसे केवल -04: 00 पर सेट करते हैं, जैसे आपके पास यहां है, तो यह डीएसटी गणना को ध्यान में नहीं रखेगा।
नथनब

1
जांचें कि क्या mysql को DST के बारे में सही तरीके से पता है, DST नियम नियमित रूप से अपडेट हो जाते हैं और संबंधित mysql तालिकाओं को भी अद्यतन करने की आवश्यकता है (मेरे उत्तर के नीचे देखें)
Timo Huovinen

1

पेशेवरों और विपक्ष बहुत अधिक समान हैं। यह इस बात पर निर्भर करता है कि आप यह चाहते हैं या नहीं।

सावधान रहें, यदि MySQL timezone आपके सिस्टम के समय (उदाहरण के लिए PHP) से अलग है, तो उपयोगकर्ता की समय या छपाई की तुलना में कुछ छेड़छाड़ शामिल होगी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.