2011-08-30 31 views
6

नहीं दिया मैं पार्स की तारीख और समय के चारों ओर एक समस्या के साथ अटक कर रहा हूँ:पार्सिंग दिनांक समय एक ज्ञात लेकिन समय क्षेत्र

मैं एक datetime स्ट्रिंग एक जर्मन वेबसाइट से निकाली गई पार्स करने के लिए कोशिश कर रहा हूँ। यह प्रारूप में दिया जाता है '24hours day.month.year: मिनट की है, जैसे:

01.01.2011 17:00 

और यह जर्मन समय क्षेत्र में हमेशा होता है। लेकिन यहाँ समस्या आता है:

  • '01 .01.2011 17:00 यूटीसी में (यहाँ ''01 .01.2011 16:00 के साथ दिनांक समय struct में पार्स किया जाना चाहिए', समय क्षेत्र सीईटी, दिन के उजाले के बिना है बचत समय)
  • जबकि '01 .06.2011 17:00 यूटीसी में (यहाँ ''01 .01.2011 15:00 के साथ दिनांक समय struct में पार्स किया जाना चाहिए', समय क्षेत्र डेलाइट बचत समय के साथ CEST के है)

मुझे कोई संकेत नहीं है कि इसे कैसे प्राप्त किया जाए। अगर मैं अपनी स्थानीय घड़ी को जर्मन टाइमज़ोन पर सेट करता हूं, और मैं DateTime.ParseExact और ध्वज DateTimeStyles.AssumeLocal और DateTimeStyles.AdjustToUniversal के साथ पार्स करता हूं तो इसे सही ढंग से पार्स किया जाता है। हालांकि, मैं चाहता हूं कि कोई भी ग्राहक अपनी स्थानीय घड़ी और टाइमज़ोन से स्वतंत्र रूप से इसका विश्लेषण करे। इसके अलावा, मैं टाइमज़ोन खुद को ऑफ़सेट नहीं करना चाहता, क्योंकि यह तिथि (गर्मी: -2/शीतकालीन -1) पर निर्भर करता है।

एक बार जब मेरे पास यूटीसी में डेटाटाइम हो तो इसे किसी भी स्थानीय टाइमज़ोन में परिवर्तित करना आसान होगा।

+0

