SQL सर्वर में TimeZone को ठीक से कैसे हैंडल करें?


34

मेरा स्थानीय विकास सर्वर मध्य पूर्व में है, लेकिन मेरा उत्पादन सर्वर यूके में है।

मुझे उपयोगकर्ता को उनके समय क्षेत्र में दिनांक दिखाने की आवश्यकता है। उदाहरण के लिए, यदि कोई उपयोगकर्ता सऊदी अरब में है तो मुझे सऊदी अरब प्रारूप के अनुसार समय दिखाने की आवश्यकता है।

क्या मुझे TimeZone नामक एक नया डेटाबेस टेबल बनाना चाहिए और UTC में समय की बचत करनी चाहिए?


प्रभावी ढंग से UTC और स्थानीय (यानी। पीएसटी) एसक्यूएल 2005 में समय के बीच दिनांक परिवर्तित http://stackoverflow.com/questions/24797/effectively-converting-dates-between-utc-and-local-ie-pst-time-in- sql-2005
mehdi

यह एक वेब अनुप्रयोग है, या डेस्कटॉप अनुप्रयोग, या ...? इसे कैसे कार्यान्वित किया जाता है यह ग्राहक वितरण तंत्र द्वारा बहुत भिन्न होता है, क्योंकि आपको जो कुछ भी चाहिए वह ग्राहक पक्ष पर निर्भर है।
जॉन सीगेल

यह वेब के साथ ही देशी मोबाइल। हां यह प्रभाव अलग-अलग ग्राहकों को अलग-अलग तरीके से होता है।
user960567

1
लगता है जैसे आपका सवाल केवल डेटाबेस के बारे में नहीं है, बल्कि इसमें एप्लिकेशन डेवलपमेंट भी शामिल है। यह स्टैक ओवरफ्लो प्रश्न आपके लिए तब अवश्य पढ़ा जाना चाहिए: डेलाइट सेविंग टाइम और टाइमज़ोन बेस्ट प्रैक्टिस
गण

जवाबों:


48

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

वैसे भी, डूइंग इट राइट के ट्रैक पर आने के लिए, समय क्षेत्र की जानकारी को समय के साथ संग्रहीत करना आवश्यक है । दूसरे शब्दों में, एहसास है कि दिनांक / समय 20130407 14:50है व्यर्थ के बिना या तो (क) समय क्षेत्र की तत्कालीन यूटीसी ऑफसेट सहित (नोट 1) , या (ख) सुनिश्चित करना कि सभी तर्क को इन मूल्यों को पहले धर्मान्तरित डालने के लिए एक निश्चित तय ऑफसेट ( सबसे अधिक संभावना है 0)। या तो उन चीजों के बिना, दो दिए गए समय मान अतुलनीय हैं , और डेटा भ्रष्ट है । (उत्तरार्द्ध विधि आग से खेल रही है (नोट 2) , वैसे, ऐसा मत करो।)

SQL Server 2008+ में, आप datetimeoffsetडेटा प्रकार का उपयोग करके समय के साथ ऑफसेट को सीधे स्टोर कर सकते हैं । (पूर्णता के लिए, 2005 और उससे पहले, मैं तत्कालीन UTC ऑफसेट मान (मिनटों में) संग्रहीत करने के लिए एक दूसरा स्तंभ जोड़ूंगा।

यह डेस्कटॉप-प्रकार के अनुप्रयोग के लिए आसान बनाता है, क्योंकि इन प्लेटफार्मों में सामान्य रूप से किसी दिनांक / समय + समय क्षेत्र को स्थानीय समय में स्वचालित रूप से परिवर्तित करने और फिर उपयोगकर्ता के क्षेत्रीय सेटिंग्स के आधार पर आउटपुट के लिए प्रारूप करने के लिए तंत्र होता है।

वेब के लिए, जो स्वाभाविक रूप से डिस्कनेक्टेड आर्किटेक्चर है, यहां तक ​​कि बैक-एंड डेटा ठीक से सेट होने के साथ, यह अधिक जटिल है क्योंकि आपको रूपांतरण और / या स्वरूपण करने में सक्षम होने के लिए क्लाइंट के बारे में जानकारी की आवश्यकता है। यह आमतौर पर उपयोगकर्ता वरीयता सेटिंग्स (आउटपुट से पहले एप्लिकेशन को कनवर्ट / स्वरूपित करता है) के माध्यम से किया जाता है, या बस सभी के लिए एक ही निश्चित प्रारूप और समय क्षेत्र ऑफसेट के साथ चीजें दिखा रहा है (जो कि स्टैक एक्सचेंज प्लेटफॉर्म वर्तमान में करता है)।

आप देख सकते हैं कि अगर बैक-एंड डेटा को ठीक से सेट नहीं किया गया है, तो बहुत जल्दी यह जटिल और हैक होने वाला है। मैं उन रास्तों में से किसी के नीचे जाने की सलाह नहीं दूंगा क्योंकि आप लाइन के नीचे और अधिक समस्याओं को समाप्त करेंगे।

नोट 1:

एक समय क्षेत्र की यूटीसी ऑफसेट तय नहीं है: दिन के उजाले की बचत पर विचार करें जहां एक जोन का यूटीसी ऑफसेट प्लस या माइनस एक घंटे से भिन्न होता है। इसके अलावा क्षेत्र की दिन की बचत की तारीखें नियमित रूप से बदलती रहती हैं। तो का उपयोग कर datetimeoffset(या की एक समग्र local timeऔर UTC offset at that time) अधिकतम जानकारी वसूली में परिणाम है।

नोट 2:

यह डेटा इनपुट को नियंत्रित करने के बारे में है। हालांकि आने वाले मूल्यों को मान्य करने के लिए कोई मूर्ख-प्रूफ तरीका नहीं है, एक साधारण मानक को लागू करना बेहतर है जिसमें संगणना शामिल नहीं है। यदि कोई सार्वजनिक API एक डेटा प्रकार की अपेक्षा करता है जिसमें ऑफ़सेट शामिल होता है, तो कॉल करने वाले के लिए यह आवश्यकता स्पष्ट हो जाएगी।

यदि ऐसा नहीं होता, तो कॉल करने वाले को दस्तावेज़ीकरण पर भरोसा करना पड़ता है (यदि वे इसे पढ़ते हैं), या गणना गलत तरीके से की जाती है, आदि विशेष रूप से वितरित सिस्टम के लिए ऑफसेट की आवश्यकता होने पर कम विफलता / बग मोड होते हैं; या यहां तक ​​कि अलग-अलग सर्वरों पर सिर्फ वेब / डेटाबेस यहां केस के रूप में)।

