Ignore milliseconds when comparing two datetimes

前端 未结 14 2157
一个人的身影
一个人的身影 2020-12-08 12:47

This is probably a dumb question, but I cannot seem to figure it out. I am comparing the LastWriteTime of two files, however it is always failing because the file I download

相关标签:
14条回答
  • 2020-12-08 13:09

    cast sortable strings and compare. simple and run well.

        return string.Compare(dtOrig.ToString("s"), dtNew.ToString("s"), 
    StringComparison.Ordinal) == 0;
    
    0 讨论(0)
  • 2020-12-08 13:12

    Ether set the milliseconds in your other datetime to zero, or subtract one date from the other and just check the TotalMinutes property of the resulting time span.

    0 讨论(0)
  • 2020-12-08 13:14

    Here is the simplest way of doing this. You can control precision as you want.

    bool AreEqual(DateTime a, DateTime b, TimeSpan precision)
    {
        return Math.Abs((a - b).TotalMilliseconds) < precision.TotalMilliseconds;
    }
    

    and usage is pretty self-explanatory

    var _ = AreEqual(a, b, precision: TimeSpan.FromSeconds(1));
    
    0 讨论(0)
  • 2020-12-08 13:20

    This is overkill for a single Truncate, but if you have several and of various types you could do this using the generalized Extension Method below:

    DateTime dtSecs = DateTime.Now.TruncateTo(Extensions.DateTruncate.Second);
    DateTime dtHrs  = DateTime.Now.TruncateTo(Extensions.DateTruncate.Hour);
    

    More general Use Extension method:

        public static DateTime TruncateTo(this DateTime dt, DateTruncate TruncateTo)
        {
            if (TruncateTo == DateTruncate.Year)
                return new DateTime(dt.Year, 0, 0);
            else if (TruncateTo == DateTruncate.Month)
                return new DateTime(dt.Year, dt.Month, 0);
            else if (TruncateTo == DateTruncate.Day)
                return new DateTime(dt.Year, dt.Month, dt.Day);
            else if (TruncateTo == DateTruncate.Hour)
                return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, 0, 0);
            else if (TruncateTo == DateTruncate.Minute)
                return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0);
            else 
                return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
    
        }
        public enum DateTruncate
        {
            Year,
            Month,
            Day,
            Hour,
            Minute,
            Second
        }
    
    0 讨论(0)
  • 2020-12-08 13:24

    Care should be taken, if dt has non-zero microseconds (fractions of millis). Setting only milliseconds to zero is not enough.
    To set millis and below to zero (and get a succesfull comparison), the code would be:

    dt = dt.AddTicks(-dt.Ticks % TimeSpan.TicksPerSecond); // TimeSpan.TicksPerSecond=10000000
    
    0 讨论(0)
  • 2020-12-08 13:24

    instead of trimming unrelevant DateTime parts via creating new DateTimes, compare only relevant parts:

    public static class Extensions
    {
        public static bool CompareWith(this DateTime dt1, DateTime dt2)
        {
            return
                dt1.Second == dt2.Second && // 1 of 60 match chance
                dt1.Minute == dt2.Minute && // 1 of 60 chance
                dt1.Day == dt2.Day &&       // 1 of 28-31 chance
                dt1.Hour == dt2.Hour &&     // 1 of 24 chance
                dt1.Month == dt2.Month &&   // 1 of 12 chance
                dt1.Year == dt2.Year;       // depends on dataset
        }
    }
    

    I took answer by Dean Chalk as base for performance comparison, and results are:

    • CompareWith is a bit faster than TrimMilliseconds in case of equal dates

    • CompareWith is a faster than dates are not equal

    my perf test (run in Console project)

    static void Main(string[] args)
    {
        var dtOrig = new DateTime(2018, 03, 1, 10, 10, 10);
        var dtNew = dtOrig.AddMilliseconds(100);
    
        //// perf run for not-equal dates comparison
        //dtNew = dtNew.AddDays(1);
        //dtNew = dtNew.AddMinutes(1);
    
        int N = 1000000;
    
        bool isEqual = false;
    
        var sw = Stopwatch.StartNew();
        for (int i = 0; i < N; i++)
        {
            // TrimMilliseconds comes from 
            // https://stackoverflow.com/a/7029046/1506454 
            // answer by Dean Chalk
            isEqual = dtOrig.TrimMilliseconds() == dtNew.TrimMilliseconds();
        }
        var ms = sw.ElapsedMilliseconds;
        Console.WriteLine("DateTime trim: " + ms + " ms");
    
        sw = Stopwatch.StartNew();
        for (int i = 0; i < N; i++)
        {
            isEqual = dtOrig.CompareWith(dtNew);
        }
        ms = sw.ElapsedMilliseconds;
        Console.WriteLine("DateTime partial compare: " + ms + " ms");
    
        Console.ReadKey();
    }
    
    0 讨论(0)
提交回复
热议问题