PostgreSQL में समय क्षेत्र के साथ / बिना टाइमस्टैम्प के बीच अंतर


186

डेटा प्रकार WITH TIME ZONEबनाम के होने पर पोस्टग्रेक्यूएल में टाइमस्टैम्प मूल्यों को अलग तरीके से संग्रहीत किया जाता है WITHOUT TIME ZONE? क्या अंतरों को सरल परीक्षण मामलों के साथ चित्रित किया जा सकता है?


जवाबों:


155

अंतर दिनांक / समय प्रकार के लिए PostgreSQL प्रलेखन में शामिल किए गए हैं । हाँ, के उपचार TIMEया TIMESTAMPएक के बीच अलग है WITH TIME ZONEयाWITHOUT TIME ZONE । यह प्रभावित नहीं करता है कि मूल्यों को कैसे संग्रहीत किया जाता है; यह प्रभावित करता है कि उनकी व्याख्या कैसे की जाती है।

इन डेटा प्रकारों पर टाइम ज़ोन का प्रभाव विशेष रूप से डॉक्स में कवर किया गया है। अंतर इस बात से उत्पन्न होता है कि सिस्टम मूल्य के बारे में क्या जान सकता है:

  • मूल्य के हिस्से के रूप में एक समय क्षेत्र के साथ, मूल्य को क्लाइंट में स्थानीय समय के रूप में प्रदान किया जा सकता है।

  • मान के भाग के रूप में समय क्षेत्र के बिना, स्पष्ट डिफ़ॉल्ट समय क्षेत्र UTC है, इसलिए यह उस समय क्षेत्र के लिए प्रदान किया जाता है।

व्यवहार कम से कम तीन कारकों के आधार पर भिन्न होता है:

  • क्लाइंट में समय क्षेत्र सेटिंग।
  • डेटा प्रकार (यानी WITH TIME ZONEयाWITHOUT TIME ZONEमान )।
  • क्या मान किसी विशेष समय क्षेत्र के साथ निर्दिष्ट किया गया है।

उन कारकों के संयोजन को कवर करने वाले उदाहरण यहां दिए गए हैं:

foo=> SET TIMEZONE TO 'Japan';
SET
foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP;
      timestamp      
---------------------
 2011-01-01 00:00:00
(1 row)

foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP WITH TIME ZONE;
      timestamptz       
------------------------
 2011-01-01 00:00:00+09
(1 row)

foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP;
      timestamp      
---------------------
 2011-01-01 00:00:00
(1 row)

foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP WITH TIME ZONE;
      timestamptz       
------------------------
 2011-01-01 06:00:00+09
(1 row)

foo=> SET TIMEZONE TO 'Australia/Melbourne';
SET
foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP;
      timestamp      
---------------------
 2011-01-01 00:00:00
(1 row)

foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP WITH TIME ZONE;
      timestamptz       
------------------------
 2011-01-01 00:00:00+11
(1 row)

foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP;
      timestamp      
---------------------
 2011-01-01 00:00:00
(1 row)

foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP WITH TIME ZONE;
      timestamptz       
------------------------
 2011-01-01 08:00:00+11
(1 row)

88
मूल्यों को सम्मिलित / पुनः प्राप्त करने की प्रक्रिया का संदर्भ देने पर ही सही। लेकिन पाठकों को यह समझना चाहिए कि दोनों डेटा प्रकार, timestamp with time zoneऔर timestamp without time zone, पोस्टग्रैज में * वास्तव में समय क्षेत्र की जानकारी संग्रहीत नहीं करते हैं। आप डेटा प्रकार डॉक्टर पृष्ठ पर एक नज़र के साथ इसकी पुष्टि कर सकते हैं: दोनों प्रकार ओकटेट्स की एक ही संख्या को लेते हैं और इसमें मूल्यों की बचत होती है, इस प्रकार समय क्षेत्र जानकारी संग्रहीत करने के लिए कोई जगह नहीं है। पृष्ठ का पाठ इसकी पुष्टि करता है। एक मिथ्या नाम के कुछ: "बिना tz" का अर्थ है "डेटा डालने पर ऑफसेट की उपेक्षा" और "tz के साथ" का अर्थ है "यूटीसी को समायोजित करने के लिए ऑफसेट का उपयोग करें"।
तुलसी बोर्क

