2009-07-29 29 views
52

मानक DateTime प्रारूप से यूटीसी में रूपांतरण कैसे काम करता है?डेटटाइम.ToUniversalTime() कैसे काम करता है?

अधिक विशेष रूप से, अगर मैं एक समय क्षेत्र में एक DateTime वस्तु बनाने और उसके बाद किसी अन्य समय क्षेत्र के लिए स्विच और उस पर ToUniversalTime() चलाने के लिए, यह कैसे रूपांतरण जान लेता है कि सही ढंग से किया गया था और उस समय अभी भी सही ढंग से प्रस्तुत किया जाता है?

उत्तर

62

DateTime ऑब्जेक्ट से जुड़ा कोई अंतर्निहित टाइमज़ोन नहीं है। आप उस पर ToUniversalTime() चलाते हैं, तो यह है कि कोड में चल रहा है संदर्भ से-क्षेत्र का उपयोग।

उदाहरण के लिए, अगर मैं 1970/01/01 के युग से एक DateTime बनाते हैं, तो यह मुझे एक ही DateTime वस्तु देता है कोई फर्क नहीं पड़ता कि दुनिया में मैं कहाँ हूँ।

यदि मैं ग्रीनविच में कोड चला रहा हूं तो ToUniversalTime() चलाता हूं, तो मुझे एक ही समय मिलता है। यदि मैं वैंकूवर में रहते हुए करता हूं, तो मुझे -8 घंटे की ऑफसेट DateTime ऑब्जेक्ट मिलता है।

यही कारण है कि आपको किसी भी प्रकार के दिनांक रूपांतरण या स्थानीयकरण की आवश्यकता होने पर यूटीसी समय के रूप में अपने डेटाबेस में समय से संबंधित जानकारी स्टोर करना महत्वपूर्ण है। इस बात पर विचार करें कि क्या आपका कोडबेस किसी अन्य टाइमज़ोन में सर्वर सुविधा में स्थानांतरित हो गया है;)

संपादित करें: जोएल के उत्तर से नोट - DateTime डिफ़ॉल्ट रूप से ऑब्जेक्ट्स DateTimeKind.Local के रूप में टाइप किए गए हैं। यदि आप किसी दिनांक को पार्स करते हैं और इसे DateTimeKind.Utc पर सेट करते हैं, तो ToUniversalTime() कोई रूपांतरण नहीं करता है।

और यहां "Best Practices Coding with Date Times" पर एक लेख है, और Converting DateTimes with .Net पर एक लेख है।

+1

नहीं। यह वर्तमान समय की परवाह नहीं करता है। यह स्थानीय प्रणाली के टाइमज़ोन की परवाह करता है। –

+12

आप हमेशा * यूटीसी में समय-संबंधित जानकारी स्टोर नहीं करना चाहते हैं। यह पूरी तरह से उस जानकारी पर निर्भर करता है कि वास्तव में वह जानकारी क्या है। समय में प्रतिभागियों को आमतौर पर यूटीसी में दर्शाया जा सकता है, लेकिन सबकुछ तुरंत नहीं है। उदाहरण के लिए, मैं पैडिंगटन से 17:18 ट्रेन पर हूं। "16:18 यूटीसी" के बजाए इसे "17:18 यूरोप/लंदन" के रूप में स्टोर करना समझ में आता है - क्योंकि जब घड़ियों वापस जाते हैं, तो * स्थानीय * समय वही रहता है। –

+3

क्या आप बता सकते हैं कि मैं कैलेंडर से संबंधित उत्पाद पर काम करता हूं? ;) –

7

@womp said, इसके अलावा यह दिनांक दिनांक की संपत्ति को जांचता है कि यह पहले से ही एक यूटीसी तिथि हो सकता है।

+0

अच्छा बिंदु। यदि प्रकार स्पष्ट रूप से सेट नहीं किया गया है, तो यह स्थानीय समय मानता है, और फिर ToUniversalTime() को कॉल करने से नई तिथि पर सार्वभौमिक प्रकार को सेट किया जाता है। – womp

+0

