2013-05-02 6 views
12

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

बेशक, मैं प्रत्येक फॉर्मटाइम पर रूपांतरण लागू कर सकता हूं। टॉस्ट्रिंग() प्रत्येक फॉर्म में कॉल या कुछ सहायक उपयोगिता को लागू करता है लेकिन यह एक समय लेने वाला कार्य है, और कुछ तीसरे पक्ष के घटक भी हैं जो कॉन्फ़िगर करने के लिए मुश्किल हैं कस्टम डेटटाइम प्रदर्शन टेम्पलेट्स।

from this moment on for this web request, 
whenever some code calls DateTime.ToString(), convert it to the local time 
     using the timezone offset given at the very beginning of the web request, 
but if possible, please keep .NET core library DateTime.ToString() calls intact 
     (I don't want to mess up event logging timestamps etc.) 

वहाँ यह करने के लिए कोई तरीका है:

अनिवार्य रूप से, मैं दिनांक समय वर्ग इस प्रकार व्यवहार करने के लिए बनाने के लिए चाहते हैं?

बीटीडब्लू, मैं एएसपी.नेट एमवीसी 4 का उपयोग कर रहा हूं, यदि यह मायने रखता है।

उत्तर

3

संक्षिप्त उत्तर यह है कि आप नहीं कर सकते हैं। HTTP अनुरोध में स्थानीय समय या टाइमज़ोन जानकारी प्रदान करने के लिए HTTP एजेंट (ब्राउज़र) के लिए HTTP (या यहां तक ​​कि एक मानक तरीका भी प्रदान नहीं करता है) की आवश्यकता नहीं है।

आप या तो जरूरत के

  • उनकी पसंदीदा समय क्षेत्र के लिए कहें, या
  • किसी भी तरह जावास्क्रिप्ट रिपोर्ट यह आप पर क्लाइंट साइड है (कुकी? Ajax? अन्य?)

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

26

आप सीधे जो भी मांगते हैं वह सीधे नहीं कर सकते हैं, लेकिन मैं कुछ विकल्पों का सुझाव दूंगा। जैसा कि निकोलस ने बताया, HTTP में कुछ भी नहीं है जो आपको समय क्षेत्र सीधे प्रदान करेगा।

विकल्प 1

  • सबसे पहले, तय आप के साथ काम करना चाहता हूँ समय क्षेत्र किस प्रकार के डेटा। दो अलग-अलग प्रकार उपलब्ध हैं, या तो माइक्रोसॉफ्ट समय क्षेत्र जो आप TimeZoneInfo कक्षा, या आईएएनए/ओल्सन समय क्षेत्र के साथ उपयोग कर सकते हैं जो शेष दुनिया का उपयोग करता है। Read here for more infoNodaTime द्वारा प्रदान किए गए कार्यान्वयन का उपयोग करके मेरी सिफारिश उत्तरार्द्ध होगी।

  • फिर निर्धारित करें कि आप किस समय क्षेत्र में कनवर्ट करना चाहते हैं। आपको अपने उपयोगकर्ता को अपना समय क्षेत्र चुनने के लिए कहीं और सेटिंग की अनुमति देनी चाहिए।

    • आप कई समय क्षेत्रों में से एक लेने के लिए एक ड्रॉप-डाउन सूची दिखाई दे सकते हैं, या आप अधिक उपयोगी कुछ, प्रदर्शन जैसे दुनिया के नक्शे है कि वे अपने समय क्षेत्र का चयन करने के लिए क्लिक कर सकते हैं कर सकते हैं। कई पुस्तकालय हैं जो जावास्क्रिप्ट में ऐसा कर सकते हैं, लेकिन मेरा पसंदीदा this one है।

    • आप उपयोग करने के लिए एक डिफ़ॉल्ट समय क्षेत्र अनुमान लगाना चाहते हैं, तो आप सूची (या मानचित्र) से चुनने से पहले जितना संभव हो उतना सटीक हो सकते हैं। jsTimeZoneDetect नामक इसके लिए एक महान पुस्तकालय है। यह ब्राउज़र की घड़ी से पूछताछ करेगा और यह अनुमान लगाएगा कि यह किस समय क्षेत्र में हो सकता है।यह काफी अच्छा है, लेकिन यह अभी भी एक अनुमान है। इसे अंधाधुंध उपयोग न करें - लेकिन प्रारंभिक बिंदु निर्धारित करने के लिए इसका उपयोग करें। अद्यतन अब आप moment.tz.guess() के साथ यह भी कर सकते हैं, moment-timezone क्षण.जेएस के घटक में।

  • अब जब कि तुम उपयोगकर्ता के समय क्षेत्र पता है, तुम उस मान का उपयोग कि स्थानीय समय क्षेत्र के लिए अपने यूटीसी DateTime मूल्यों कन्वर्ट करने के लिए कर सकते हैं। दुर्भाग्य से, ऐसा कुछ भी नहीं है जिसे आप थ्रेड पर सेट कर सकते हैं जो ऐसा करेगा। जब आप सिस्टम समय क्षेत्र बदलते हैं, तो यह सभी प्रक्रियाओं और धागे के लिए वैश्विक है। तो आपके पास समय क्षेत्र को प्रत्येक स्थान पर वापस भेजने के अलावा कोई विकल्प नहीं है जिसे आप इसे वापस भेज रहे हैं। (मेरा मानना ​​है कि यह आपका मुख्य प्रश्न था।) See this almost duplicate here.

  • इससे पहले कि आप इसे एक स्ट्रिंग में परिवर्तित करें, आपको उपयोगकर्ता के लोकेल को भी जानना होगा (जिसे आप Request.UserLanguages मान से प्राप्त कर सकते हैं)। आप इसे वर्तमान थ्रेड पर असाइन कर सकते हैं, या आप इसे DateTime.ToString() विधि के पैरामीटर के रूप में पास कर सकते हैं। यह किसी भी समय क्षेत्र रूपांतरण नहीं करता है - यह केवल यह सुनिश्चित करता है कि संख्याएं सही विभाजक हैं, सही विभाजक का उपयोग करके, और सप्ताहांत या महीनों के नामों के लिए उपयुक्त भाषा।

विकल्प 2

बिल्कुल सर्वर पर स्थानीय समय के अनुसार परिवर्तित नहीं करो।

  • जब से तुम ने कहा कि आप यूटीसी मूल्यों के साथ काम कर रहे हैं, सुनिश्चित करें कि उनके .Kind संपत्ति Utc है या नहीं। जब आप अपने डेटाबेस से लोड आप शायद इस करना चाहिए, लेकिन आप इसे मैन्युअल रूप से कर सकते हैं आप के लिए है, तो:

    myDateTime = DateTime.SpecifyKind(myDateTime, DateTimeKind.Utc); 
    
  • , वापस शुद्ध यूटीसी के रूप में ब्राउज़र के लिए भेज ISO8601 की तरह एक अपरिवर्तनीय प्रारूप में। दूसरे शब्दों में:

    myDateTime.ToString("o"); // example: "2013-05-02T21:01:26.0828604Z" 
    
  • ब्राउज़र पर कुछ जावास्क्रिप्ट का उपयोग यूटीसी के रूप में पार्स करने के लिए करें। यह स्वचालित रूप से ब्राउज़र की स्थानीय समय सेटिंग उठाएगा। एक तरह से उपयोग करने के लिए है में निर्मित जावास्क्रिप्ट में Date वस्तु, इस तरह:

    var dt = new Date('2013-05-02T21:01:26.0828604Z'); 
    

    बहरहाल, यह केवल नए ब्राउज़रों कि आईएसओ 8601 प्रारूप का समर्थन में काम करेंगे। इसके बजाय, मैं moment.js लाइब्रेरी का उपयोग करने की सलाह देता हूं। यह ब्राउज़र भर में सुसंगत है, और आईएसओ तिथियों और स्थानीयकरण के लिए इसका बेहतर समर्थन है। इसके अलावा आपको कई अन्य उपयोगी पार्सिंग और स्वरूपण कार्य मिलते हैं।

    // pass the value from your server 
    var m = moment('2013-05-02T21:01:26.0828604Z'); 
    
    // use one of the formats supported by moment.js 
    // this is locale-specific "long date time" format. 
    var s = m.format('LLLL'); 
    

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

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

आपको यह भी पता होना चाहिए कि यदि आप विकल्प # 2 चुनते हैं, तो आप ईसीएमएस्क्रिप्ट 5.1 के डिजाइन में एक दोष से प्रभावित हो सकते हैं। यह खेल में आता है यदि आप तिथियों के साथ काम कर रहे हैं जो वर्तमान में प्रभावी रूप से डेलाइट सेविंग टाइम नियमों के एक अलग सेट द्वारा कवर किए गए हैं। आप in this question, और on my blog पढ़ सकते हैं।

अगर हमारे पास HTTP शीर्षलेखों में कुछ समय क्षेत्र जानकारी थी, तो दुर्भाग्य से हम ऐसा नहीं करेंगे। ये बहुत सारे हुप्स हैं जो कूदने के लिए हैं, लेकिन यह लचीलापन और सटीकता दोनों का सबसे अच्छा तरीका है।

+0

ग्रेट उत्तर! आपने कहा कि यह जावास्क्रिप्ट में अंतर्निहित 'दिनांक' ऑब्जेक्ट के साथ भी किया जा सकता है। क्या आप यह दिखाने के लिए अपना उत्तर अपडेट करेंगे कि यह कैसे किया जा सकता है? – Scott

+0

@ स्कॉट - अपडेट किया गया। धन्यवाद। –

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