2012-12-12 11 views
15

मैं प्रारूप "+ एचएच: मिमी" (या "-hh: mm") में एक स्ट्रिंग का उपयोग करने के बारे में सोच रहा हूं। क्या यह दोनों आवश्यक और पर्याप्त है?टाइमज़ोन स्टोर करने के लिए उपयुक्त डेटा प्रकार क्या है?

नोट: मुझे दिनांक या समय, बस टाइमज़ोन स्टोर करने की आवश्यकता नहीं है।

उत्तर

21

दुर्भाग्य से PostgreSQL एक समय क्षेत्र डेटा प्रकार की पेशकश नहीं करता है, तो आप शायद text उपयोग करना चाहिए।

interval पहली नज़र में लॉजिकल विकल्प की तरह लगता है, और कुछ उपयोगों के लिए उपयुक्त है। हालांकि, यह डेलाइट बचत समय पर विचार करने में विफल रहता है, और न ही यह इस तथ्य पर विचार करता है कि उसी यूटीसी ऑफ़सेट के विभिन्न क्षेत्रों में अलग-अलग डीएसटी नियम हैं।

यूटीसी ऑफ़सेट से समय क्षेत्र में 1: 1 मैपिंग नहीं है।

उदाहरण के लिए, Australia/Sydney के लिए समय क्षेत्र (न्यू साउथ वेल्स) UTC+10 (EST), या UTC+11 (EDT) डेलाइट सेविंग टाइम के दौरान होता है। हां, यह वही संक्षिप्त शब्द EST है जो संयुक्त राज्य अमेरिका का उपयोग करता है; समय क्षेत्र शब्दकोष tzdata डेटाबेस में गैर-अद्वितीय हैं, यही कारण है कि पीजी में timezone_abbreviations सेटिंग है। इससे भी बदतर, ब्रिस्बेन (क्वींसलैंड) लगभग समानांतरता में है और UTC+10 EST में है ... लेकिन इसमें डेलाइट बचत नहीं है, इसलिए कभी-कभी यह -1 पर एनएसडब्ल्यू के डीएसटी के दौरान न्यू साउथ वेल्स में ऑफसेट होता है।

(अद्यतन: अभी हाल ही में ऑस्ट्रेलिया, एक A उपसर्ग अपनाया तो यह अपने पूर्वी राज्यों TZ परिवर्णी शब्द के रूप में AEST उपयोग करता है, लेकिन EST और WST आम उपयोग में रहने)।

ज्यादा उलझन में?

यदि आपको स्टोर करने की आवश्यकता है तो यूटीसी ऑफसेट है तो interval उचित है। यदि आप समय क्षेत्र स्टोर करना चाहते हैं, तो इसे text के रूप में स्टोर करें। इस समय एक समय क्षेत्र ऑफसेट को सत्यापित करने और बदलने के लिए यह दर्द है, लेकिन कम से कम यह डीएसटी के साथ copes।

+1

क्या सभी समय क्षेत्रों के लिए कैननिकल टेक्स्ट स्ट्रिंग्स (ऑस्ट्रेलिया/सिडनी) का कोई लिंक है? – odigity

+1

हां: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones – odigity

+0

यदि आप प्रदर्शन + स्पेस सेविंग (और पोर्टेबिलिटी/लचीलापन को कम करने) को अनुकूलित करना चाहते हैं, तो tz डेटाबेस + enum अच्छा होगा –

1

शायद अंतराल

 
postgres=# select interval '01:30'; 
interval 
---------- 
01:30:00 
(1 row) 

postgres=# select interval '-01:30'; 
interval 
----------- 
-01:30:00 
(1 row) 
9

