कैसे समय-समय पर निपटने के लिए


140

मेरे पास एक वेबसाइट है जो एप्लिकेशन का उपयोग करने वाले उपयोगकर्ताओं की तुलना में एक अलग समय क्षेत्र में होस्ट की जाती है। इसके अतिरिक्त, उपयोगकर्ताओं के पास एक विशिष्ट समयक्षेत्र हो सकता है। मैं सोच रहा था कि अन्य SO उपयोगकर्ता और अनुप्रयोग इस तक कैसे पहुँचते हैं? सबसे स्पष्ट हिस्सा यह है कि DB के अंदर, दिनांक / समय UTC में संग्रहीत हैं। जब सर्वर पर, सभी तिथि / समय को यूटीसी में निपटाया जाना चाहिए। हालाँकि, मैं तीन समस्याओं को देख रहा हूँ जिन्हें मैं दूर करने की कोशिश कर रहा हूँ:

  1. UTC में वर्तमान समय प्राप्त करना (आसानी से हल करना DateTime.UtcNow)।

  2. डेटाबेस से दिनांक / समय खींचना और इन्हें उपयोगकर्ता को दिखाना। विभिन्न विचारों पर तारीखों को प्रिंट करने के लिए संभावित रूप से बहुत सारे कॉल हैं। मैं दृश्य और नियंत्रकों के बीच कुछ परत के बारे में सोच रहा था जो इस मुद्दे को हल कर सकते थे। या DateTime(नीचे देखें) पर एक कस्टम एक्सटेंशन विधि है । प्रमुख पक्ष यह है कि दृश्य में डेटाइम का उपयोग करने के प्रत्येक स्थान पर, विस्तार विधि को कॉल किया जाना चाहिए!

    यह भी कुछ की तरह का उपयोग करने के लिए कठिनाई जोड़ देगा JsonResult। अब आप आसानी से कॉल नहीं कर सकते Json(myEnumerable), यह होना ही चाहिए Json(myEnumerable.Select(transformAllDates))। शायद AutoMapper इस स्थिति में मदद कर सकता है?

  3. उपयोगकर्ता से इनपुट प्राप्त करना (लोकल टू यूटीसी)। उदाहरण के लिए, किसी दिनांक के साथ प्रपत्र पोस्ट करने से पहले दिनांक को UTC में परिवर्तित करना होगा। पहली बात जो मन में आती है वह एक रिवाज बना रही है ModelBinder

यहाँ उन एक्सटेंशनों के बारे में बताया गया है जो मैंने विचारों में उपयोग किए हैं:

public static class DateTimeExtensions
{
    public static DateTime UtcToLocal(this DateTime source, 
        TimeZoneInfo localTimeZone)
    {
        return TimeZoneInfo.ConvertTimeFromUtc(source, localTimeZone);
    }

    public static DateTime LocalToUtc(this DateTime source, 
        TimeZoneInfo localTimeZone)
    {
        source = DateTime.SpecifyKind(source, DateTimeKind.Unspecified);
        return TimeZoneInfo.ConvertTimeToUtc(source, localTimeZone);
    }
}

मुझे लगता है कि टाइमज़ोन से निपटना एक ऐसी सामान्य बात होगी, बहुत सारे अनुप्रयोगों पर विचार करना अब क्लाउड आधारित है जहां सर्वर का स्थानीय समय अपेक्षित समय क्षेत्र की तुलना में बहुत भिन्न हो सकता है।

क्या इससे पहले इसे सुरुचिपूर्ण ढंग से हल किया गया है? क्या ऐसा कुछ है जो मुझे याद आ रहा है? विचारों और विचारों की बहुत सराहना की जाती है।

संपादित करें: कुछ भ्रम को दूर करने के लिए मैंने सोचा कि कुछ और विवरण जोड़ें। अभी समस्या यह नहीं है कि UTC बार db में कैसे स्टोर किया जाए, यह UTC-> लोकल और लोकल-> UTC से जाने की प्रक्रिया के बारे में अधिक है। @Max Zerbini के अनुसार, यह स्पष्ट रूप से UTC-> स्थानीय कोड को देखने के लिए स्मार्ट है, लेकिन क्या DateTimeExtensionsवास्तव में इसका उत्तर उपयोग कर रहा है ? उपयोगकर्ता से इनपुट प्राप्त करते समय, क्या यह उपयोगकर्ता के स्थानीय समय के रूप में तारीखों को स्वीकार करने के लिए समझ में आता है (क्योंकि जेएस का उपयोग किया जाएगा) और फिर ModelBinderयूटीसी में बदलने के लिए उपयोग करें ? उपयोगकर्ता के समयक्षेत्र को DB में संग्रहीत किया जाता है और आसानी से पुनर्प्राप्त किया जाता है।


