जवाबों:
अंतर दिनांक / समय प्रकार के लिए 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)
timestamp with time zone
और timestamp without time zone
, पोस्टग्रैज में * वास्तव में समय क्षेत्र की जानकारी संग्रहीत नहीं करते हैं। आप डेटा प्रकार डॉक्टर पृष्ठ पर एक नज़र के साथ इसकी पुष्टि कर सकते हैं: दोनों प्रकार ओकटेट्स की एक ही संख्या को लेते हैं और इसमें मूल्यों की बचत होती है, इस प्रकार समय क्षेत्र जानकारी संग्रहीत करने के लिए कोई जगह नहीं है। पृष्ठ का पाठ इसकी पुष्टि करता है। एक मिथ्या नाम के कुछ: "बिना tz" का अर्थ है "डेटा डालने पर ऑफसेट की उपेक्षा" और "tz के साथ" का अर्थ है "यूटीसी को समायोजित करने के लिए ऑफसेट का उपयोग करें"।
मैं इसे संदर्भित 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 ZONE
UTC समय रेखा पर एक बिंदु संग्रहीत करता है। यह कैसे दिखता है (कितने घंटे, मिनट, आदि) आपके समय क्षेत्र पर निर्भर करता है, लेकिन यह हमेशा एक ही "भौतिक" तत्काल (वास्तविक भौतिक घटना के क्षण की तरह) को संदर्भित करता है। इनपुट को आंतरिक रूप से यूटीसी में बदल दिया गया है, और इसी तरह यह संग्रहीत है। उसके लिए, इनपुट की ऑफ़सेट ज्ञात होनी चाहिए, इसलिए जब इनपुट में कोई स्पष्ट ऑफ़सेट या टाइम ज़ोन न हो (जैसे '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
अन्य ऑफ़सेट ले जा सकते हैं।
OffsetDateTime
मैप किए गए जावा प्रकार का उल्लेख है । मुझे यकीन नहीं है कि अगर Instance
अभी भी अनौपचारिक रूप से कहीं समर्थित है।
'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);
और यह इसे सही तरीके से बदलने के लिए परिवर्तित कर देगा। जहाँ तिथि समयक्षेत्र के बिना टाइमस्टैम्प है। मैं यह समझने की कोशिश कर रहा हूं कि टाइमज़ोन के साथ टाइमस्टैम्प का मुख्य मूल्य क्या है और परेशानी है।
::timestamptz
। इसके साथ आप स्ट्रिंग को परिवर्तित करते हैं TIMESTAMP WITH TIME ZONE
, और जब इसे आगे परिवर्तित किया WITHOUT TIME ZONE
जाएगा, जो आपके सत्र समय क्षेत्र (जो कि शायद यूटीसी है) से "इंस्टेंट कैलेंडर" दिन और उस घड़ी की दीवार घड़ी के समय को संग्रहीत करेगा। यह अभी भी केवल अनिर्दिष्ट ऑफसेट (कोई क्षेत्र) के साथ एक स्थानीय टाइमस्टैम्प होगा।
यहाँ एक उदाहरण है जो मदद करना चाहिए। यदि आपके पास टाइमस्टैंप के साथ टाइमस्टैम्प है, तो आप उस टाइमस्टैम्प को किसी अन्य टाइमज़ोन में बदल सकते हैं। यदि आपको आधार टाइमज़ोन नहीं मिला है तो इसे सही तरीके से नहीं बदला जाएगा।
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
timestamp
और क्या timestamptz
मतलब है। timestamptz
समय (UTC) में एक निरपेक्ष बिंदु का timestamp
अर्थ है, जबकि यह दर्शाता है कि घड़ी एक निश्चित समय क्षेत्र में क्या दर्शाती है। इस प्रकार, timestamptz
एक समय क्षेत्र में परिवर्तित करते समय आप पूछ रहे हैं कि इस निरपेक्ष बिंदु पर न्यूयॉर्क में घड़ी ने क्या दिखाया? जब आप "परिवर्तित" timestamp
कर रहे हैं, तो आप पूछ रहे हैं कि उस समय क्या पूर्ण बिंदु था जब न्यूयॉर्क में घड़ी ने एक्स दिखाया था?
AT TIME ZONE
यहां तक कि अगर आप पहले से ही समझ में निर्माण, अपने स्वयं के टीज़र एक मस्तिष्क है WITH
बनाम WITHOUT TIME ZONE
प्रकार के। तो यह उन्हें समझाने के लिए एक उत्सुक विकल्प है। (: ( AT TIME ZONE
एक WITH TIME ZONE
टाइमस्टैम्प को टाइमस्टैम्प में परिवर्तित करता है WITHOUT TIME ZONE
, और इसके विपरीत ... बिल्कुल स्पष्ट नहीं है।)
now()::timestamp AT TIME ZONE 'CST'
समझ में नहीं आता है, जब तक आप जोन 'सीएसटी' के लिए किस घड़ी को नहीं दिखाते हैं, जो इस समय दिखाएगा कि आपकी स्थानीय घड़ी वर्तमान में दिख रही है