C # DateTime.Now सटीक


97

मैं सिर्फ कुछ यूनिट परीक्षणों को करते हुए DateTime.UtcNow के साथ कुछ अप्रत्याशित व्यवहार में भाग गया। ऐसा प्रतीत होता है कि जब आप DateTime.Now/UtcNow को तीव्र गति से कहते हैं, तो यह आपको अधिक सटीक मिलीसेकेंड वेतन वृद्धि पर कब्जा करने के बजाय समय की अपेक्षा अधिक लंबे अंतराल के लिए समान मूल्य वापस देने के लिए लगता है।

मुझे पता है कि एक स्टॉपवॉच वर्ग है जो सटीक समय माप करने के लिए बेहतर अनुकूल होगा, लेकिन मैं उत्सुक था कि क्या कोई डेटाइम में इस व्यवहार की व्याख्या कर सकता है? क्या DateTime.Now (उदाहरण के लिए, 50 मिसे के भीतर सटीक?) के लिए एक आधिकारिक सटीकता का दस्तावेज है? क्यों DateTime.Now सबसे सीपीयू घड़ियों क्या संभाल सकता है की तुलना में कम सटीक बनाया जाएगा? हो सकता है कि यह सिर्फ सबसे कम आम भाजक सीपीयू के लिए डिज़ाइन किया गया हो

public static void Main(string[] args)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    for (int i=0; i<1000; i++)
    {
        var now = DateTime.Now;
        Console.WriteLine(string.Format(
            "Ticks: {0}\tMilliseconds: {1}", now.Ticks, now.Millisecond));
    }

    stopwatch.Stop();
    Console.WriteLine("Stopwatch.ElapsedMilliseconds: {0}",
        stopwatch.ElapsedMilliseconds);

    Console.ReadLine();
}

वह अंतराल क्या है जिसके दौरान आपको समान मान वापस मिलता है?
ChrisF


जब मैंने उपरोक्त कोड चलाया, तो मुझे टिक्स और मिलीसेकंड के लिए केवल 3 अद्वितीय मान मिले, और अंतिम स्टॉप वॉच का समय 147 एमएस था, इसलिए ऐसा प्रतीत होता है कि मेरी मशीन पर यह केवल 50ms के आसपास ही सटीक है ...
एंडी व्हाइट

मुझे कहना चाहिए, लूप ने कई बार भाग लिया, लेकिन मैंने केवल 3 अलग-अलग मूल्यों को देखा ...
एंडी व्हाइट

यहाँ आने वाले किसी भी व्यक्ति के लिए, यहाँ TL है; DR // QueryPerformanceCounter फ़ंक्शन का उपयोग करें "प्रदर्शन काउंटर के वर्तमान मूल्य को पुनः प्राप्त करता है, जो एक उच्च रिज़ॉल्यूशन (<1us) टाइम स्टैम्प है जिसे समय-अंतराल माप के लिए उपयोग किया जा सकता है।" (प्रबंधित कोड के लिए, System.Diagnostics.Stopwatch वर्ग QPC इसका सटीक समय के आधार के रूप में उपयोग करता है।) Msdn.microsoft.com/en-us/library/windows/desktop/...
AnotherUser

जवाबों:


180

क्यों DateTime.Now सबसे सीपीयू घड़ियों क्या संभाल सकता है की तुलना में कम सटीक बनाया जाएगा?

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

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

याद रखें, DateTime का उद्देश्य दिनांक और समय का प्रतिनिधित्व करना है । उच्च-सटीक समय, दिनांक समय के सभी उद्देश्य पर नहीं है; जैसा कि आप ध्यान दें, यही स्टॉपवॉच का उद्देश्य है। दिनांक समय का उद्देश्य उपयोगकर्ता को वर्तमान समय प्रदर्शित करने, अगले मंगलवार तक दिनों की संख्या की गणना करने, और इसी तरह उद्देश्यों के लिए एक तिथि और समय का प्रतिनिधित्व करना है।

संक्षेप में, "क्या समय है?" और "कितना समय लगा?" पूरी तरह से अलग सवाल हैं; एक प्रश्न का उत्तर देने के लिए डिज़ाइन किए गए टूल का उपयोग न करें।

प्रश्न के लिए धन्यवाद; यह एक अच्छा ब्लॉग लेख बना देगा! :-)


2
@ एरिक लिपर्ट: रेमंड चेन के पास "सटीकता" और "सटीकता" के बीच अंतर के बहुत ही विषय पर एक पुराना लेकिन गुडी है
जेसन