3
आप पहली बार इस उत्कृष्ट पोस्ट के माध्यम से पढ़ सकते हैं ... डेलाइट बचत समय और
टाइमज़ोन

@dodgy_coder - यह हमेशा टाइमज़ोन के लिए एक महान संसाधन लिंक रहा है। हालाँकि, यह वास्तव में मेरी किसी भी समस्या (विशेष रूप से MVC से संबंधित) को हल नहीं करता है। हालांकि धन्यवाद।
TheCloudlessSky

code.google.com/p/noda-time उपयोगी हो सकता है
अर्निस लैपासा

जिज्ञासु जो समाधान आप में चुना है। खुद भी ऐसे ही फैसले का सामना कर रहे हैं। अच्छा प्रश्न।
शॉन

@ सीन - इस प्रकार समाधान अब तक सुरुचिपूर्ण नहीं रहा है (यही कारण है कि मैंने अभी तक एक उत्तर स्वीकार नहीं किया है)। यह मुद्रण तिथियों / समयों के मैनुअल ओवरहेड का एक बहुत कुछ रहा है और मैन्युअल रूप से उन्हें वापस एक साथ परिवर्तित कर रहा है ModelBinder
theCloudlessSky

जवाबों:


106

ऐसा नहीं है कि यह एक सिफारिश है, एक प्रतिमान के अपने अधिक साझाकरण, लेकिन मैंने एक वेब ऐप में टाइमज़ोन जानकारी को संभालने के लिए सबसे अधिक आक्रामक तरीका (जो ASP.NET MVC के लिए अनन्य नहीं है) निम्नलिखित था:

  • सर्वर पर सभी दिनांक बार UTC हैं। इसका मतलब है कि जैसा आपने कहा, उपयोग करना DateTime.UtcNow

  • जितना संभव हो कम से कम सर्वर से गुजरने वाले क्लाइंट पर भरोसा करने की कोशिश करें। उदाहरण के लिए, यदि आपको "अभी" की आवश्यकता है, तो क्लाइंट पर एक तारीख न बनाएं और फिर इसे सर्वर पर भेज दें। या तो अपने GET में एक तारीख बनाएं और उसे ViewModel या POST पर पास करें DateTime.UtcNow

अब तक, सुंदर मानक किराया, लेकिन यह वह जगह है जहाँ चीजें 'दिलचस्प' मिलती हैं।

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

  • जब वे विचार प्रस्तुत करते हैं, तो वे एचटीएमएल 5 <time>तत्व का उपयोग कर रहे थे , वे सीधे व्यूमेटल में डेटासेट को प्रस्तुत नहीं करेंगे। इसे HtmlHelperविस्तार के रूप में लागू किया गया था , जैसे कुछ Html.Time(Model.when)। यह प्रस्तुत करना होगा <time datetime='[utctime]' data-date-format='[datetimeformat]'></time>

    तब वे ग्राहकों को स्थानीय समय में यूटीसी समय का अनुवाद करने के लिए जावास्क्रिप्ट का उपयोग करेंगे। स्क्रिप्ट सभी <time>तत्वों को खोजेगी और date-formatडेट को प्रारूपित करने और तत्व की सामग्री को पॉप्युलेट करने के लिए डेटा प्रॉपर्टी का उपयोग करेगी ।

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

मैं यह नहीं कह रहा हूं कि यह सबसे अच्छा तरीका था, लेकिन यह एक अलग था जिसे मैंने पहले नहीं देखा था। हो सकता है कि आप इससे कुछ दिलचस्प विचारों को चमका देंगे।