संभावित डुप्लिकेट [सी # एफएक्स 3.5 में एक विशिष्ट समय क्षेत्र में डेटटाइम बनाना] (http://stackoverflow.com/questions/246498/creating-a-datetime-in-a- विशिष्ट- टाइम- ज़ोन-in -सी-एफएक्स -3-5) –

+0

@ माइकल हरेन: नहीं, यह एक डुप्लिकेट नहीं है। मैंने इस सवाल से पहले यह देखा था और इससे मेरी विशिष्ट समस्या में मदद नहीं मिली। –

+0

शायद डुप्लिकेट नहीं है लेकिन मुझे लगा कि यह सहायक होगा –

उत्तर

1

के बाद भी देखा है कि काम WP7/सिल्वरलाइट ढांचे की मदद से archieved नहीं किया जा सकता हो जाएगा, मैं एक छोटे से सहायक ने लिखा है कि काम करता है:

public static class DateTimeHelper 
{ 
    /// <summary> 
    /// Tries to parse the given datetime string that is not annotated with a timezone 
    /// information but known to be in the CET/CEST zone and returns a DateTime struct 
    /// in UTC (so it can be converted to the devices local time). If it could not be 
    /// parsed, result contains the current date/time in UTC. 
    /// </summary> 
    public static bool TryParseCetCest(string s, string format, IFormatProvider provider, DateTimeStyles style, out DateTime result) 
    { 
     // Parse datetime, knowing it is in CET/CEST timezone. Parse as universal as we fix it afterwards 
     if (!DateTime.TryParseExact(s, format, provider, style, out result)) 
     { 
      result = DateTime.UtcNow; 
      return false; 
     } 
     result = DateTime.SpecifyKind(result, DateTimeKind.Utc); 

     // The boundaries of the daylight saving time period in CET and CEST (_not_ in UTC!) 
     // Both DateTime structs are of kind 'Utc', to be able to compare them with the parsing result 
     DateTime DstStart = LastSundayOf(result.Year, 3).AddHours(2); 
     DateTime DstEnd = LastSundayOf(result.Year, 10).AddHours(3); 

     // Are we inside the daylight saving time period? 
     if (DstStart.CompareTo(result) <= 0 && result.CompareTo(DstEnd) < 0) 
      result = result.AddHours(-2); // CEST = UTC+2h 
     else 
      result = result.AddHours(-1); // CET = UTC+1h 

     return true; 
    } 

    /// <summary> 
    /// Returns the last sunday of the given month and year in UTC 
    /// </summary> 
    private static DateTime LastSundayOf(int year, int month) 
    { 
     DateTime firstOfNextMonth = new DateTime(year, month + 1, 1, 0, 0, 0, DateTimeKind.Utc); 
     return firstOfNextMonth.AddDays(firstOfNextMonth.DayOfWeek == DayOfWeek.Sunday ? -7 : 
                (-1 * (int)firstOfNextMonth.DayOfWeek)); 
    } 
} 

चाल थी यह, बिना पार्स करने के लिए DateTimeStyles.AssumeUniversal ध्वज (इस TryParseExact मान तारीख UTC और तारीख लौटने परिवर्तित/स्थानीय करने के लिए समायोजित है बनाता है) यूटीसी के रूप में यह respecifying और फिर मैन्युअल रूप से actu को समायोजित करें अल यूटीसी समकक्ष।

यह डीएसटी नियमों का पालन करता है जो here पाया जा सकता है। मैंने इसे डेलाइट सेविंग टाइम के प्रारंभ/अंत के ठीक पहले/बाद के सभी 4 सीमा मामलों के साथ परीक्षण किया। इससे फिर से परीक्षण का महत्व दिखाया गया: मुझे ऑपरेटर को DstStart.CompareTo(result) < 0 से <= में सही परिणाम देने के लिए बदलना पड़ा।

मुझे यह महसूस हो रहा था कि मैं यहां पहिया को पुनर्निर्मित कर रहा हूं (जिसे मैं नफरत करता हूं), लेकिन इस सरल नौकरी के लिए समर्पित पुस्तकालय का उपयोग नहीं करना चाहता था। मैंने नोडा टाइम पर एक नज़र डाली जो कि एक महान परियोजना है, लेकिन मुझे लगता है कि इसके लिए यह जरूरी नहीं है।

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

+0

मुझे आश्चर्य है कि आपने AssumeUniversal का उपयोग नहीं किया - मुझे * अपेक्षित * होगा कि इसे पहले ही यूटीसी डेटटाइम के साथ वापस कर दिया जाए; अगर यह मामला नहीं है तो उस मोर्चे पर आपको भ्रामक बनाने के लिए क्षमा करें। डेटटाइम मुझे परेशान करता है :( –

+0

@ जोन: मैंने सोचा कि ईमानदार होने के लिए बिल्कुल वही है, और आश्चर्य हुआ कि उसने इस तरह के अजीब नतीजों का उत्पादन क्यों किया। जब तक मुझे एहसास हुआ कि यह सही चीज है लेकिन आप जो उम्मीद कर सकते हैं उससे भिन्न: यदि आप इसे '17 ' : 00 'यह उम्मीदवार की तरह 5 बजे यूटीसी मानता है लेकिन मेरे मामले (स्थानीय टाइमज़ोन = जर्मन) में 7 बजे (Kind = local) के साथ डेटटाइम स्ट्रक्चर देता है। यदि आप इस पर' निर्दिष्ट करेंकिंड (.., यूटीसी) 'कहते हैं, तो यह रिटर्न एक 7 बजे यूटीसी संरचना ... –

+0

और हाँ: डेटटाइम वास्तव में कष्टप्रद है :) –

4

ऐसा लगता है जैसे आप जानते हैं कि आपको किस समय क्षेत्र को पार्स करना चाहिए। .NET 3.5 (और इस प्रकार TimeZoneInfo) तार्किक मान लिया जाये कि आप करना चाहिए:

  • एक "स्थानीय" समय के रूप में यह पार्स (नहीं समय विशिष्ट क्षेत्र)
  • कन्वर्ट है कि एक UTC समय

को स्थानीय समय दुर्भाग्य से DateTime makes that slightly tricky। संपादित करें: I सोचा आप इसे DateTimeStyles.AssumeUniversal का उपयोग करके पार्स को कन्वर्ट करना चाहते हैं - लेकिन यह स्थानीयDateTime को परेशान करते हुए समाप्त होता है। मूल रूप से आप के साथ समाप्त करना चाहते हैं के लिए सही समय के साथ एकDateTime ताकि आप उपयोग कर सकते हैं: कि तुम सच में एक चाहते

DateTime utc = TimeZoneInfo.ConvertTimeToUtc(parsed, germanTimeZone); 

नोट:

parsed = DateTime.SpecifyKind(parsed, DateTimeKind.Unspecified); 

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

और हाँ, यह एक बहुत Noda Time में आसान इसके समाप्त होने पर :)

+0

+1 ग्रेट, 'कनवर्टटाइम टीओयूटीसी'' किसी भी तरह गायब टुकड़ा था। हालांकि, मेरे पास एक आखिरी सवाल है: मुझे 'germanTimeZone'' कहां से मिल सकता है? –

+0

@ फिलिप: आप उपयुक्त समय क्षेत्र आईडी का उपयोग करते हैं, और 'TimeZoneInfo.FindSystemTimeZoneById' का उपयोग करें। मुझे लगता है कि आप "डब्ल्यू यूरोप मानक समय" चाहते हैं (इस तथ्य को अनदेखा करें कि इसे मानक समय कहा जाता है; यह केवल आईडी है - यह अभी भी डेलाइट सेविंग टाइम को संभालेगा)। –

+0

मुझे शायद यह उल्लेख करना चाहिए था कि मैं एक विंडोज फोन 7 एप्लीकेशन बना रहा हूं, जहां 'टाइमज़ोनइन्फो 'में केवल' 'कनवर्टटाइम' विधि और समय क्षेत्र 'यूटीसी'' और 'लोकल' है। –

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