2008-12-19 6 views
25

डिफ़ॉल्ट रूप से C# 100T टिक पर डेटटाइम ऑब्जेक्ट की तुलना करता है। हालांकि, मेरा डेटाबेस डेटटाइम मान को निकटतम मिलीसेकंड में देता है। निर्दिष्ट सहिष्णुता का उपयोग करके सी # में दो डेटटाइम ऑब्जेक्ट्स की तुलना करने का सबसे अच्छा तरीका क्या है?सी # में निर्दिष्ट सहिष्णुता का उपयोग करके डेटटाइम ऑब्जेक्ट्स की तुलना कैसे करते हैं?

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

मेरे लिए काम करने वाला समाधान नीचे दिए गए लोगों का संयोजन है।

(dateTime1 - dateTime2).Duration() < TimeSpan.FromMilliseconds(1) 

यह अंतर सच होता है यदि अंतर एक मिलीसेकंड से कम है। दो तिथियों के बीच अंतर का पूर्ण मूल्य प्राप्त करने के लिए कॉल अवधि() महत्वपूर्ण है।

उत्तर

23

मैं आमतौर पर इस तरह कुछ करने के लिए TimeSpan.FromXXX तरीकों का उपयोग:

if((myDate - myOtherDate) > TimeSpan.FromSeconds(10)) 
{ 
    //Do something here 
} 
+3

एक थोड़ा अलग तरह से: अगर ((DATE1 - date2) .TotalSeconds> 10) – Thomas

+4

यह '(dateTime1 - dateTime2) होना चाहिए। अवधि() Marius

5

आप दिनांक वस्तु से मिलीसेकेंड घटक को दूर करने की जरूरत है। एक ही रास्ता है:

DateTime d = DateTime.Now; 
    d.Subtract(new TimeSpan(0, 0, 0, 0, d.Millisecond)); 

तुम भी दो datetimes

d.Subtract (DateTime.Now) घटाना कर सकते हैं;

यह एक टाइमपेन ऑब्जेक्ट लौटाएगा जिसका उपयोग आप अंतर देखने के लिए दिन, घंटे, मिनट और सेकंड घटकों की तुलना करने के लिए कर सकते हैं।

2
 if (Math.Abs(dt1.Subtract(dt2).TotalSeconds) < 1.0) 
+0

+1 घड़ी के लिए पूर्ण खाते का उपयोग कर उत्तर के लिए +1 –

10

कैसे दिनांक समय एक धाराप्रवाह इंटरफ़ेस का एक सा बनाने के लिए (उन सभी क्रोध सही कर रहे हैं?)

public static class DateTimeTolerance 
{ 
    private static TimeSpan _defaultTolerance = TimeSpan.FromSeconds(10); 
    public static void SetDefault(TimeSpan tolerance) 
    { 
     _defaultTolerance = tolerance; 
    } 

    public static DateTimeWithin Within(this DateTime dateTime, TimeSpan tolerance) 
    { 
     return new DateTimeWithin(dateTime, tolerance); 
    } 

    public static DateTimeWithin Within(this DateTime dateTime) 
    { 
     return new DateTimeWithin(dateTime, _defaultTolerance); 
    } 
} 

यह राज्य की दुकान और एक परिभाषित करने के लिए एक वर्ग पर निर्भर करता है के लिए एक विस्तार विधि के बारे में ! == के लिए जोड़े को ऑपरेटर भार के और =:

public class DateTimeWithin 
{ 
    public DateTimeWithin(DateTime dateTime, TimeSpan tolerance) 
    { 
     DateTime = dateTime; 
     Tolerance = tolerance; 
    } 

    public TimeSpan Tolerance { get; private set; } 
    public DateTime DateTime { get; private set; } 

    public static bool operator ==(DateTime lhs, DateTimeWithin rhs) 
    { 
     return (lhs - rhs.DateTime).Duration() <= rhs.Tolerance; 
    } 

    public static bool operator !=(DateTime lhs, DateTimeWithin rhs) 
    { 
     return (lhs - rhs.DateTime).Duration() > rhs.Tolerance; 
    } 

    public static bool operator ==(DateTimeWithin lhs, DateTime rhs) 
    { 
     return rhs == lhs; 
    } 

    public static bool operator !=(DateTimeWithin lhs, DateTime rhs) 
    { 
     return rhs != lhs; 
    } 
} 

फिर अपने कोड में आप कर सकते हैं:

DateTime d1 = DateTime.Now; 
DateTime d2 = d1 + TimeSpan.FromSeconds(20); 

if(d1 == d2.Within(TimeSpan.FromMinutes(1))) { 
    // TRUE! Do whatever 
} 

विस्तार वर्ग भी एक डिफ़ॉल्ट स्थिर सहिष्णुता घरों, ताकि आप अपनी पूरी परियोजना के लिए एक सहिष्णुता की स्थापना की और कोई पैरामीटर के साथ विधि के भीतर का उपयोग कर सकते हैं:

DateTimeTolerance.SetDefault(TimeSpan.FromMinutes(1)); 

if(d1 == d2.Within()) { // Uses default tolerance 
    // TRUE! Do whatever 
} 

मैं कुछ इकाई परीक्षण है, लेकिन है कि हो जाएगा यहां पेस्ट करने के लिए थोड़ा अधिक कोड।

+0

यह एक स्वीकार्य उपयोग की तरह दिखता है विस्तार मेथ का ओडीएस, हुरेय! – EndangeredMassa

+0

विधि स्थिर – darasd

+0

होना चाहिए और इसे एक अलग नाम की आवश्यकता होगी, क्योंकि संकलक सोचता है कि आप स्थिर दिनांक समय को कॉल करने का प्रयास कर रहे हैं। विधि विधि, और फिर शिकायत करती है कि इसे एक उदाहरण विधि के रूप में नहीं कहा जा सकता है। – darasd