आपके प्रतिक्रिया के लिए धन्येवाद। जब उपयोगकर्ता से तारीख इनपुट प्राप्त कर रहे हैं (उदाहरण के लिए एक नियुक्ति का समय निर्धारण), क्या यह इनपुट उनके वर्तमान समयक्षेत्र में नहीं माना जाता है? कार्रवाई में प्रवेश करने से पहले आप इस परिवर्तन को करने वाले मॉडलबिंदर के बारे में क्या सोचते हैं (मेरी टिप्पणी @casperOne पर देखें। साथ ही, यह <time>विचार बहुत अच्छा है। केवल नुकसान यह है कि इसका मतलब है कि मुझे इन तत्वों के लिए पूरे डोम को क्वेरी करने की आवश्यकता है, जो तारीखें बदलना ठीक नहीं है (जेएस अक्षम के बारे में क्या?) फिर से धन्यवाद!
TheCloudlessSky

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

2
मैंने तब से एक और प्रोजेक्ट पर काम किया है जिसमें स्थानीय तारीखों की ज़रूरत थी और यह वह तरीका था जिसका मैंने इस्तेमाल किया। मैं दिनांक / समय प्रारूपण करने के लिए क्षणों का उपयोग कर रहा हूं ... यह मीठा है। धन्यवाद!
theCloudlessSky

वहाँ अनुप्रयोग में परिभाषित करने के लिए एक आसान तरीका नहीं है। अनुप्रयोग का एक अनुप्रयोग गुंजाइश समयक्षेत्र / web.cofig की और यह DateTime.UtcNow में सभी DateTime.Now मूल्यों बारी? (मैं उन परिस्थितियों से बचना चाहता हूं जहां कंपनी में प्रोग्रामर अभी भी डेटटाइम का उपयोग करेंगे। अब गलती से भी)
उरी अब्रामसन

3
इस दृष्टिकोण का एक नुकसान जो मैं देख सकता हूं वह यह है कि जब आप अन्य चीजों के लिए समय का उपयोग कर रहे हैं, तो पीडीएफ, ईमेल और इस तरह से बना रहे हैं, उन लोगों के लिए समय तत्व नहीं है, इसलिए आपको अभी भी उन लोगों को मैन्युअल रूप से परिवर्तित करना होगा। अन्यथा, बहुत साफ समाधान
shenku

15

कई प्रतिक्रियाओं के बाद, यहां मेरा अंतिम समाधान है जो मुझे लगता है कि स्वच्छ और सरल है और दिन के उजाले की बचत के मुद्दों को कवर करता है।

1 - हम मॉडल स्तर पर रूपांतरण को संभालते हैं। इसलिए, मॉडल वर्ग में, हम लिखते हैं:

    public class Quote
    {
        ...
        public DateTime DateCreated
        {
            get { return CRM.Global.ToLocalTime(_DateCreated); }
            set { _DateCreated = value.ToUniversalTime(); }
        }
        private DateTime _DateCreated { get; set; }
        ...
    }

2 - एक वैश्विक सहायक में हम अपना कस्टम फंक्शन "ToLocalTime" बनाते हैं:

    public static DateTime ToLocalTime(DateTime utcDate)
    {
        var localTimeZoneId = "China Standard Time";
        var localTimeZone = TimeZoneInfo.FindSystemTimeZoneById(localTimeZoneId);
        var localTime = TimeZoneInfo.ConvertTimeFromUtc(utcDate, localTimeZone);
        return localTime;
    }

3 - हम इसे और बेहतर कर सकते हैं, प्रत्येक यूजर प्रोफाइल में टाइमज़ोन आईडी को सेव करके ताकि हम निरंतर "चाइना स्टैंडर्ड टाइम" का उपयोग करने के बजाय उपयोगकर्ता वर्ग से पुनर्प्राप्त कर सकें:

public class Contact
{
    ...
    public string TimeZone { get; set; }
    ...
}

4 - यहां हम ड्रॉपडाउन से चयन करने के लिए उपयोगकर्ता को दिखाने के लिए टाइमज़ोन की सूची प्राप्त कर सकते हैं:

public class ListHelper
{
    public IEnumerable<SelectListItem> GetTimeZoneList()
    {
        var list = from tz in TimeZoneInfo.GetSystemTimeZones()
                   select new SelectListItem { Value = tz.Id, Text = tz.DisplayName };

        return list;
    }
}

इसलिए, अब चीन में 9:25 बजे, वेबसाइट यूएसए में होस्ट की गई, डेटाबेस में UTC में सहेजी गई तिथि, यहाँ अंतिम परिणाम है:

5/9/2013 6:25:58 PM (Server - in USA) 
5/10/2013 1:25:58 AM (Database - Converted UTC)
5/10/2013 9:25:58 AM (Local - in China)

संपादित करें

मूल समाधान के कमजोर भागों को इंगित करने के लिए मैट जॉनसन के लिए धन्यवाद , और मूल पोस्ट को हटाने के लिए खेद है, लेकिन मुद्दों को सही कोड डिस्प्ले प्रारूप मिल रहा है ... निकला संपादक को "पूर्व कोड" के साथ "बुलेट" मिश्रण करने में समस्याएं हैं, इसलिए मैं। बल्बों को हटा दिया और यह ठीक था।


यह काम करने योग्य प्रतीत होता है यदि कुछ में एन-टियर आर्किटेक्चर नहीं है या वेब लाइब्रेरी साझा नहीं की गई है। हम डेटा लेयर पर टाइमज़ोन आईडी कैसे साझा कर सकते हैं।
विकाश कुमार

9

Sf4answers के ईवेंट अनुभाग में , उपयोगकर्ता किसी ईवेंट के लिए एक पता दर्ज करते हैं, साथ ही एक आरंभ तिथि और एक वैकल्पिक समाप्ति तिथि भी दर्ज करते हैं। इन समयों को SQL सर्वर में अनुवादित किया जाता है जो UTC से ऑफसेट के लिए खाते हैं।datetimeoffset

यह वही समस्या है जिसका आप सामना कर रहे हैं (हालांकि आप इसके लिए एक अलग दृष्टिकोण ले रहे हैं, जिसमें आप उपयोग कर रहे हैं DateTime.UtcNow); आपके पास एक स्थान है और आपको एक समयक्षेत्र से दूसरे समय में अनुवाद करने की आवश्यकता है।

मेरे द्वारा किए गए दो मुख्य काम हैं। सबसे पहले, DateTimeOffsetसंरचना का उपयोग करें , हमेशा। यह यूटीसी से ऑफसेट के लिए जिम्मेदार है और यदि आप अपने ग्राहक से वह जानकारी प्राप्त कर सकते हैं, तो यह आपके जीवन को थोड़ा आसान बनाता है।

दूसरा, अनुवाद करते समय, यह मानते हुए कि ग्राहक जिस स्थान / समय क्षेत्र में है, आप जानते हैं, आप सार्वजनिक सूचना समय क्षेत्र डेटाबेस का उपयोग UTC से दूसरे समय क्षेत्र (या त्रिभुज, यदि आप करेंगे, दो के बीच) का अनुवाद करने के लिए कर सकते हैं समय क्षेत्र)। Tz डेटाबेस (कभी-कभी ओल्सन डेटाबेस के रूप में संदर्भित ) के बारे में महान बात यह है कि यह पूरे इतिहास में समय क्षेत्र में परिवर्तन के लिए जिम्मेदार है; ऑफ़सेट प्राप्त करना उस दिनांक का एक कार्य है जिसे आप ऑफ़सेट प्राप्त करना चाहते हैं (बस 2005 के ऊर्जा नीति अधिनियम को देखें जिसने यूएस में डेलाइट बचत समय प्रभावी होने पर तिथियां बदल दीं )।

