मैं दो उदाहरणों की व्याख्या करता हूं:
दोनों में हम एक टाइमज़ोन यूटीसी मानते हैं (यानी SET timezone TO UTC
)।
db=# SELECT timezone('US/Pacific', '2016-01-01 00:00');
timezone
---------------------
2015-12-31 16:00:00
(1 row)
यह SELECT timezone('US/Pacific', '2016-01-01 00:00'::timestamptz)
के बराबर है , यानी पोस्टग्रेज ने स्ट्रिंग को परोक्ष रूप से timestamptz
. में बदल दिया ।
हम जानते हैं कि timezone
फ़ंक्शन timestamp
. के बीच आगे और पीछे कनवर्ट करता है और timestamptz
:
चूँकि हम इसे एक timestamptz
दे रहे हैं इनपुट के रूप में, यह एक timestamp
आउटपुट देगा . दूसरे शब्दों में, यह समय में पूर्ण बिंदु को परिवर्तित कर रहा है 2016-01-01 00:00Z
US/Pacific
. में वॉल टाइम तक , यानी लॉस एंजिल्स की घड़ी ने उस निरपेक्ष समय पर क्या दिखाया।
उदाहरण 2 में हम इसके विपरीत काम कर रहे हैं, अर्थात् timestamp
. ले रहे हैं और इसे timestamptz
. में कनवर्ट करना . दूसरे शब्दों में, हम पूछ रहे हैं:उस समय का निरपेक्ष बिंदु क्या था जब लॉस एंजिल्स में घड़ी ने 2016-01-01 00:00
दिखाया ?
आप उल्लेख करते हैं:
'2016-01-01 00:00'::timestamp
एक timestamp
है , यानी एक दीवार समय। इसमें समय क्षेत्र की धारणा नहीं है।
मुझे लगता है कि आप timestamp
. के बीच के अंतर को पूरी तरह से नहीं समझ पाए होंगे और timestamptz
, जो यहाँ महत्वपूर्ण है। बस उन्हें दीवार के समय . के रूप में सोचें , यानी वह समय जो दुनिया में कहीं दीवार पर लटकी हुई घड़ी और पूर्ण समय पर दिखाई देता है , यानी हमारे ब्रह्मांड में पूर्ण समय।
आपने अपने उत्तर में जो उदाहरण दिए हैं वे बिल्कुल सटीक नहीं हैं।
SELECT ts FROM (VALUES
(timestamptz '2012-03-05 17:00:00+0') -- outputs 2012-03-05 17:00:00+00 --1
,(timestamptz '2012-03-05 18:00:00+1') -- outputs 2012-03-05 17:00:00+00 --2
,(timestamp '2012-03-05 18:00:00+1') -- outputs 2012-03-05 18:00:00+00 --3
,(timestamp '2012-03-05 11:00:00' AT TIME ZONE '+6') -- outputs 2012-03-05 17:00:00+00 --4
,(timestamp '2012-03-05 17:00:00' AT TIME ZONE 'UTC') -- outputs 2012-03-05 17:00:00+00 --5
,(timestamp '2012-03-05 17:00:00'::timestamp) -- outputs 2012-03-05 17:00:00+00 --6
,(timestamp '2012-03-05 17:00:00'::timestamptz) -- outputs 2012-03-05 17:00:00+00 --7
) t(ts);
आपके उदाहरण के साथ समस्या यह है कि आप एक कॉलम के साथ एक डेटा सेट बना रहे हैं। चूंकि एक कॉलम में केवल एक प्रकार हो सकता है, प्रत्येक पंक्ति (या इस मामले में एकल मान) को उसी प्रकार में परिवर्तित किया जा रहा है, अर्थात् timestamptz
, भले ही कुछ मानों की गणना timestamp
. के रूप में की गई हो (जैसे मान 3)। इस प्रकार, आपके पास यहां एक अतिरिक्त अंतर्निहित रूपांतरण है।
आइए उदाहरण को अलग-अलग प्रश्नों में विभाजित करें और देखें कि क्या हो रहा है:
उदाहरण 1
db=# SELECT timestamptz '2012-03-05 17:00:00+0';
timestamptz
------------------------
2012-03-05 17:00:00+00
जैसा कि आप पहले से ही जानते होंगे, timestamptz '2012-03-05 17:00:00+0'
और '2012-03-05 17:00:00+0'::timestamptz
समकक्ष हैं (मैं बाद वाले को पसंद करता हूं)। इस प्रकार, लेख के समान सिंटैक्स का उपयोग करने के लिए, मैं फिर से लिखूंगा:
db=# SELECT '2012-03-05 17:00:00+0'::timestamptz;
timestamptz
------------------------
2012-03-05 17:00:00+00
अब, यहाँ क्या हो रहा है? ठीक है, आपकी मूल व्याख्या से कम। स्ट्रिंग को केवल timestamptz
. के रूप में पार्स किया जाता है . जब परिणाम प्रिंट हो जाता है, तो यह वर्तमान में सेट timezone
. का उपयोग करता है config को वापस अंतर्निहित डेटा संरचना, यानी 2012-03-05 17:00:00+00
के मानव पठनीय प्रतिनिधित्व में परिवर्तित करने के लिए ।
आइए बदलते हैं timezone
कॉन्फिग करें और देखें कि क्या होता है:
db=# SET timezone TO 'Europe/Berlin';
SET
db=# SELECT '2012-03-05 17:00:00+0'::timestamptz;
timestamptz
------------------------
2012-03-05 18:00:00+01
केवल एक चीज जो बदली है वह है कैसे timestamptz
स्क्रीन पर प्रिंट हो जाता है, अर्थात् यूरोप/बर्लिन . का उपयोग करके समयक्षेत्र।
उदाहरण 2
db=# SELECT timestamptz '2012-03-05 18:00:00+1';
timestamptz
------------------------
2012-03-05 17:00:00+00
(1 row)
दोबारा, बस तारीख को पार्स कर रहा हूं।
उदाहरण 3
db=# SELECT timestamp '2012-03-05 18:00:00+1';
timestamp
---------------------
2012-03-05 18:00:00
(1 row)
यह '2012-03-05 18:00:00+1'::timestamp
जैसा ही है . यहाँ क्या होता है कि टाइमज़ोन ऑफ़सेट को केवल इसलिए अनदेखा कर दिया जाता है क्योंकि आप timestamp
मांग रहे हैं ।
उदाहरण 4
db=# SELECT timestamp '2012-03-05 11:00:00' AT TIME ZONE '+6';
timezone
------------------------
2012-03-05 17:00:00+00
(1 row)
आइए सरल होने के लिए फिर से लिखें:
db=# SELECT timezone('+6', '2012-03-05 11:00:00'::timestamp);
timezone
------------------------
2012-03-05 17:00:00+00
(1 row)
यह पूछ रहा है:पूर्ण समय क्या था जब समय क्षेत्र में दीवार पर घड़ी +6 घंटे की ऑफसेट के साथ दिखा रही थी 2012-03-05 11:00:00
?
उदाहरण 5
db=# SELECT timestamp '2012-03-05 17:00:00' AT TIME ZONE 'UTC';
timezone
------------------------
2012-03-05 17:00:00+00
(1 row)
आइए फिर से लिखें:
db=# SELECT timezone('UTC', '2012-03-05 17:00:00'::timestamp);
timezone
------------------------
2012-03-05 17:00:00+00
(1 row)
यह पूछ रहा है:जब समय क्षेत्र यूटीसी में दीवार पर घड़ी दिखा रही थी तो पूर्ण समय क्या था 2012-03-05 17:00:00
?
उदाहरण 6
db=# SELECT timestamp '2012-03-05 17:00:00'::timestamp;
timestamp
---------------------
2012-03-05 17:00:00
(1 row)
यहां आप timestamp
. पर दो बार कास्ट कर रहे हैं , जिससे कोई फर्क नहीं पड़ता। आइए सरल करें:
db=# SELECT '2012-03-05 17:00:00'::timestamp;
timestamp
---------------------
2012-03-05 17:00:00
(1 row)
मुझे लगता है कि यह स्पष्ट है।
उदाहरण 7
db=# SELECT timestamp '2012-03-05 17:00:00'::timestamptz;
timestamptz
------------------------
2012-03-05 17:00:00+00
(1 row)
आइए फिर से लिखें:
db=# SELECT ('2012-03-05 17:00:00'::timestamp)::timestamptz;
timestamptz
------------------------
2012-03-05 17:00:00+00
(1 row)
आप पहले स्ट्रिंग को timestamp
. के रूप में पार्स कर रहे हैं और फिर इसे timestamptz
. में कनवर्ट करना वर्तमान में सेट timezone
. का उपयोग करके . अगर हम timezone
बदलते हैं , हमें कुछ और मिलता है क्योंकि timestamp
को कनवर्ट करते समय Postgres उस टाइमज़ोन को मान लेता है (या एक स्ट्रिंग जिसमें टाइमज़ोन की जानकारी नहीं है) से timestamptz
. तक :
db=# SET timezone TO 'Europe/Berlin';
SET
db=# SELECT ('2012-03-05 17:00:00'::timestamp)::timestamptz;
timestamptz
------------------------
2012-03-05 17:00:00+01
(1 row)
यूटीसी में व्यक्त यह पूर्ण समय 2012-03-05 16:00:00+00
. है , इस प्रकार मूल उदाहरण से अलग है।
मुझे आशा है कि यह चीजों को स्पष्ट करता है। फिर से, timestamp
के बीच के अंतर को समझना और timestamptz
यह कुंजी है। दीवार समय बनाम पूर्ण समय के बारे में सोचें।