2011-04-15 13 views
6

मेरे पास डेटाबेस में दिनांक समय है और मैं इसे एंटीटी फ्रेमवर्क का उपयोग करके डेटाबेस से पुनर्प्राप्त करता हूं, फिर मैं डेटाकंट्रैक्टजसनसेरियलाइज़र के माध्यम से JSON API के माध्यम से डेटा पास करता हूं।DataContractJsonSerializer DateTime implicit timezone रूपांतरण

डाटाकंट्रैक्टजसनसेरियलाइज़र में संसाधित होने पर सर्वर के स्थानीय टाइमज़ोन के अनुसार दिनांक समय क्षेत्र में समय समायोजित किया गया प्रतीत होता है। व्यक्त किए गए युग का समय अपेक्षित समय से 1 घंटा आगे है। डेटटाइम प्रकार यूटीसी है, लेकिन पहले इसे निर्दिष्ट नहीं किया गया था और मुझे एक ही समस्या थी।

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

धन्यवाद

उत्तर

4

DataContractJsonSerializer इच्छा उत्पादन समय क्षेत्र भाग (+ ZZZZ) अगर आपके DateTime.Kind स्थानीय या अनिर्दिष्ट के बराबर है। यह व्यवहार XmlSerializer से अलग है जो केवल समय क्षेत्र को आउटपुट करता है यदि प्रकार निर्दिष्ट नहीं है।

internal override void WriteDateTime(DateTime value) 
    { 
     // ToUniversalTime() truncates dates to DateTime.MaxValue or DateTime.MinValue instead of throwing 
     // This will break round-tripping of these dates (see bug 9690 in CSD Developer Framework) 
     if (value.Kind != DateTimeKind.Utc) 
     { 
      long tickCount = value.Ticks - TimeZone.CurrentTimeZone.GetUtcOffset(value).Ticks; 
      if ((tickCount > DateTime.MaxValue.Ticks) || (tickCount < DateTime.MinValue.Ticks)) 
      { 
       throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
        XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.JsonDateTimeOutOfRange), new ArgumentOutOfRangeException("value"))); 
      } 
     } 

     writer.WriteString(JsonGlobals.DateTimeStartGuardReader); 
     writer.WriteValue((value.ToUniversalTime().Ticks - JsonGlobals.unixEpochTicks)/10000); 

     switch (value.Kind) 
     { 
      case DateTimeKind.Unspecified: 
      case DateTimeKind.Local: 
       // +"zzzz"; 
       TimeSpan ts = TimeZone.CurrentTimeZone.GetUtcOffset(value.ToLocalTime()); 
       if (ts.Ticks < 0) 
       { 
        writer.WriteString("-"); 
       } 
       else 
       { 
        writer.WriteString("+"); 
       } 
       int hours = Math.Abs(ts.Hours); 
       writer.WriteString((hours < 10) ? "0" + hours : hours.ToString(CultureInfo.InvariantCulture)); 
       int minutes = Math.Abs(ts.Minutes); 
       writer.WriteString((minutes < 10) ? "0" + minutes : minutes.ToString(CultureInfo.InvariantCulture)); 
       break; 
      case DateTimeKind.Utc: 
       break; 
     } 
     writer.WriteString(JsonGlobals.DateTimeEndGuardReader); 
    } 

मैं अपने मशीन

var jsonSerializer = new DataContractJsonSerializer(typeof(DateTime)); 
var date = DateTime.UtcNow; 
     Console.WriteLine("original date = " + date.ToString("s")); 
     using (var stream = new MemoryStream()) 
     { 
      jsonSerializer.WriteObject(stream, date); 

      stream.Position = 0; 
      var deserializedDate = (DateTime)jsonSerializer.ReadObject(stream); 
      Console.WriteLine("deserialized date = " + deserializedDate.ToString("s")); 

     } 

जो उम्मीद उत्पादन का उत्पादन पर निम्न परीक्षण किया है::

उत्सुक जांच JsonWriterDelegator के लिए स्रोत है जो निम्न विधि मौजूद होता है तो

original date = 2011-04-19T10:24:39 
deserialized date = 2011-04-19T10:24:39 

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

यह डीबी से बाहर खींच के बाद यूटीसी को अनिर्दिष्ट से तरह परिवर्तित

entity.Date = DateTime.SpecifyKind(entity.Date, DateTimeKind.Utc); 

फोन करके और भूल नहीं है वापस अपने वस्तु की तरह मैं

+0

मेरे राशि में SpecifyKind की वापसी मान देना डेटाटाइम को 1303500600000 + 0000 – krisdyson

+0

पर क्रमबद्ध किया गया है आपका नमूना "\/Date (1303220156217) \ /" को क्रमबद्ध करता है, जबकि मेरा "\/Date (1303500600000 + 0000) \ /" को क्रमबद्ध करता है। मुझे नहीं पता कि इसमें +0000 – krisdyson

+1

शामिल क्यों हैं, क्या आप वाकई डेटटाइमकिंड = यूटीसी हैं? मैंने बस अपनी मशीन पर फिर कोशिश की और जब डेटटाइमकिंड यूटीसी के बराबर नहीं है (या तो स्थानीय या निर्दिष्ट नहीं) टाइमज़ोन आउटपुट है। मैंने सोर्स कोड को भी देखा है और टाइमज़ोन आउटपुट नहीं होगा यदि डेटटाइमकिंड == यूटीसी – wal