हाथ में डेटाबेस के साथ, आप ZoneInfo (tz database / Olson database) .NET API का उपयोग कर सकते हैं । ध्यान दें कि कोई बाइनरी वितरण नहीं है, आपको नवीनतम संस्करण डाउनलोड करना होगा और इसे स्वयं संकलित करना होगा।

इस लेखन के समय, यह वर्तमान में नवीनतम डेटा वितरण में सभी फ़ाइलों को पार्स करता है (मैंने वास्तव में इसे 25 सितंबर को ftels://elsie.nci.nih.gov/pub/tzdata2011k.tar.gg फ़ाइल के खिलाफ चलाया था । 2011; मार्च 2017 में, आप इसे https://iana.org/time-zones के माध्यम से या ftp://fpt.iana.org/tz/releases/tzdata2017a.tar.gz ) के माध्यम से प्राप्त करेंगे ।

इसलिए sf4answers पर, पता मिलने के बाद, इसे अक्षांश / देशांतर संयोजन में जियोकोडेड किया जाता है और फिर टाइमज़ोन प्राप्त करने के लिए एक तृतीय-पक्ष वेब सेवा पर भेजा जाता है जो tz डेटाबेस में एक प्रविष्टि से मेल खाती है। वहां से, शुरू और अंत समय DateTimeOffsetउचित यूटीसी ऑफसेट के साथ उदाहरणों में परिवर्तित हो जाते हैं और फिर डेटाबेस में संग्रहीत होते हैं।

एसओ और वेबसाइटों पर इससे निपटने के लिए, यह दर्शकों पर निर्भर करता है और आप क्या प्रदर्शित करने का प्रयास कर रहे हैं। यदि आप ध्यान दें, तो अधिकांश सामाजिक वेबसाइट (और SO, और sf4answers पर ईवेंट अनुभाग) सापेक्ष समय में ईवेंट प्रदर्शित करते हैं , या, यदि कोई निरपेक्ष मान का उपयोग किया जाता है, तो यह आमतौर पर यूटीसी होता है।

हालाँकि, यदि आपके दर्शक स्थानीय समय की अपेक्षा करते हैं, तो DateTimeOffsetएक विस्तार विधि के साथ उपयोग करना जो कन्वर्ट करने के लिए समय क्षेत्र लेता है, बस ठीक होगा; SQL डेटा प्रकार datetimeoffset.NET का अनुवाद करेगा DateTimeOffsetजिसे आप GetUniversalTimeविधि का उपयोग करने के लिए सार्वभौमिक समय प्राप्त कर सकते हैं । वहां से, आप बस ZoneInfoयूटीसी से स्थानीय समय में बदलने के लिए कक्षा में विधियों का उपयोग करते हैं (आपको इसे प्राप्त करने के लिए थोड़ा काम करना होगा DateTimeOffset, लेकिन यह करना काफी सरल है)।

परिवर्तन कहां करें? यह एक ऐसी लागत है जिसका आपको कहीं भुगतान करना होगा , और कोई "सर्वश्रेष्ठ" तरीका नहीं है। हालाँकि, मैं दृश्य मॉडल के भाग के रूप में दृश्य के लिए प्रस्तुत किए गए टाइमज़ोन ऑफसेट के साथ दृश्य को चुनूंगा। इस तरह, यदि दृश्य की आवश्यकताएं बदल जाती हैं, तो आपको परिवर्तन को समायोजित करने के लिए अपना दृश्य मॉडल बदलना नहीं होगा। आपके JsonResultपास बस और ऑफसेट के साथ एक मॉडल होगा ।IEnumerable<T>

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


आपकी विस्तृत प्रतिक्रिया के लिए धन्यवाद। मुझे आशा है कि मैं असभ्य के रूप में सामने नहीं आऊंगा, लेकिन यह वास्तव में ASP.NET MVC के साथ मेरी चिंताओं में से किसी का भी जवाब नहीं देता है: उपयोगकर्ता इनपुट के बारे में (कस्टम मॉडल बाइंडर प्रत्यय का उपयोग करके) क्या होगा? और सबसे महत्वपूर्ण बात, इन तिथियों (उपयोगकर्ता के स्थानीय समय क्षेत्र में) को प्रदर्शित करने के बारे में क्या ? मुझे ऐसा लगता है कि विस्तार विधि मेरे विचारों में बहुत अधिक वजन जोड़ने वाली है जो अनावश्यक लगता है।
TheCloudlessSky

1
@ TheCloudlessSky: मेरी संपादित प्रतिक्रिया के अंतिम दो पैराग्राफ देखें। व्यक्तिगत रूप से, मुझे लगता है कि परिवर्तनों को कहाँ करना है, इसका विवरण मामूली है; मुख्य मुद्दा वास्तविक रूपांतरण और डेटाटाइम डेटा (btw) का भंडारण है, मैं datetimeoffsetSQL सर्वर और DateTimeOffset.NET में पर्याप्त उपयोग पर जोर नहीं दे सकता , यहां वे वास्तव में चीजों को बहुत सरल करते हैं) जो मुझे विश्वास है कि .NET पर्याप्त रूप से संभाल नहीं करता है ऊपर उल्लिखित कारणों के लिए। यदि आपके पास NYC में एक तारीख है जिसे 2003 में दर्ज किया गया था, और फिर आप इसे 2011 में LA में एक तारीख को अनुवादित करना चाहते हैं। .NET इस मामले में कठिन नहीं है।
कैस्परऑन