"+ एचएच: मिमी" और "-एचएच: मिमी" समय क्षेत्र नहीं हैं, वे यूटीसी ऑफ़सेट हैं। उनको बचाने के लिए एक अच्छा प्रारूप मिनटों में ऑफ़सेट के साथ एक हस्ताक्षरित पूर्णांक के रूप में हैं। आप interval जैसी चीजों का भी उपयोग कर सकते हैं, लेकिन यह केवल तभी आपकी मदद करेगा यदि आप सीधे पोस्टग्रेएसक्यूएल में दिनांक गणना करना चाहते हैं, जैसे कि क्वेरी में, आदि। आमतौर पर हालांकि आप इन गणनाओं को किसी अन्य भाषा में करते हैं, और फिर यह उस भाषा पर निर्भर करता है interval अच्छी तरह से टाइप करता है और इसकी अच्छी तिथि/समय लाइब्रेरी है या नहीं। लेकिन interval के समान प्रकार में एक पूर्णांक को परिवर्तित करना, जैसे पायथन timedelta छोटा होना चाहिए, इसलिए मैं इसे व्यक्तिगत रूप से केवल एक पूर्णांक के रूप में संग्रहीत करता हूं।

समय क्षेत्र के नाम हैं, और हालांकि समय क्षेत्र के लिए कोई मानकीकृत नाम नहीं हैं, "tz" या "zoneinfo" डेटाबेस में एक वास्तविक तथ्य है, और इसका नाम "यूरोप/पेरिस", "अमेरिका/न्यू_यॉर्क "या" यूएस/पैसिफ़िक "। उन तारों के रूप में संग्रहीत किया जाना चाहिए।

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

"पीडीटी" और "ईएसटी" जैसे संक्षेप समय क्षेत्र के नाम के रूप में प्रयोग योग्य नहीं हैं, क्योंकि वे अद्वितीय नहीं हैं। चार (मुझे लगता है, या यह पांच था?) अलग-अलग समय क्षेत्रों को "सीएसटी" कहा जाता है, इसलिए यह उपयोग करने योग्य नहीं है।

संक्षेप में: समय क्षेत्र के लिए, नाम को एक स्ट्रिंग के रूप में संग्रहीत करें। यूटीसी ऑफ़सेट के लिए, ऑफसेट को मिनटों में एक हस्ताक्षरित पूर्णांक के रूप में स्टोर करें।

+0

क्या कैनोलिक टेक्स्ट का कोई लिंक है स्ट्रिंग्स (ऑस्ट्रेलिया/सिडनी) सभी समय क्षेत्रों के लिए? – odigity

+0

हां: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones – odigity

4

एक आदर्श दुनिया में आपके पास ज्ञात टाइमज़ोन के सेट के लिए एक विदेशी कुंजी हो सकती है। आप दृश्यों और डोमेन के साथ इसके करीब कुछ कर सकते हैं।

CREATE OR REPLACE FUNCTION is_timezone(tz TEXT) RETURNS BOOLEAN as $$ 
BEGIN 
PERFORM now() AT TIME ZONE tz; 
RETURN TRUE; 
EXCEPTION WHEN invalid_parameter_value THEN 
RETURN FALSE; 
END; 
$$ language plpgsql STABLE; 

CREATE DOMAIN timezone AS CITEXT 
CHECK (is_timezone(value)); 

यह ज्ञात समय-क्षेत्रों की एक सूची है करने के लिए उपयोगी है, इस स्थिति में आप डोमेन के साथ बांटना सकता है:

डेविड ई Wheleer द्वारा इस wiki tip एक डोमेन है कि एक समय क्षेत्र के रूप में अपनी वैधता के लिए परीक्षण किया जाता है बनाता है और बस में जाना जाता है समय क्षेत्र नामों (देखें pg_timezone_names से प्राप्त) युक्त एक तालिका में बाधा लागू करने, कहीं और डोमेन का पर्दाफाश करने की जरूरत से परहेज:

CREATE TABLE tzone 
(
    tzone_name text PRIMARY KEY (tzone_name) CHECK (is_timezone(tzone_name)) 
); 

INSERT INTO tzone (tzone_name) 
SELECT name FROM pg_timezone_names; 

तो फिर तुम forei के माध्यम से लागू कर सकते हैं शुद्धता gn कुंजी:

CREATE TABLE myTable (
... 
tzone TEXT REFERENCES tzone(tzone_name) 
); 
संबंधित मुद्दे

 संबंधित मुद्दे