41
डेटा प्रकार एक दूसरे तरीके से एक मिथ्या नाम हैं: वे "समय क्षेत्र" कहते हैं लेकिन वास्तव में हम यूटीसी / जीएमटी से ऑफसेट के बारे में बात कर रहे हैं। एक समय क्षेत्र वास्तव में डेलाइट सेविंग टाइम (डीएसटी) और अन्य विसंगतियों के बारे में एक ऑफसेट प्लस नियम / इतिहास है।
तुलसी बोर्क

4
मैं यह कहूंगा कि डीएसटी के लिए एक ऑफसेट एक समय क्षेत्र प्लस नियम है। आप ऑफसेट दिए गए समय क्षेत्र की खोज नहीं कर सकते हैं, लेकिन आप समय क्षेत्र और डीएसटी नियमों को देखते हुए ऑफसेट की खोज कर सकते हैं।
igorsantos07

3
आधिकारिक डॉक का हवाला देते हुए : सभी समय-अवगत तिथियों और समय को यूटीसी में आंतरिक रूप से संग्रहीत किया जाता है। क्लाइंट को प्रदर्शित किए जाने से पहले वे टाइमज़ोन कॉन्फ़िगरेशन पैरामीटर द्वारा निर्दिष्ट क्षेत्र में स्थानीय समय में परिवर्तित हो जाते हैं।
गुइलुम हस्टा

2
@ igorsantos07 एक समय क्षेत्र है डीएसटी परिवर्तन और अन्य परिवर्तन के बारे में नियम / इतिहास का सेट। आपका शब्दांकन अतिश्योक्तिपूर्ण लगता है। और आपका कथन है कि "एक ऑफसेट एक समय क्षेत्र है और डीएसटी के लिए नियम" बस गलत है: एक ऑफसेट केवल घंटे, मिनट और सेकंड की एक संख्या है - अधिक कुछ नहीं, कुछ भी कम नहीं।
तुलसी बॉर्क

34

मैं इसे संदर्भित PostgreSQL प्रलेखन की तुलना में अधिक स्पष्ट रूप से समझाने की कोशिश करता हूं।

TIMESTAMPनाम का सुझाव देने के बावजूद न तो वेरिएंट एक समय क्षेत्र (या एक ऑफसेट) स्टोर करते हैं। अंतर संग्रहीत डेटा की व्याख्या में है (और इच्छित एप्लिकेशन में), स्टोरेज प्रारूप में ही नहीं:

  • TIMESTAMP WITHOUT TIME ZONEस्थानीय तिथि-समय (उर्फ। दीवार कैलेंडर तिथि और दीवार घड़ी समय) संग्रहीत करता है । जहाँ तक PostgreSQL बता सकता है (हालांकि आपका आवेदन क्या है यह जान सकता है) इसका समय क्षेत्र अनिर्दिष्ट है। इसलिए, PostgreSQL इनपुट या आउटपुट पर कोई समय क्षेत्र संबंधित रूपांतरण नहीं करता है। यदि मान डेटाबेस में दर्ज किया गया था '2011-07-01 06:30:30', तो बाद में आप इसे किस समय क्षेत्र में प्रदर्शित करते हैं, इसका कोई मैटर नहीं है, यह अभी भी वर्ष 2011, माह 07, दिन 01, 06 घंटे, 30 मिनट और 30 सेकंड (किसी प्रारूप में) कहेगा। इसके अलावा, इनपुट में आपके द्वारा निर्दिष्ट किसी भी ऑफ़सेट या टाइम ज़ोन को PostgreSQL द्वारा अनदेखा किया जाता है, इसलिए '2011-07-01 06:30:30+00'और '2011-07-01 06:30:30+05'बस के समान ही हैं '2011-07-01 06:30:30'। जावा डेवलपर्स के लिए: यह अनुरूप है java.time.LocalDateTime

  • TIMESTAMP WITH TIME ZONEUTC समय रेखा पर एक बिंदु संग्रहीत करता है। यह कैसे दिखता है (कितने घंटे, मिनट, आदि) आपके समय क्षेत्र पर निर्भर करता है, लेकिन यह हमेशा एक ही "भौतिक" तत्काल (वास्तविक भौतिक घटना के क्षण की तरह) को संदर्भित करता है। इनपुट को आंतरिक रूप से यूटीसी में बदल दिया गया है, और इसी तरह यह संग्रहीत है। उसके लिए, इनपुट की ऑफ़सेट ज्ञात होनी चाहिए, इसलिए जब इनपुट में कोई स्पष्ट ऑफ़सेट या टाइम ज़ोन न हो (जैसे '2011-07-01 06:30:30') तो यह माना जाता है कि यह पोस्टग्रेक्यूएल सत्र के वर्तमान समय क्षेत्र में है, अन्यथा स्पष्ट रूप से निर्दिष्ट ऑफ़सेट या टाइम ज़ोन का उपयोग किया जाता है (के रूप में '2011-07-01 06:30:30+05')। आउटपुट को PostgreSQL सत्र के वर्तमान समय क्षेत्र में रूपांतरित किया जाता है। जावा डेवलपर्स के लिए: यह java.time.Instant(हालांकि कम रिज़ॉल्यूशन के साथ) के अनुरूप है , लेकिन JDBC और JPA 2.2 के साथ आप इसे java.time.OffsetDateTime(या इसे) मैप करने java.util.Dateवाले हैंjava.sql.Timestamp बेशक)।

