यूटीसी / जीएमटी समय को स्थानीय समय में बदलें


301

हम वेब-सेवा क्लाइंट के लिए C # एप्लिकेशन विकसित कर रहे हैं। यह विंडोज एक्सपी पीसी पर चलेगा।

वेब सेवा द्वारा लौटाए गए क्षेत्रों में से एक DateTime फ़ील्ड है। सर्वर GMT प्रारूप में एक फ़ील्ड देता है, अर्थात अंत में "Z" के साथ।

हालाँकि, हमने पाया कि .NET कुछ प्रकार के निहितार्थ रूपांतरण करता है और समय हमेशा 12 घंटे था।

निम्न कोड नमूना इसे कुछ हद तक हल करता है जिसमें 12 घंटे का अंतर चला गया है लेकिन यह एनजेड डेलाइट बचत के लिए कोई भत्ता नहीं देता है।

CultureInfo ci = new CultureInfo("en-NZ");
string date = "Web service date".ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);            

इस तिथि साइट के अनुसार :

यूटीसी / जीएमटी ऑफसेट

मानक समय क्षेत्र: UTC / GMT +12 घंटे
डेलाइट सेविंग टाइम: +1 घंटा
वर्तमान समय क्षेत्र ऑफ़सेट: UTC / GMT +13 घंटे

हम अतिरिक्त घंटे के लिए कैसे समायोजित करते हैं? क्या यह प्रोग्रामेटिक रूप से किया जा सकता है या क्या यह पीसी पर किसी प्रकार की सेटिंग है?


2
Zसमय UTC, नहीं जीएमटी को दर्शाता है। दोनों में 0.9 सेकंड तक अंतर हो सकता है।
mc0e

जवाबों:


374

इस तरह के तार के लिए 2012-09-19 01:27:30.000, DateTime.Parseयह नहीं बता सकते हैं कि दिनांक और समय किस क्षेत्र से हैं।

DateTimeएक तरह की संपत्ति है, जिसमें तीन समय क्षेत्र विकल्पों में से एक हो सकता है:

  • अनिर्दिष्ट
  • स्थानीय
  • यु.टी. सी

नोट यदि आप UTC या अपने स्थानीय समय क्षेत्र के अलावा किसी तिथि / समय का प्रतिनिधित्व करना चाहते हैं, तो आपको इसका उपयोग करना चाहिए DateTimeOffset


तो आपके प्रश्न में कोड के लिए:

DateTime convertedDate = DateTime.Parse(dateStr);

var kind = convertedDate.Kind; // will equal DateTimeKind.Unspecified

आप कहते हैं कि आप जानते हैं कि यह किस तरह का है, इसलिए इसे बताएं।

DateTime convertedDate = DateTime.SpecifyKind(
    DateTime.Parse(dateStr),
    DateTimeKind.Utc);

var kind = convertedDate.Kind; // will equal DateTimeKind.Utc

अब, जब UTC समय में सिस्टम को पता चल गया है, तो आप कॉल कर सकते हैं ToLocalTime:

DateTime dt = convertedDate.ToLocalTime();

यह आपको आवश्यक परिणाम देगा।


19
इस प्रकार को निर्दिष्ट करने का दूसरा तरीका:DateTime convertedTime = new DateTime(DateTime.Parse(dateStr).Ticks), DateTimeKind.Utc);
ब्रैड

क्या यह ToLocalTime () नहीं है? @ ब्रैड - आपके पैरेंस मेल नहीं खाते।
ट्रूविल

2
क्या यह समाधान दिन की बचत के लिए है? जब मैं इसे आज़माता हूं, तो मैं एक घंटे के लिए रुक जाता हूं।
बॉब हॉर्न

7
बदलने का कदम Kindकी DateTimeसे Unspecifiedकरने के लिए UTCअनावश्यक है। के प्रयोजनों के लिए Unspecifiedमाना UTCजाता है ToLocalTime: msdn.microsoft.com/en-us/library/…
CJ7

16
@ CJ7: हाँ, लेकिन स्पष्ट होना अन्य डेवलपर्स के लिए विशेष रूप से सहायक है, जिन्हें कोड बनाए रखना पड़ सकता है।
रयान

