c# सी#में एक विशिष्ट समय क्षेत्र में दिनांक समय बनाना




मानक समय दृष्टि (5)

मैं किसी मशीन पर टाइमज़ोन बदलते समय केस का परीक्षण करने के लिए एक यूनिट टेस्ट बनाने की कोशिश कर रहा हूं क्योंकि इसे गलत तरीके से सेट किया गया है और फिर सही किया गया है।

परीक्षण में मुझे किसी भी स्थानीय समय क्षेत्र में डेटटाइम ऑब्जेक्ट्स बनाने में सक्षम होने की आवश्यकता है ताकि यह सुनिश्चित किया जा सके कि परीक्षण करने वाले लोग सफलतापूर्वक ऐसा कर सकें कि वे कहां स्थित हैं।

डेटटाइम कन्स्ट्रक्टर से मैं जो देख सकता हूं उससे मैं टाइमज़ोन को स्थानीय टाइमज़ोन, यूटीसी टाइमज़ोन या निर्दिष्ट नहीं कर सकता हूं।

मैं पीएसटी जैसे विशिष्ट टाइमज़ोन के साथ डेटटाइम कैसे बना सकता हूं?


मैंने जॉन स्कीट को विस्तार विधि के साथ वेब के लिए थोड़ा सा जवाब दिया। यह एक आकर्षण की तरह अजीब पर भी काम करता है।

public static class DateTimeWithZone
{

private static readonly TimeZoneInfo timeZone;

static DateTimeWithZone()
{
//I added web.config <add key="CurrentTimeZoneId" value="Central Europe Standard Time" />
//You can add value directly into function.
    timeZone = TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings["CurrentTimeZoneId"]);
}


public static DateTime LocalTime(this DateTime t)
{
     return TimeZoneInfo.ConvertTime(t, timeZone);   
}
}

इसके लिए आपको एक कस्टम ऑब्जेक्ट बनाना होगा। आपकी कस्टम ऑब्जेक्ट में दो मान होंगे:

  • एक डेटटाइम मान
  • एक TimeZone ऑब्जेक्ट

सुनिश्चित नहीं है कि पहले से ही एक सीएलआर-प्रदत्त डेटा प्रकार है जिसमें वह है, लेकिन कम से कम टाइमज़ोन घटक पहले से ही उपलब्ध है।


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

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

मुझे लगता है कि इन संपत्ति के नाम इसे साफ़ करते हैं ...

public DateTime TimeInOriginalZone { get { return TimeZoneInfo.ConvertTime(utcDateTime, timeZone); } }
public DateTime TimeInLocalZone    { get { return TimeZoneInfo.ConvertTime(utcDateTime, TimeZoneInfo.Local); } }
public DateTime TimeInSpecificZone(TimeZoneInfo tz)
{
    return TimeZoneInfo.ConvertTime(utcDateTime, tz);
}

टाइमज़ोन के बारे में जॉन का जवाब वार्ता, लेकिन मैं इसके बजाय TimeZoneInfo का उपयोग करने का सुझाव दूंगा

व्यक्तिगत रूप से मुझे जहां संभव हो, यूटीसी में चीजों को रखना पसंद है, इसलिए मैं इस तरह की संरचना का सुझाव दूंगा:

public struct DateTimeWithZone
{
    private readonly DateTime utcDateTime;
    private readonly TimeZoneInfo timeZone;

    public DateTimeWithZone(DateTime dateTime, TimeZoneInfo timeZone)
    {
        var dateTimeUnspec = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified);
        utcDateTime = TimeZoneInfo.ConvertTimeToUtc(dateTimeUnspec, timeZone); 
        this.timeZone = timeZone;
    }

    public DateTime UniversalTime { get { return utcDateTime; } }

    public TimeZoneInfo TimeZone { get { return timeZone; } }

    public DateTime LocalTime
    { 
        get 
        { 
            return TimeZoneInfo.ConvertTime(utcDateTime, timeZone); 
        }
    }        
}

चीजों को स्पष्ट करने के लिए आप "टाइमज़ोन" नामों को "टाइमज़ोनइन्फो" में बदलना चाह सकते हैं - मैं खुद को ब्रीफर नाम पसंद करता हूं।


यहां अन्य उत्तर उपयोगी हैं लेकिन वे विशेष रूप से प्रशांत तक पहुंचने के तरीके को कवर नहीं करते हैं - यहां आप जाते हैं:

public static DateTime GmtToPacific(DateTime dateTime)
{
    return TimeZoneInfo.ConvertTimeFromUtc(dateTime,
        TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"));
}

विचित्र रूप से पर्याप्त, हालांकि "प्रशांत मानक समय" आमतौर पर "प्रशांत दैनिक समय" से कुछ अलग है, इस मामले में यह सामान्य रूप से प्रशांत समय को संदर्भित करता है। वास्तव में, यदि आप इसे लाने के लिए FindSystemTimeZoneById का उपयोग करते हैं, तो उपलब्ध गुणों में से एक एक बूल है जो आपको बता रहा है कि क्या FindSystemTimeZoneById वर्तमान में डेलाइट बचत में है या नहीं।

आप लाइब्रेरी में इसके अधिक सामान्यीकृत उदाहरण देख सकते हैं, जिसे मैंने डेटटाइम्स से निपटने के लिए एक साथ फेंक दिया है, मुझे अलग-अलग टाइमज़ोन में आवश्यकता है, जहां उपयोगकर्ता पूछ रहा है, आदि:

https://github.com/b9chris/TimeZoneInfoLib.Net

यह विंडोज़ के बाहर काम नहीं करेगा (उदाहरण के लिए लिनक्स पर मोनो) क्योंकि विंडोज रजिस्ट्री से समय की सूची आती है: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\

नीचे आप कुंजी पाएंगे (रजिस्ट्री संपादक में फ़ोल्डर आइकन); उन चाबियों के नाम हैं जिन्हें आप FindSystemTimeZoneById पास करते हैं। लिनक्स पर आपको टाइमज़ोन परिभाषाओं के एक अलग लिनक्स-मानक सेट का उपयोग करना होगा, जिसे मैंने पर्याप्त रूप से एक्सप्लोर नहीं किया है।





.net-3.5