मॉडल बांधने की मशीन (या कार्रवाई से पहले किसी भी परत) का उपयोग नहीं करने के साथ समस्या यह है कि तारीखों के साथ काम करते समय प्रत्येक नियंत्रक का परीक्षण करना बहुत कठिन हो जाता है (वे सभी तिथि-रूपांतरण पर निर्भरता प्राप्त करेंगे)। इससे यूनिट टेस्ट की तिथियां UTC में लिखी जा सकेंगी। मेरे आवेदन में ऐसे उपयोगकर्ता हैं जो एक प्रोफ़ाइल से संबंधित हैं (डॉक्टर / सचिवों को उनके अभ्यास से जुड़े)। प्रोफ़ाइल समय-क्षेत्र जानकारी रखती है। इसलिए, वर्तमान उपयोगकर्ता की प्रोफ़ाइल का टाइमज़ोन प्राप्त करना और बाइंडिंग के दौरान रूपांतरित करना बहुत आसान है। क्या आपके पास इसके खिलाफ अन्य तर्क हैं? आपके सहयोग के लिए धन्यवाद!
TheCloudlessSky

इसके विरूद्ध मामला यह है कि आपके परीक्षण परीक्षण मामलों को सटीक रूप से प्रतिबिंबित नहीं करेंगे। आपका इनपुट UTC में नहीं होने वाला है, इसलिए आपके परीक्षण मामलों को इसका उपयोग करने के लिए तैयार नहीं किया जाना चाहिए। यह स्थानों और सभी के साथ वास्तविक दुनिया की तारीखों का उपयोग करना चाहिए (हालांकि यदि आप उपयोग करते हैं DateTimeOffsetतो यह एक बड़ा सौदा, IMO को कम कर देगा)।
कैस्परऑन

