skip to Main Content

I have two dates and I only want to make sure they match on these 6 fields:
year, month, day, hour, minute and second.

I have noticed that if I perform a simple equality == comparison if(d1 == d2) that match on these fields, I still get ‘false’. I’m assuming this has to do with other fields under the hood that relate to ticks, milliseconds etc. How can I ignore everything and just make sure they match on the 6 fields above?

I have created the prototype function below but to me this feels amateurish and inefficient for production-level code. Furthermore, date1 has to be a nullable datetime.

Does anyone else have any better suggestions?

    private static bool DatesAreEqual(DateTime date1, DateTime date2)
    {

        var d1 = new DateTime(date1.Year, date1.Month, date1.Day,
                    date1.Hour, date1.Minute, date1.Second);

        var d2 = new DateTime(date2.Year, date2.Month, date2.Day,
                    date2.Hour, date2.Minute, date2.Second);

        return d1 == d2;
    }

3

Answers


  1. This might be slightly quicker:

    var sameDateTime = ((date1 - date2).Milliseconds < 1000);
    

    https://stackoverflow.com/a/58173628/759558

    Login or Signup to reply.
  2. You can remove fractional part of the dates (please, note, that fractional part is longer then just milliseconds):

    DateTime date = DateTime.Now;
    
    // 28 02 2022 22:19:56.3704625 
    Console.WriteLine($"{date:dd MM yyyy HH:mm:ss.fffffff}"); 
    
    date -= TimeSpan.FromTicks(date.Ticks % 10_000_000);
    
    // 28 02 2022 22:19:56.0000000
    Console.WriteLine($"{date:dd MM yyyy HH:mm:ss.fffffff}");
    

    Code:

    DateTime date1 = ...
    DateTime date2 = ...
    
    ...
    
    if (date1 - TimeSpan.FromTicks(date1.Ticks % 10_000_000) == 
        date2 - TimeSpan.FromTicks(date2.Ticks % 10_000_000)) {
      //TODO: Relevant code here
    }
    

    You can implement extension class to keep main code shorter and more readable:

    public partial static class DateTimeExtensions {
      public static DateTime TrimToSeconds(this DateTime value) => 
        value - TimeSpan.FromTicks(value.Ticks % 10_000_000)
    }
    

    And then

    DateTime date1 = ...
    DateTime date2 = ...
    
    ...
    
    if (date1.TrimToSeconds() == date2.TrimToSeconds()) {
      //TODO: Relevant code here
    }
    
    Login or Signup to reply.
  3. If you check on the TimeSpam, we have the TimeSpan.TicksPerSecond that is the minimum that you want to be the same (the seconds), so we reset that part to zero and we make the compare using ticks (that is the faster) as:

    pubic static bool DatesAreEqual(DateTime d1, DateTime d2)
    {
        return (d1.Ticks - (d1.Ticks % TimeSpan.TicksPerSecond)) == (d2.Ticks - (d2.Ticks % TimeSpan.TicksPerSecond));
    }
    

    With this way you just make some number compare and its the faster way.

    More Than That

    Base on the above code I also make two more functions with selected Precision and Equal, or Compare functions

    public enum DateTimeComparePrecision : long
    {
        Millisecond  = TimeSpan.TicksPerMillisecond,
        Second = TimeSpan.TicksPerSecond,
        Minute = TimeSpan.TicksPerMinute,
        Hour = TimeSpan.TicksPerHour,
        Day = TimeSpan.TicksPerDay,
    }
    
    
    public static bool DatesAreEqual(DateTime d1, DateTime d2, DateTimeComparePrecision Precision)
    {
        return (d1.Ticks - (d1.Ticks % (long)Precision)) == (d2.Ticks - (d2.Ticks % (long)Precision));
    }        
    
    
    public static int DatesCompare(DateTime d1, DateTime d2, DateTimeComparePrecision Precision)
    {
        long Day1 = (d1.Ticks - (d1.Ticks % (long)Precision));
        long Day2 = (d2.Ticks - (d2.Ticks % (long)Precision));
    
        if (Day2 > Day1) 
            return 1;            
    
        if (Day2 < Day1)            
            return -1;            
    
        return 0;
    }
    

    Simple Visual Test

    DateTime NowIs = DateTime.UtcNow;
    Console.WriteLine($"{NowIs:dd MM yyyy HH:mm:ss.fffffff}");
    
    DateTime d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerMillisecond)));
    Console.WriteLine($"{d1:dd MM yyyy HH:mm:ss.fffffff}");
    
    d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerSecond)));
    Console.WriteLine($"{d1:dd MM yyyy HH:mm:ss.fffffff}");
    
    d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerMinute)));
    Console.WriteLine($"{d1:dd MM yyyy HH:mm:ss.fffffff}");
    
    d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerHour)));
    Console.WriteLine($"{d1:dd MM yyyy HH:mm:ss.fffffff}");
    
    d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerDay)));
    Console.WriteLine($"{d1:dd MM yyyy HH:mm:ss.fffffff}");
    

    output

    01 03 2022 12:51:26.7237323
    01 03 2022 12:51:26.7230000
    01 03 2022 12:51:26.0000000
    01 03 2022 12:51:00.0000000
    01 03 2022 12:00:00.0000000
    01 03 2022 00:00:00.0000000
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search