कुछ का कहना है कि दोनों TIMESTAMPभिन्नताएँ यूटीसी तिथि-समय संग्रहीत करती हैं। तरह, लेकिन यह मेरी राय में इस तरह से इसे भ्रमित करने के लिए है। TIMESTAMP WITHOUT TIME ZONEएक की तरह संग्रहीत किया जाता है TIMESTAMP WITH TIME ZONE, जो UTC टाइम ज़ोन के साथ प्रदान किया जाता है, यह उसी वर्ष, माह, दिन, घंटे, मिनट, सेकंड और माइक्रोसेकंड के रूप में होता है, जब वे स्थानीय तारीख-समय में होते हैं। लेकिन इसका मतलब यह नहीं है कि UTC व्याख्या कहे जाने वाले टाइम लाइन पर उस बिंदु का प्रतिनिधित्व करती है, यह वैसे ही है जैसे स्थानीय दिनांक-समय फ़ील्ड्स एन्कोडेड हैं। (यह समय रेखा पर डॉट्स के कुछ क्लस्टर हैं, क्योंकि वास्तविक समय क्षेत्र UTC नहीं है; हम नहीं जानते कि यह क्या है।)


एक के TIMESTAMP WITH TIME ZONEरूप में पुनः प्राप्त करने में कुछ भी गलत नहीं है Instant। दोनों UTC में समय रेखा पर एक बिंदु का प्रतिनिधित्व करते हैं। Instantमेरी राय में, OffsetDateTimeयह अधिक स्व-दस्तावेजीकरण के रूप में पसंद किया जाता है: ए TIMESTAMP WITH TIME ZONEको हमेशा डेटाबेस से यूटीसी के रूप में पुनर्प्राप्त किया जाता है, और एक Instantहमेशा यूटीसी में एक प्राकृतिक मैच होता है, जबकि OffsetDateTimeअन्य ऑफ़सेट ले जा सकते हैं।
बेसिल बोर्के

@BasilBourque दुर्भाग्य से, वर्तमान JDBC विनिर्देश, JPA 2.2 विनिर्देश, और पोस्टग्रेसीक्यूडी JDBC प्रलेखन में केवल OffsetDateTimeमैप किए गए जावा प्रकार का उल्लेख है । मुझे यकीन नहीं है कि अगर Instanceअभी भी अनौपचारिक रूप से कहीं समर्थित है।
ddekany

प्रश्न, आप कहते हैं कि किसी भी ऑफसेट को मैं इनपुट में निर्दिष्ट करता हूं जैसे कि '2011-07-01 06:30:30+00'और '2011-07-01 06:30:30+05' नजरअंदाज किया जाता है लेकिन मैं ऐसा करने में सक्षम हूं insert into test_table (date) values ('2018-03-24T00:00:00-05:00'::timestamptz);और यह इसे सही तरीके से बदलने के लिए परिवर्तित कर देगा। जहाँ तिथि समयक्षेत्र के बिना टाइमस्टैम्प है। मैं यह समझने की कोशिश कर रहा हूं कि टाइमज़ोन के साथ टाइमस्टैम्प का मुख्य मूल्य क्या है और परेशानी है।
pk1m