ऑफसेट को संचित करना वैसे भी एक पत्थर से दो पक्षियों को मारता है; और यहां तक ​​कि अगर अभी आवश्यक नहीं है , तो यह संभावना को बाद में यदि आवश्यक हो तो उपलब्ध कराता है। यह सच है कि यह अधिक भंडारण लेता है, लेकिन मुझे लगता है कि यह व्यापार-मूल्य के लायक है क्योंकि डेटा खो जाता है अगर यह पहली बार में कभी भी दर्ज नहीं किया जाता है।


3
जैसा कि मैं समझता हूं कि यह ऑफसेट टाइमज़ोन के समान नहीं है ... डेटाइमऑफ़सेट में संग्रहित समय दिन के उजाले की बचत के समय की जागरूकता जैसी जानकारी खो देता है ... अधिक जानकारी: stackoverflow.com/tags/timezone/info
पीटर मैकएवॉय

1
@PeterMcEvoy DST की यहां कोई प्रासंगिकता नहीं है। datetimeoffsetइसका अर्थ है "यह उपयोगकर्ता / कंप्यूटर का स्थानीय समय है जब बात हुई थी" - हमें यह जानने की आवश्यकता नहीं है कि क्या डीएसटी प्रभाव में था या नहीं, क्योंकि दिए गए यूटीसी ऑफसेट हमेशा वहाँ हैं ( datetimeoffsetमूल्य के भीतर एम्बेडेड )।
दाई

12

मैंने SQL सर्वर में समय क्षेत्र रूपांतरण के लिए एक व्यापक समाधान विकसित किया है। GitHub पर SQL सर्वर टाइम ज़ोन समर्थन देखें ।

यह दिन के समय की बचत सहित समय क्षेत्रों और यूटीसी से और यूटीसी के बीच रूपांतरणों को ठीक से संभालता है।

यह विज्ञापनों के उत्तर में वर्णित "टी-एसक्यूएल टूलबॉक्स" समाधान की अवधारणा के समान है, लेकिन यह माइक्रोसॉफ्ट के बजाय अधिक सामान्य IANA / Olson / TZDB टाइम ज़ोन का उपयोग करता है, और इसमें डेटा को नए रिलीज के रूप में बनाए रखने के लिए उपयोगिताओं को शामिल किया गया है TZDB बाहर आते हैं।

उदाहरण का उपयोग (ओपी का जवाब देने के लिए):

SELECT Tzdb.UtcToLocal(sysutcdatetime(), 'Asia/Riyadh') as CurrentTimeInSaudiArabia

अतिरिक्त API और विस्तृत विवरण के लिए GitHub पर रीडमी देखें ।

यह भी ध्यान दें कि चूंकि यह यूडीएफ आधारित समाधान है, इसलिए इसे प्राथमिक उद्देश्य के रूप में प्रदर्शन के साथ नहीं बनाया गया है। यह तब भी बेहतर होगा जब यह कार्यक्षमता SQL सर्वर में बनाई गई थी, इसी तरह CONVERT_TZOracle और MySQL में फ़ंक्शन कैसे मौजूद है।


6

SQL सर्वर ने 2005 में संशोधन किया जिसमें UTC में आंतरिक समयक्षेत्र को बचाया गया है। यह काफी हद तक भू-प्रतिकृति और हा प्रोजेक्टर के कारण लॉग शिपिंग से जुड़ा था, और अलग-अलग समय क्षेत्रों में सहेजे गए लॉग शिपिंग समय होने के कारण उन्हें पुनर्स्थापित करने की पुरानी पद्धति के लिए असंभव हो गया था।