121

यदि आप .NET 3.5 में हैं, तो मैं System.TimeZoneInfo वर्ग का उपयोग करूंगा। Http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx देखें । यह दिन की बचत बचत को सही ढंग से ध्यान में रखना चाहिए।

// Coordinated Universal Time string from 
// DateTime.Now.ToUniversalTime().ToString("u");
string date = "2009-02-25 16:13:00Z"; 
// Local .NET timeZone.
DateTime localDateTime = DateTime.Parse(date); 
DateTime utcDateTime = localDateTime.ToUniversalTime();

// ID from: 
// "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Time Zone"
// See http://msdn.microsoft.com/en-us/library/system.timezoneinfo.id.aspx
string nzTimeZoneKey = "New Zealand Standard Time";
TimeZoneInfo nzTimeZone = TimeZoneInfo.FindSystemTimeZoneById(nzTimeZoneKey);
DateTime nzDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, nzTimeZone);

यदि आप अपने स्वयं के समय क्षेत्र में काम कर रहे हैं (एन-एनजेड इस मामले में) तो आपको टाइमजोनइन्फो से निपटने की आवश्यकता नहीं है। यह सिर्फ अनावश्यक जटिलता है। अधिक विस्तार के लिए मेरा जवाब देखें।
ड्रू नोज

11
और अगर किसी को ज़रूरत है, तो यहां मैं आपके लिए TimeZoneInfo.FindSystemTimeZoneById - codeproject.com/Messages/3867850/…
nikib3ro

प्रतिभाशाली! इस पोस्ट के लिए धन्यवाद Dan। मैं 3 दिनों के लिए इस फिक्स के लिए देख रहा हूँ।
केविन मूर

58
TimeZone.CurrentTimeZone.ToLocalTime(date);

8
यह केवल तभी काम करता है जब सिस्टम जानता है कि जिस तिथि से परिवर्तित किया जा रहा है वह UTC में है। कृपया मेरा उत्तर देखें।
ड्रू नोज

1
लेकिन UTC डिफ़ॉल्ट है यह नहीं है? इसलिए यह CJ7 के उत्तर में "अनिर्दिष्ट" के लिए काम करता है।
निक जीएन

25

DateTimeवस्तुओं है Kindकी Unspecifiedडिफ़ॉल्ट है, जो के प्रयोजनों के लिए द्वारा ToLocalTimeमाना जाता है UTC

किसी Unspecified DateTimeवस्तु का स्थानीय समय प्राप्त करने के लिए , आपको केवल ऐसा करने की आवश्यकता है:

convertedDate.ToLocalTime();

बदलने का कदम Kindकी DateTimeसे Unspecifiedकरने के लिए UTCअनावश्यक है। के प्रयोजनों के लिए Unspecifiedमाना UTCजाता है ToLocalTime: http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspx


6
और इसके विपरीत: convertedDate.FromLocalTime();में परिवर्तित हो जाएगा UTC
आर। Schreurs

16

मुझे पता है कि यह एक पुराना सवाल है, लेकिन मैं एक समान स्थिति में भाग गया, और मैं भविष्य के खोजकर्ताओं के लिए जो कुछ भी पाया था, उसे साझा करना चाहता था, संभवत: खुद को भी :)।

DateTime.Parse()मुश्किल हो सकता है - उदाहरण के लिए यहां देखें ।

यदि यह DateTimeएक वेब सेवा या किसी अन्य स्रोत से ज्ञात प्रारूप के साथ आ रहा है, तो आप कुछ इस तरह से विचार करना चाह सकते हैं

DateTime.ParseExact(dateString, 
                   "MM/dd/yyyy HH:mm:ss", 
                   CultureInfo.InvariantCulture, 
                   DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)

या, और भी बेहतर,

DateTime.TryParseExact(...)