3
ठीक है, सटीकता बनाम सटीकता के बारे में अच्छी बात है। मुझे लगता है कि मैं अभी भी वास्तव में यह कथन नहीं खरीदता कि डेटटाइम सटीक नहीं है क्योंकि "यह होना जरूरी नहीं है।" यदि मेरे पास एक लेन-देन प्रणाली है, और मैं प्रत्येक रिकॉर्ड के लिए एक डेटाइम को चिह्नित करना चाहता हूं, तो मेरे लिए डेटाइम क्लास का उपयोग करना सहज लगता है, लेकिन ऐसा लगता है कि .NET में अधिक सटीक / सटीक समय घटक हैं, इसलिए डेटटाइम क्यों होगा कम सक्षम बनाया। मुझे लगता है कि मुझे कुछ और पढ़ना होगा ...
एंडी व्हाइट

11
ठीक है @Andy, मान लीजिए कि आपके पास ऐसी व्यवस्था है। एक मशीन पर आप 1 जनवरी, 12: 34: 30.23498273 पर होने वाले लेनदेन को चिह्नित करते हैं। आपके क्लस्टर में एक और मशीन पर आप 1 जनवरी, 12: 34: 30.23498456 पर होने वाले लेनदेन को चिह्नित करते हैं। पहले कौन सा लेनदेन हुआ? जब तक आप यह नहीं जानते हैं कि दो मशीनों की घड़ियां एक दूसरे के एक माइक्रोसेकंड के भीतर सिंक्रनाइज़ हैं, आपको पता नहीं है कि पहले कौन हुआ था। अतिरिक्त परिशुद्धता कचरा भ्रामक है । यदि मेरे पास अपना रास्ता होता, तो सभी DateTimes निकटतम दूसरे के पास होते, क्योंकि वे VBScript में थे।
एरिक लिपर्ट

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

3
मान लें कि मैं एक गतिविधि लॉग बना रहा हूं जिसके लिए (1) यह जानना आवश्यक है कि कैलेंडर स्पेस (कुछ सेकंड के भीतर) के संदर्भ में कुछ हुआ है (2) बहुत सटीक रूप से घटनाओं (50 या तो मिलीसेकंड के भीतर) के बीच अंतर जानना। ऐसा लगता है कि इसके लिए सबसे सुरक्षित शर्त डेटटाइम का उपयोग करना होगा। पहले कार्रवाई के टाइमस्टैम्प के लिए, फिर प्रारंभिक डेटाइम से ऑफ़सेट निर्धारित करने के लिए बाद की कार्रवाई के लिए स्टॉपवॉच का उपयोग करें। क्या यह दृष्टिकोण आपको सलाह देगा, एरिक?
देवदूत

18

डेटटाइम की सटीक उस सिस्टम के लिए कुछ हद तक विशिष्ट है जिस पर इसे चलाया जा रहा है। सटीक एक संदर्भ स्विच की गति से संबंधित है, जो लगभग 15 या 16 एमएस हो जाता है। (मेरे सिस्टम पर, यह वास्तव में मेरे परीक्षण से लगभग 14 एमएस है, लेकिन मैंने कुछ लैपटॉप देखे हैं जहां यह 35-40 एमएस सटीकता के करीब है।)

पीटर ब्रोमबर्ग ने C # में उच्च परिशुद्धता कोड टाइमिंग पर एक लेख लिखा , जो इस पर चर्चा करता है।


2
4 Win7 मशीनें जो मेरे पास वर्षों से हैं, सभी में लगभग 1ms सटीकता है। अब () नींद (1) अब (हमेशा) जब मैं परीक्षण कर रहा था, तो डेटाइम में ~ 1ms परिवर्तन हुआ।
बेंगी

मैं ~ 1ms सटीकता भी देख रहा हूं।
तिमो

12

मुझे एक सटीक डेटाटाइम पसंद है। अब :), इसलिए मैंने इसे पकाया:

public class PreciseDatetime
{
    // using DateTime.Now resulted in many many log events with the same timestamp.
    // use static variables in case there are many instances of this class in use in the same program
    // (that way they will all be in sync)
    private static readonly Stopwatch myStopwatch = new Stopwatch();
    private static System.DateTime myStopwatchStartTime;

    static PreciseDatetime()
    {
        Reset();

        try
        {
            // In case the system clock gets updated
            SystemEvents.TimeChanged += SystemEvents_TimeChanged;
        }
        catch (Exception)
        {                
        }
    }

    static void SystemEvents_TimeChanged(object sender, EventArgs e)
    {
        Reset();
    }