इस प्रकार, UTC समय में आंतरिक रूप से सब कुछ सहेजने से SQL सर्वर को विश्व स्तर पर अच्छी तरह से काम करने की अनुमति मिली। यह एक कारण है कि विंडोज में निपटने के लिए डेलाइट बचत एक तरह का दर्द है, क्योंकि अन्य एमएस उत्पाद जैसे कि आउटलुक भी यूटीसी के रूप में आंतरिक रूप से दिनांक / समय बचाते हैं और एक ऑफसेट बनाते हैं जिसे पैच करने की आवश्यकता होती है।

मैं एक ऐसी कंपनी में काम करता हूं, जहां हमारे हजारों सर्वर हैं (एमएस SQL ​​सर्वर नहीं हैं, लेकिन सभी प्रकार के सर्वर) दुनिया भर में फैले हुए हैं, और अगर हम विशेष रूप से यूटीसी द्वारा जाने के लिए सब कुछ मजबूर नहीं करते हैं, तो हम सभी पागल हो जाएंगे बहुत जल्दी।


5

मैंने SQL सर्वर में डेटाइम और टाइमज़ोन से निपटने में किसी भी व्यक्ति की मदद करने के लिए कोडप्लेक्स पर "टी-एसक्यूएल टूलबॉक्स" परियोजना को विकसित और प्रकाशित किया है । यह खुला स्रोत है और पूरी तरह से उपयोग करने के लिए स्वतंत्र है।

यह बॉक्स से बाहर अतिरिक्त कॉन्फ़िगरेशन तालिकाओं के साथ सादे टी-एसक्यूएल का उपयोग करके आसान डेटाटाइम रूपांतरण यूडीएफ प्रदान करता है।

अपने उदाहरण में, आप निम्नलिखित नमूने का उपयोग कर सकते हैं:

SELECT [DateTimeUtil].[UDF_ConvertLocalToLocalByTimezoneIdentifier] (
    'GMT Standard Time', -- the original timezone in which your datetime is stored
    'Middle East Standard Time', -- the target timezone for your user
    '2014-03-30 01:55:00' -- the original datetime you want to convert
)

यह आपके उपयोगकर्ता के लिए परिवर्तित डेटाटाइम मान लौटाएगा।

सभी समर्थित टाइमज़ोन की एक सूची टेबल "DateTimeUtil.Timezone" में टी-एसक्यूएल बॉक्स डेटाबेस के भीतर भी प्रदान की जा सकती है।


ऐसा टूलकिट एक डेवलपर के लिए एक बड़ी मदद प्रतीत होगा। हालाँकि, एक स्केलर फ़ंक्शन क्वेरी ऑप्टिमाइज़र के लिए एक ब्लैक बॉक्स है। इसका मतलब है कि जब मैं आपके फ़ंक्शन को एक कॉलम पर लागू करता हूं, तो आपके द्वारा उल्लेखित कॉन्फ़िगरेशन तालिकाओं को कई बार हिट किया जाएगा क्योंकि परिणाम सेट में पंक्तियाँ हैं (यह मानते हुए कि मैं फ़ंक्शन का चयन केवल चयन खंड में करता हूं)। यह प्रदर्शन के मामले में एक अच्छा परिप्रेक्ष्य नहीं लगता है। मैंने वास्तव में आपके टूलकिट का परीक्षण नहीं किया है, हालांकि, मैं यह सुनिश्चित करने के लिए नहीं कह सकता, कि मैं जो जानता हूं, उसके आधार पर यह केवल एक सामान्य चिंता है।
एंड्री एम

एंड्री, निश्चित रूप से, आप एक प्रदर्शन के दृष्टिकोण से सही हैं। UDFs क्वेरी टेबल बड़े पैमाने पर डेटा संचालन के लिए डिज़ाइन नहीं किए गए हैं, लेकिन आसान उपयोग के लिए। फिर भी, वे मेरी मशीन पर लगभग 100.000 रिकॉर्ड तक ठीक करते हैं।
एडीएस

2
यदि किसी को अपने उपयोग के मामले में अधिक रिकॉर्ड संसाधित करना पड़ता है, और प्रदर्शन मायने रखता है, तो आपको पूर्व-परिकलित डेटा को बनाए रखने के बारे में बेहतर सोचना चाहिए। लेकिन फिर भी, ये यूडीएफ आवश्यक टाइमज़ोन में डेटाइम मूल्यों को बनाए रखने में मदद कर सकते हैं।
एडीएस

मेरे दृष्टिकोण से यह मुद्दा प्रदर्शन के बारे में नहीं है, और इसके बारे में और अधिक बुनियादी कार्यक्षमता प्राप्त करने के बारे में है। किसी क्वेरी से सटीक जानकारी वापस करने में सक्षम होना पहली बात है। चीजों को कैश करने के लिए कुछ अस्थायी तालिका पर काम करना और फिर क्वेरी में इसका उल्लेख करना या फिर प्रदर्शन को बेहतर बनाने के लिए संभालना।
एक्शन डैन

1

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

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