AssumeUniversalझंडा पार्सर कि दिनांक / समय पहले से ही यूटीसी है बताता है; के संयोजन AssumeUniversalऔर AdjustToUniversalइसे "स्थानीय" समय पर परिणाम में परिवर्तित नहीं करने के लिए कहता है, जिसे वह डिफ़ॉल्ट रूप से करने का प्रयास करेगा। (मैं व्यक्तिगत रूप से वैसे भी व्यवसाय / एप्लिकेशन / सेवा परत (ओं) में यूटीसी के साथ विशेष रूप से निपटने की कोशिश करता हूं। लेकिन स्थानीय समय में रूपांतरण को दरकिनार करने से भी चीजों को गति मिलती है - मेरे परीक्षणों में 50% या अधिक, नीचे देखें।)

यहाँ हम पहले क्या कर रहे थे:

DateTime.Parse(dateString, new CultureInfo("en-US"))

हमने ऐप को प्रोफाइल कर दिया था और पाया कि DateTime.Parse ने CPU उपयोग के एक महत्वपूर्ण प्रतिशत का प्रतिनिधित्व किया। (संयोग से, CultureInfoनिर्माता CPU उपयोग में महत्वपूर्ण योगदानकर्ता नहीं था ।)

इसलिए मैंने विभिन्न तरीकों से एक तारीख / समय स्ट्रिंग 10000 बार पार्स करने के लिए एक कंसोल ऐप स्थापित किया। नीचे पंक्ति:
Parse()10 सेकंड
ParseExact()(स्थानीय में परिवर्तित) 20-45 एमएस
ParseExact()(स्थानीय में परिवर्तित नहीं) 10-15 एमएस
... और हां, सेकंडParse() में परिणाम हैं , जबकि अन्य मिलीसेकंड में हैं


14

मैं बस सावधानी का एक सामान्य नोट जोड़ना चाहूंगा।

यदि आप जो कुछ भी कर रहे हैं वह कंप्यूटर की आंतरिक घड़ी से वर्तमान समय को डिस्प्ले या एक रिपोर्ट पर तारीख / समय लगाने के लिए हो रहा है, तो सब ठीक है। लेकिन अगर आप बाद के संदर्भ के लिए तारीख / समय की जानकारी सहेज रहे हैं या तारीख / समय की गणना कर रहे हैं , तो सावधान!

मान लें कि आप निर्धारित करते हैं कि एक क्रूज जहाज 20 दिसंबर 2007 को 15:00 यूटीसी पर होनोलूलू में आया था। और आप जानना चाहते हैं कि वह कौन सा स्थानीय समय था।
1. इसमें कम से कम तीन 'स्थानीय' शामिल हैं। स्थानीय का मतलब होनोलुलु हो सकता है, या इसका मतलब यह हो सकता है कि आपका कंप्यूटर कहाँ स्थित है, या इसका मतलब यह हो सकता है कि आपका ग्राहक कहाँ स्थित है।
2. यदि आप रूपांतरण करने के लिए अंतर्निहित कार्यों का उपयोग करते हैं, तो यह संभवतः गलत होगा। ऐसा इसलिए है क्योंकि वर्तमान में आपके कंप्यूटर पर दिन के समय की बचत का समय (शायद) प्रभावी है, लेकिन दिसंबर में प्रभावी नहीं था। लेकिन विंडोज को यह नहीं पता है ... यह निर्धारित करने के लिए कि यह दिन के समय बचत प्रभाव में है, यह सब एक झंडा है। और अगर यह वर्तमान में प्रभावी है, तो यह खुशी से दिसंबर में एक घंटे को भी जोड़ देगा।
3।विभिन्न राजनीतिक उपविभागों में डेलाइट बचत समय को अलग तरीके से (या बिल्कुल नहीं) लागू किया जाता है। ऐसा मत सोचो कि सिर्फ इसलिए कि आपका देश एक विशिष्ट तिथि पर बदलता है, अन्य देश भी।


6
दरअसल, # 2 पूरी तरह से सही नहीं है। हर समयक्षेत्र में डीएसटी के बारे में वास्तव में नियम हैं जो आपके कंप्यूटर को पता चल जाएगा कि क्या जानकारी इंस्टॉल की गई है (और अपडेट की गई है)। कई क्षेत्रों के लिए, उन नियमों को तय किया गया है। अन्य लोग "गतिशील डीएसटी" को लागू करते हैं। इसके लिए ब्राज़ील मेरा पालतू जीव है। सारांश में, अगर आपका स्थानीय समय डीएसटी में होगा, तो यह मानकर काम किया जा सकता है कि अब और तब के बीच कानून में कोई बदलाव नहीं किया गया है।
रोजर विल्क

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


