स्थानीय Timezone में .NET DateTime के लिए JSON स्ट्रिंग का वर्णन दो घंटे जोड़ता है
जब मैं अपने स्थानीय पीसी पर इस जस्सु स्ट्रिंग "2020-10-05T07: 29: 00 + 00: 00" को डेट्रायट वस्तु पर रखता हूं तो यह 2020-10-05 09:29 तक समाप्त हो जाता है, जहां इसे 07:29 होना चाहिए। दिनांक स्थानीय (+00: 00) के रूप में निर्दिष्ट की गई है, इसलिए मुझे समझ में नहीं आता है कि अतिरिक्त दो घंटे कहां से आते हैं। मैं इस सवाल पर देख रहे हैं की कोशिश की Datetime समय क्षेत्र अक्रमांकन लेकिन (.ToLocalTime का उपयोग करके तिथि परिवर्तित) कुछ नहीं करता है।
संदर्भ एक बड़ा एपीआई स्ट्रिंग है जिसमें कई एपीआई के साथ बाहरी एपीआई से हवाई अड्डे हैं, कुछ यूटीसी हैं कुछ स्थानीय समय हैं। मुझे स्ट्रिंग को डिसेर्बलाइज करने का सबसे सरल तरीका खोजने की जरूरत है जो सही डेटाइम उत्पन्न करेगा।
ध्यान दें कि स्थानीय समय दुनिया में कहीं भी हो सकता है, इसलिए यह उस सर्वर पर निर्भर नहीं होना चाहिए जो एप्लिकेशन चलाता है।
यहाँ एक कोड उदाहरण का उपयोग करके न्यूटन सॉफ्ट का उपयोग किया गया है।
static void Main(string[] args)
{
var json =
"{\"UTC\": \"2020-10-05T05:29:00Z\",\"Local\": \"2020-10-05T07:29:00+00:00\" }";
var expected = new DateTime(2020,10,5,7,29,0);
var foo = JsonConvert.DeserializeObject<CustomTime>(json);
Console.WriteLine($"UTC:{foo.UTC} ({foo.UTC.Kind}).\r\nLOC:{foo.Local} ({foo.Local.Kind})");
System.Console.WriteLine(foo.Local.Equals(expected) ? "All good" : "Conversion failed");
}
public sealed class CustomTime
{
public DateTime UTC { get; set; }
public DateTime Local { get; set; }
}
मेरे समयक्षेत्र (UTC +2 DaylightSavingTime) में यह मेरा आउटपुट है:
UTC: 05-10-2020 05:29:00 (Utc)। LOC: 05-10-2020 09:29:00 (स्थानीय) रूपांतरण विफल रहा
यहां एक डॉटनेट फिडेल है https://dotnetfiddle.net/uHLdAh यह सही आउटपुट उत्पन्न करता है क्योंकि सर्वर संभवतः GMT चलाता है।
जवाब
समस्या यह है कि "2020-10-05T07: 29: 00 + 00: 00" स्थानीय समय नहीं है, इसे 0 घंटे ऑफसेट के साथ UTC समय के रूप में व्याख्या किया गया है। और, जब आप इसे अपनी मशीन पर चलाते हैं तो यह आपके वर्तमान समय क्षेत्र की ऑफसेट को जोड़ता है, अर्थात +02: 00h।
उदाहरण के लिए, अब समय 08:36 है और मेरा समय क्षेत्र CET है। अगर मैं UTC में DateTimeOffset ऑब्जेक्ट बनाता था, तो यह 2020-11-27T06: 36: 00 + 02: 00 कहेगा।
इसलिए, निम्नलिखित कोड चलाने से निष्पादन मशीन के समय क्षेत्र के आधार पर विभिन्न परिणाम मिलते हैं:
// Current time
dto = DateTimeOffset.Now;
Console.WriteLine(dto.LocalDateTime);
// UTC time
dto = DateTimeOffset.UtcNow;
Console.WriteLine(dto.LocalDateTime);
Dotnetfiddle.net पर चलने पर आउटपुट:
3/11/2007 10:30:00 AM
3/11/2007 9:30:00 AM
मेरे स्थानीय मशीन पर चलने पर आउटपुट:
2020-11-27 08:54:09
2020-11-27 08:54:09
आपको यह निर्धारित करना होगा कि यदि आपका इनपुट 0 के उचित ऑफसेट के साथ यूटीसी समय में दिया गया है, या यदि यह "स्थानीय" समय में है, तो एक दोषपूर्ण ऑफसेट के साथ। फिर आपको उस समयक्षेत्र को निर्दिष्ट करते हुए एक DateTimeOffset ऑब्जेक्ट बनाना होगा जो नई डेटाटाइम ऑब्जेक्ट के पास होना चाहिए।
var dto = new DateTimeOffset(2020,10,5,7,29,0, new TimeSpan(2, 0, 0));
Console.WriteLine(dto);
Console.WriteLine(dto.LocalDateTime.Kind);
Console.WriteLine(dto.UtcDateTime);
Console.WriteLine(dto.UtcDateTime.Kind);
निम्नलिखित उत्पादन से कौन सा उत्पादन होता है:
2020-10-05 07:29:00 +02:00
Local
2020-10-05 05:29:00
Utc
अब आपके पास एक DateTimeOffset ऑब्जेक्ट है जैसा कि अपेक्षित है।
समस्या का समाधान एक सरल साबित हुआ। बस हर समय UTC मान रहे हैं। यह रूपांतरण में सभी समस्याओं को हल करता है।
var foo = JsonConvert.DeserializeObject<CustomTime>(json, new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
});