हां - लेकिन इसका मतलब है कि तारीखों से निपटने वाले प्रत्येक परीक्षण को इसके लिए जिम्मेदार होना चाहिए। डेटासेट से संबंधित हर क्रिया हमेशा यूटीसी में बदल जाएगी । मेरे लिए यह मॉडल बाइंडर के लिए एक प्रमुख उम्मीदवार है और फिर मॉडल बाइंडर का परीक्षण करें
theCloudlessSky

5

यह सिर्फ मेरी राय है, मुझे लगता है कि एमवीसी एप्लिकेशन को डेटा मॉडल प्रबंधन से डेटा प्रस्तुति समस्या को अलग करना चाहिए। एक डेटाबेस स्थानीय सर्वर समय में डेटा स्टोर कर सकता है लेकिन स्थानीय उपयोगकर्ता टाइमज़ोन का उपयोग करके डेटाटाइम को प्रस्तुत करना प्रस्तुति परत का एक कर्तव्य है। यह मुझे I18N और विभिन्न देशों के लिए संख्या प्रारूप जैसी ही समस्या लगती है। आपके मामले में, आपके एप्लिकेशन को Cultureउपयोगकर्ता के समय और समय का पता लगाना चाहिए और अलग-अलग पाठ, संख्या और डेटाइम प्रस्तुति दिखाते हुए दृश्य को बदलना चाहिए , लेकिन संग्रहीत डेटा में एक ही प्रारूप हो सकता है।


आपके प्रतिक्रिया के लिए धन्येवाद। हाँ, यह वही है जो मैंने मूल रूप से वर्णित किया है, मैं सोच रहा हूं कि यह कैसे एमवीसी के साथ शान से हासिल किया जा सकता है। ऐप उपयोगकर्ता के टाइमज़ोन को उनके खाता निर्माण के भाग के रूप में संग्रहीत करता है (वे अपना टाइमज़ोम चुनते हैं)। समस्या फिर से आती है कि कैसे मैं (उम्मीद के बिना ) प्रत्येक दृश्य में तारीखों को प्रस्तुत करने के लिए उन्हें उन तरीकों से अटे पड़े, जिनके लिए मैंने बनाया था DateTimeExtensions
TheCloudlessSky