5

यदि आपके पास पहले से ही डेटटाइम ऑब्जेक्ट है, तो यह न भूलें और यदि यह UTC या स्थानीय है तो निश्चित नहीं है, यह आसान है कि ऑब्जेक्ट पर दिए गए तरीकों का उपयोग करें:

DateTime convertedDate = DateTime.Parse(date);
DateTime localDate = convertedDate.ToLocalTime();

हम अतिरिक्त घंटे के लिए कैसे समायोजित करते हैं?

जब तक निर्दिष्ट नहीं किया जाता है .net स्थानीय पीसी सेटिंग्स का उपयोग करेगा। मेरे पास इसका एक पाठ होगा: http://msdn.microsoft.com/en-us/library/system.globalization.daylighttime.aspx

लगता है कि कोड कुछ इस तरह दिख सकता है:

DaylightTime daylight = TimeZone.CurrentTimeZone.GetDaylightChanges( year );

और जैसा कि ऊपर डबल चेक किया गया है कि आपका सर्वर किस टाइमज़ोन सेटिंग पर है। IIS में परिवर्तनों को सुरक्षित रूप से कैसे प्रभावित किया जाए, इसके लिए नेट पर लेख हैं।


सिस्टम आपके लिए इस कॉम्प्लेक्सिटी से निपटेगा, बशर्ते आप सिस्टम को बताएं कि आपकी तारीख क्या है (स्थानीय / utc / अनिर्दिष्ट)।
ड्रू नोकें जू

2

दाना के सुझाव के जवाब में:

कोड नमूना अब ऐसा दिखता है:

string date = "Web service date"..ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);            
DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(convertedDate);

मूल तिथि 20/08/08 थी; तरह यूटीसी था।

दोनों "ConvertDate" और "dt" समान हैं:

21/08/08 10:00:26; तरह स्थानीय था


कृपया इसके स्पष्टीकरण के लिए मेरा उत्तर देखें।
ड्रू नोकें जू

1

मुझे इसके साथ एक समस्या यह थी कि एक डेटा सेट में तार (वेबसर्वर टू क्लाइंट) को धकेला जा रहा था कि यह स्वचालित रूप से बदल जाएगा क्योंकि डेटाकॉलूम का डेटटाइप फ़ील्ड स्थानीय पर सेट था। सुनिश्चित करें कि आप जाँचें कि DateType क्या है यदि आपका पुश डेटासेट भर में है।

यदि आप इसे बदलना नहीं चाहते हैं, तो इसे अनिर्दिष्ट करें


1

मुझे यह सवाल तब आया जब मुझे ट्विटर एपीआई के माध्यम से वापस प्राप्त होने वाली यूटीसी तिथियों के साथ एक समस्या हो रही थी (एक स्थिति पर फ़ील्ड बनाया गया); मुझे उन्हें DateTime में बदलने की आवश्यकता है। इस पृष्ठ पर दिए गए उत्तरों में कोई भी उत्तर / कोड नमूने मुझे "स्ट्रिंग को एक मान्य दिनांक समय के रूप में मान्यता नहीं दी गई थी" त्रुटि को रोकने के लिए पर्याप्त थे (लेकिन यह निकटतम है जो मुझे SO पर सही उत्तर खोजने के लिए मिला है)

इस लिंक को यहाँ पोस्ट करने से यह किसी और की मदद करता है - मुझे जो उत्तर चाहिए वह इस ब्लॉग पोस्ट पर पाया गया: http://www.wduffy.co.uk/blog/parsing-dates-when-aspnets-datetimeparse-doesnt-work/ - मूल रूप से DateTime.Parse के बजाय एक प्रारूप स्ट्रिंग के साथ DateTime.ParseExact का उपयोग करें

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