Home > database >  How to compare two dates in C# on just year, month, day, hour, minute, second?
How to compare two dates in C# on just year, month, day, hour, minute, second?

Time:03-01

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;
    }

CodePudding user response:

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
}

CodePudding user response:

When newing a date explicitly pass all properties down to your desired resolution. The other properties default to zero. A direct compare date1 == date2 compares all properties as expressed in Ticks (a nod to Jon Skeet), but zeroed out milliseconds, for example, is effectively not compared.

For application consistency have the getters and setters zero out "unused" precision properties. Don't require nor depend on client code to call tortured combinations of Date properties to get the form it is supposed to be in the first place.

CodePudding user response:

This might be slightly quicker:

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

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

CodePudding user response:

As sr28 just pointed out, you can add ? to make DateTime nullable (this started in C# 6).

To simplify your method, try converting the dates to strings with formatting, then do the comparison. This works:

    private static bool DatesAreEqual(DateTime? date1, DateTime? date2)
    {
        string? d1 = date1?.ToString("MM/dd/yyyy HH:mm:ss");
        string? d2 = date2?.ToString("MM/dd/yyyy HH:mm:ss");

        return d1 == d2;
    }
  • Related