ऐसा करने के कई तरीके हैं, एक है सहायक विधियों का उपयोग करना जैसा कि आपने सुझाव दिया, एक और शायद अधिक जटिल लेकिन सुरुचिपूर्ण एक फिल्टर का उपयोग है जो अनुरोधों और प्रतिक्रियाओं को संसाधित करता है और डेटाइम को परिवर्तित करता है। दूसरा तरीका यह है कि आप अपने दृश्य-मॉडल के प्रकार डेटटाइम के फ़ील्ड को एनोटेट करने के लिए एक कस्टम डिस्प्ले विशेषता विकसित करें।
मासिमो ज़र्बिनि

उन चीजों के प्रकार हैं जिन्हें मैं ढूंढ रहा था। यदि आप मेरे ओपी को देखते हैं, तो मैंने दृश्य / json परिणाम पर जाने से पहले कुछ प्रोसेसिंग करने के लिए AutoMapper का उपयोग करने का भी उल्लेख किया है, लेकिन कार्रवाई निष्पादित होने के बाद।
TheCloudlessSky

1

आउटपुट के लिए, इस तरह एक प्रदर्शन / संपादक टेम्पलेट बनाएं

@inherits System.Web.Mvc.WebViewPage<System.DateTime>
@Html.Label(Model.ToLocalTime().ToLongTimeString()))

यदि आप केवल उन मॉडल का उपयोग करना चाहते हैं, तो आप उन्हें अपने मॉडल के गुणों के आधार पर बांध सकते हैं।

कस्टम संपादक टेम्पलेट बनाने के बारे में अधिक जानकारी के लिए यहां और यहां देखें ।

वैकल्पिक रूप से, चूंकि आप चाहते हैं कि यह इनपुट और आउटपुट दोनों के लिए काम करे, मैं सुझाव दूंगा कि आप एक नियंत्रण का विस्तार करें या अपना स्वयं का निर्माण करें। इस तरह आप इनपुट और आउटपुट दोनों को इंटरसेप्ट कर सकते हैं और आवश्यकतानुसार टेक्स्ट / वैल्यू को बदल सकते हैं।

यदि आप उस रास्ते से नीचे जाना चाहते हैं तो यह लिंक आपको सही दिशा में ले जाएगा।

किसी भी तरह से, यदि आप एक सुरुचिपूर्ण समाधान चाहते हैं, तो यह थोड़ा काम होने वाला है। उज्जवल पक्ष पर, एक बार जब आप इसे कर लेते हैं तो एक बार भविष्य के उपयोग के लिए इसे अपने कोड लाइब्रेरी में रख सकते हैं!


मुझे लगता है कि कस्टम प्रदर्शन / संपादक टेम्पलेट और बाइंडर सबसे सुरुचिपूर्ण समाधान है, क्योंकि यह एक बार लागू होने पर "बस काम" करेगा। कोई डेवलपर कुछ विशेष पता करने के लिए काम कर रहा है ना सिर्फ का उपयोग दिनांक प्राप्त करने की आवश्यकता होगी DisplayForऔर EditorForऔर यह हर बार काम करेंगे। +1
केविन स्ट्रिकर

17
क्या यह एप्लिकेशन सर्वर के समय को प्रस्तुत नहीं करेगा और ब्राउज़र के समय को नहीं करेगा?
एलेक्स

0

यह शायद एक अखरोट को तोड़ने के लिए एक स्लेजहैमर है, लेकिन आप UI और व्यावसायिक परतों के बीच एक परत को इंजेक्ट कर सकते हैं जो पारदर्शी रूप से डेटाटाइम्स को लौटे ऑब्जेक्ट ग्राफ़ पर स्थानीय समय में और इनपुट डेटाइम मापदंडों पर UTC में कनवर्ट करता है।

मुझे लगता है कि यह PostSharp या नियंत्रण कंटेनर के कुछ व्युत्क्रम का उपयोग करके प्राप्त किया जा सकता है।

व्यक्तिगत रूप से, मैं यूआई में स्पष्ट रूप से अपने डेटासेट को परिवर्तित करने के साथ जाऊंगा ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.