    // SystemEvents.TimeChanged can be slow to fire (3 secs), so allow forcing of reset
    static public void Reset()
    {
        myStopwatchStartTime = System.DateTime.Now;
        myStopwatch.Restart();
    }

    public System.DateTime Now { get { return myStopwatchStartTime.Add(myStopwatch.Elapsed); } }
}

2
मुझे यह समाधान पसंद है, लेकिन मुझे यकीन नहीं था, इसलिए मैंने अपना सवाल पूछा ( stackoverflow.com/q/18257987/270344 )। Servy की टिप्पणी / उत्तर के अनुसार, आपको कभी भी स्टॉपवॉच को रीसेट नहीं करना चाहिए।
रोबसिक्लोस

1
हो सकता है कि आपके संदर्भ में नहीं, लेकिन रीसेट करना मेरे संदर्भ में समझ में आता है - मैं सिर्फ यह सुनिश्चित करता हूं कि वास्तव में शुरू होने से पहले ही इसे पूरा कर लिया जाए।
जिम्मी

आपको सदस्यता की आवश्यकता नहीं है और आपको स्टॉपवॉच को रीसेट करने की आवश्यकता नहीं है। इस कोड को चलाना हर ~ 10ms आवश्यक नहीं है और CPU का उपभोग करता है। और यह कोड थ्रेड-सेफ बिल्कुल भी नहीं है। बस myStopwatchStartTime = DateTime.UtcNow को इनिशियलाइज़ करें; एक बार, स्थिर निर्माण में।
वेगनहंटर

1
@VeganHunter मुझे यकीन नहीं है कि अगर मैं आपकी टिप्पणी को सही समझ रहा हूं, लेकिन आपको लगता है कि TimeChanged को हर called किलोमीटर कहा जाता है? यह नहीं है
जिमी

@ जिमी, तुम सही हो। मेरा बुरा, मैंने कोड को गलत समझा। SystemEvents.TimeChanged ईवेंट केवल तभी कहा जाता है जब उपयोगकर्ता सिस्टम समय बदलता है। यह एक दुर्लभ घटना है।
VeganHunter

6

से MSDN आपको लगता है कि मिल जाएगा DateTime.Nowएक है लगभग सभी NT ऑपरेटिंग सिस्टम पर 10 मिलीसेकंड का संकल्प।

वास्तविक परिशुद्धता हार्डवेयर पर निर्भर है। बेहतर परिशुद्धता का उपयोग करके प्राप्त किया जा सकता है QueryPerformanceCounter


5

इसके लायक क्या है, वास्तव में .NET स्रोत की जाँच करने से कम, एरिक लिपर्ट ने इस SO प्रश्न पर एक टिप्पणी प्रदान करते हुए कहा कि DateTime केवल 30 एमएस लगभग अनुमानित है। उनके शब्दों में, नैनोसेकंड सटीक नहीं होने का तर्क यह है कि इसे "होने की आवश्यकता नहीं है"।


4
और यह बदतर हो सकता है। VBScript नाओ () फ़ंक्शन के परिणाम को निकटतम दूसरे पर लौटाता है, इस तथ्य को हटाता है कि लौटाए गए मूल्य में माइक्रोसेकंड के सटीक होने के लिए पर्याप्त उपलब्ध परिशुद्धता है। सी # में, संरचना को डेटाइम कहा जाता है; यह विशिष्ट वास्तविक दुनिया के गैर-वैज्ञानिक डोमेन के लिए एक तारीख और समय का प्रतिनिधित्व करने का इरादा है, जैसे कि आपका जीवन बीमा कब समाप्त होता है या आपके अंतिम रिबूट के बाद से कब तक। यह उच्च-परिशुद्धता उप-सेकंड टाइमिंग के लिए अभिप्रेत नहीं है।
एरिक लिपर्ट

3

MSDN प्रलेखन से :

इस संपत्ति का संकल्प सिस्टम टाइमर पर निर्भर करता है।

वे यह भी दावा करते हैं कि विंडोज़ एनटी 3.5 और बाद में 10 एमएस पर अनुमानित संकल्प :)


1

इस संपत्ति का संकल्प सिस्टम टाइमर पर निर्भर करता है, जो अंतर्निहित ऑपरेटिंग सिस्टम पर निर्भर करता है। यह 0.5 और 15 मिलीसेकंड के बीच रहता है।

परिणामस्वरूप, थोड़े समय के अंतराल में नाओ प्रॉपर्टी को बार-बार कॉल करना, जैसे कि लूप में, समान मान वापस कर सकता है।

MSDN लिंक

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