यह इंगित करने योग्य है कि SQL सर्वर प्रकार को संग्रहीत नहीं करता है (http://stackoverflow.com/questions/823313/linq-to-sql-datetime-values-are-local-kind-unspecified-how-do-i- मेक-इट-यूटीसी) ताकि यदि आप यूएस सर्वर पर यूटीसी डेट स्टोर करते हैं, तो इसे स्थानीय –

2

डेटटाइम। ToUniversalTime स्थानीय टाइमज़ोन के टाइमज़ोन ऑफसेट को यूटीसी को डेटटाइम सामान्य करने के लिए हटा देता है। यदि आप किसी अन्य टाइमज़ोन में सामान्यीकृत मान पर DateTime.ToLocalTime का उपयोग करते हैं, तो उस टाइमज़ोन का टाइमज़ोन ऑफसेट उस टाइमज़ोन में सही प्रतिनिधित्व के लिए सामान्यीकृत मान में जोड़ा जाएगा।

29

सबसे पहले, यह जांचता है कि DateTime के Kind को पहले ही यूटीसी माना जाता है। यदि ऐसा है, तो यह वही मान देता है।

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

समय क्षेत्र में स्थानीय समय को यूटीसी समय में बदलने के लिए पर्याप्त जानकारी होती है या इसके विपरीत, हालांकि कई बार यह संदिग्ध या अमान्य है। (स्थानीय समय के जो दो बार होती है, और स्थानीय बार जो कभी नहीं हो डेलाइट बचत समय की वजह से कर रहे हैं।) इन मामलों से निपटने के लिए नियम the documentation में निर्दिष्ट कर रहे हैं:

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

वापस लौटाया गया मान DateTimeKind.Utc की Kind होगा, इसलिए यदि आप पर है कि यह जीत लिया ToUniveralTime फोन ऑफ़सेट फिर से लागू नहीं करें। (यह .NET 1.1 पर एक बड़ा सुधार है!)

यदि आप एक गैर-स्थानीय समय क्षेत्र चाहते हैं, तो आपको TimeZoneInfo का उपयोग करना चाहिए जो .NET 3.5 में पेश किया गया था (पिछले संस्करणों के लिए हैकी समाधान हैं, लेकिन वे हैं अच्छा नहीं है)। समय पर तत्काल प्रतिनिधित्व करने के लिए, आपको DateTimeOffset का उपयोग करने पर विचार करना चाहिए जिसे .NET 2.0SP1, .NET3.0SP1 और .NET 3.5 में पेश किया गया था। हालांकि, अभी भी इसके साथ जुड़े वास्तविक समय क्षेत्र नहीं हैं - बस यूटीसी से ऑफसेट। इसका मतलब है कि आप नहीं जानते कि स्थानीय समय एक घंटे बाद क्या होगा, उदाहरण के लिए - डीएसटी नियम उस समय क्षेत्र के बीच भिन्न हो सकते हैं जो उस विशेष तत्काल के लिए उसी ऑफसेट का उपयोग करने के लिए हुआ था। TimeZoneInfo को ऐतिहासिक और भविष्य के नियमों को ध्यान में रखने के लिए डिज़ाइन किया गया है, TimeZone के विपरीत जो कुछ हद तक सरल है।

असल में .NET 3.5 में समर्थन यह अपेक्षाकृत बेहतर है, लेकिन अभी भी उचित कैलेंडर अंकगणितीय के लिए वांछित कुछ छोड़ देता है। कोई भी फैंसी पोर्टिंग Joda Time .NET पर? ;)

+0

माना जाएगा क्यों .NET हमेशा यूटीसी में तिथियां संग्रहीत नहीं करेगा और समस्या को पूरी तरह से टाल देगा? या क्या यह एक और धागा वारंट करता है? – derGral

+2

आप हमेशा यूटीसी समय नहीं चाहते हैं। दिनांक/समय के मुद्दे काफी जटिल हैं, और वहां * कोई नहीं है "एक आकार सभी फिट बैठता है" नियम। हमेशा यूटीसी का उपयोग टाइमस्टैम्प के लिए ठीक है, लेकिन यह कई अन्य स्थितियों में अच्छा है। –

+0

उस दूसरे पैराग्राफ के लिए धन्यवाद। मुझे अलग-अलग समय क्षेत्रों में चीजों का परीक्षण करने के लिए कुछ कोड चल रहा है लेकिन यह आलसी प्रारंभिक कारणों से काम नहीं करता है। :( – mao47

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