@ pk1m आप के साथ मामलों को जटिल करते हैं ::timestamptz। इसके साथ आप स्ट्रिंग को परिवर्तित करते हैं TIMESTAMP WITH TIME ZONE, और जब इसे आगे परिवर्तित किया WITHOUT TIME ZONEजाएगा, जो आपके सत्र समय क्षेत्र (जो कि शायद यूटीसी है) से "इंस्टेंट कैलेंडर" दिन और उस घड़ी की दीवार घड़ी के समय को संग्रहीत करेगा। यह अभी भी केवल अनिर्दिष्ट ऑफसेट (कोई क्षेत्र) के साथ एक स्थानीय टाइमस्टैम्प होगा।
ddekany

मैं अजगर के साथ काम कर रहा हूँ, और जब एक टाइमस्टैम्प जागरूक डेटेट टाइम ऑब्जेक्ट सम्मिलित करता है, तो वह सम्मिलित होता है। मुझे लगता है कि टाइम ज़ोन के साथ टाइमस्टैम्प का उपयोग करने में मूल्य है, लेकिन टाइमज़ोन को संभालने के लिए इसकी आवश्यकता नहीं है।
pk1m

12

यहाँ एक उदाहरण है जो मदद करना चाहिए। यदि आपके पास टाइमस्टैंप के साथ टाइमस्टैम्प है, तो आप उस टाइमस्टैम्प को किसी अन्य टाइमज़ोन में बदल सकते हैं। यदि आपको आधार टाइमज़ोन नहीं मिला है तो इसे सही तरीके से नहीं बदला जाएगा।

SELECT now(),
   now()::timestamp,
   now() AT TIME ZONE 'CST',
   now()::timestamp AT TIME ZONE 'CST'

आउटपुट:

-[ RECORD 1 ]---------------------------
now      | 2018-09-15 17:01:36.399357+03
now      | 2018-09-15 17:01:36.399357
timezone | 2018-09-15 08:01:36.399357
timezone | 2018-09-16 02:01:36.399357+03

5
बयान "सही ढंग से परिवर्तित नहीं किया जाएगा" बस सच नहीं है। आपको समझना होगा कि क्या timestampऔर क्या timestamptzमतलब है। timestamptzसमय (UTC) में एक निरपेक्ष बिंदु का timestampअर्थ है, जबकि यह दर्शाता है कि घड़ी एक निश्चित समय क्षेत्र में क्या दर्शाती है। इस प्रकार, timestamptzएक समय क्षेत्र में परिवर्तित करते समय आप पूछ रहे हैं कि इस निरपेक्ष बिंदु पर न्यूयॉर्क में घड़ी ने क्या दिखाया? जब आप "परिवर्तित" timestampकर रहे हैं, तो आप पूछ रहे हैं कि उस समय क्या पूर्ण बिंदु था जब न्यूयॉर्क में घड़ी ने एक्स दिखाया था?
फफिलिप

AT TIME ZONEयहां तक कि अगर आप पहले से ही समझ में निर्माण, अपने स्वयं के टीज़र एक मस्तिष्क है WITHबनाम WITHOUT TIME ZONEप्रकार के। तो यह उन्हें समझाने के लिए एक उत्सुक विकल्प है। (: ( AT TIME ZONEएक WITH TIME ZONEटाइमस्टैम्प को टाइमस्टैम्प में परिवर्तित करता है WITHOUT TIME ZONE, और इसके विपरीत ... बिल्कुल स्पष्ट नहीं है।)
ddekany

now()::timestamp AT TIME ZONE 'CST'समझ में नहीं आता है, जब तक आप जोन 'सीएसटी' के लिए किस घड़ी को नहीं दिखाते हैं, जो इस समय दिखाएगा कि आपकी स्थानीय घड़ी वर्तमान में दिख रही है
जैसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.