1

डिफ़ॉल्ट रूप से सी # मिलीसेकंड के लिए डेटटाइम ऑब्जेक्ट्स की तुलना करता है।

वास्तव में संकल्प 100ns टिक के लिए है।

यदि आप डेटाबेस से दो डेटटाइम मानों की तुलना कर रहे हैं, जिसमें 1s रिज़ॉल्यूशन है, कोई समस्या नहीं है।

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

मैं आपको सेकंड की एक अभिन्न संख्या में गोल या छंटनी का सुझाव देता हूं, फिर डेटाबेस से मूल्य के साथ तुलना करता हूं। Here's a post that describes how to round a DateTime (यह उदाहरण मिनटों के दौर में है, लेकिन प्रिंसिपल वही है)।

0

मुझे मूल प्रश्नकर्ता के समान समस्या थी लेकिन चीजों को और अधिक रोचक बनाने के लिए मैं Nullable<DateTime> को सहेज रहा था और पुनर्प्राप्त कर रहा था।

मैं joshperry's answer पसंद है और मेरी प्रयोजनों के लिए काम करने के लिए इसे बढ़ाया:

public static class DateTimeTolerance 
{ 
    private static TimeSpan _defaultTolerance = TimeSpan.FromMilliseconds(10); // 10ms default resolution 
    public static void SetDefault(TimeSpan tolerance) 
    { 
     _defaultTolerance = tolerance; 
    } 

    public static DateTimeWithin Within(this DateTime dateTime, TimeSpan tolerance) 
    { 
     return new DateTimeWithin(dateTime, tolerance); 
    } 

    public static DateTimeWithin Within(this DateTime dateTime) 
    { 
     return new DateTimeWithin(dateTime, _defaultTolerance); 
    } 

    // Additional overload that can deal with Nullable dates 
    // (treats null as DateTime.MinValue) 
    public static DateTimeWithin Within(this DateTime? dateTime) 
    { 
     return dateTime.GetValueOrDefault().Within(); 
    } 

    public static DateTimeWithin Within(this DateTime? dateTime, TimeSpan tolerance) 
    { 
     return dateTime.GetValueOrDefault().Within(tolerance); 
    } 
} 

public class DateTimeWithin 
{ 
    public DateTimeWithin(DateTime dateTime, TimeSpan tolerance) 
    { 
     DateTime = dateTime; 
     Tolerance = tolerance; 
    } 

    public TimeSpan Tolerance { get; private set; } 
    public DateTime DateTime { get; private set; } 

    public static bool operator ==(DateTime lhs, DateTimeWithin rhs) 
    { 
     return (lhs - rhs.DateTime).Duration() <= rhs.Tolerance; 
    } 

    public static bool operator !=(DateTime lhs, DateTimeWithin rhs) 
    { 
     return (lhs - rhs.DateTime).Duration() > rhs.Tolerance; 
    } 

    public static bool operator ==(DateTimeWithin lhs, DateTime rhs) 
    { 
     return rhs == lhs; 
    } 

    public static bool operator !=(DateTimeWithin lhs, DateTime rhs) 
    { 
     return rhs != lhs; 
    } 

    // Overloads that can deal with Nullable dates 
    public static bool operator !=(DateTimeWithin lhs, DateTime? rhs) 
    { 
     return rhs != lhs; 
    } 

    public static bool operator ==(DateTime? lhs, DateTimeWithin rhs) 
    { 
     if (!lhs.HasValue && rhs.DateTime == default(DateTime)) return true; 
     if (!lhs.HasValue) return false; 
     return (lhs.Value - rhs.DateTime).Duration() <= rhs.Tolerance; 
    } 

    public static bool operator !=(DateTime? lhs, DateTimeWithin rhs) 
    { 
     if (!lhs.HasValue && rhs.DateTime == default(DateTime)) return true; 
     if (!lhs.HasValue) return false; 
     return (lhs.Value - rhs.DateTime).Duration() > rhs.Tolerance; 
    } 

    public static bool operator ==(DateTimeWithin lhs, DateTime? rhs) 
    { 
     return rhs == lhs; 
    } 
} 

और सब कुछ को सत्यापित करने के लिए एक त्वरित इकाई परीक्षण सही ढंग से काम कर रहा है:

[TestMethod] 
public void DateTimeExtensions_Within_WorksWithNullable() 
{ 
    var now = DateTime.Now; 
    var dtNow1 = new DateTime?(now); 
    var dtNow2 = new DateTime?(now.AddMilliseconds(1)); 
    var dtNowish = new DateTime?(now.AddMilliseconds(25)); 
    DateTime? dtNull = null; 

    Assert.IsTrue(now == dtNow1.Within()); // Compare DateTime to DateTime? 
    Assert.IsTrue(dtNow1 == dtNow2.Within()); // Compare two DateTime? using a different syntax 
    Assert.IsTrue(dtNow1 == dtNow2.Within()); // Same value should be true 
    Assert.IsFalse(dtNow1 == dtNowish.Within()); // Outside of the default 10ms tolerance, should not be equal 
    Assert.IsTrue(dtNow1 == dtNowish.Within(TimeSpan.FromMilliseconds(50))); // ... but we can override this 
    Assert.IsFalse(dtNow1 == dtNull.Within()); // Comparing a value to null should be false 
    Assert.IsTrue(dtNull == dtNull.Within()); // ... but two nulls should be true 
} 
+0

बस अगर कोई आसानी से 'Nullable' तिथियों के साथ ऐसा करने का तरीका खोज रहा था। जोशरी का समाधान पहले से ही 'डेटटाइम' ऑब्जेक्ट्स के लिए पूरी तरह से काम करता है। –

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