Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# DateTime.Equals() not working properly

Tags:

c#

I am trying to compare two DateTime variables which are having the same values in it.

But when I use Equals method it returns false which indicates "Not Equal".

My code is :

DateTime date = DateTime.Parse("2/27/2010 1:06:49 PM");
foreach (KeyValuePair<DateTime, List<string>> k in Sample)
{
   if (date.Equals(k.Key))
   {
      Console.WriteLine("Yes");
   }
   else {
      Console.WriteLine("No");
   }
}

The dictionary Sample contains the following keys :

  • 5/8/2018 11:18:00 AM
  • 5/8/2018 11:17:46 AM
  • 2/27/2010 1:06:49 PM
  • 5/8/2018 11:18:08 AM

The third key value is same as the comparing value.

And for all the key I get no as output.

Can anyone explain why it is happening like this ?

like image 821
Anitha Sundaramoorthy Avatar asked May 09 '18 10:05

Anitha Sundaramoorthy


3 Answers

As i've commented, DateTime contains not only seconds but also milliseconds and ticks. Maybe they are not equal. But you culd use following extension method to compare only up to the seconds:

public static class DateTimeExtensions
{
    public static bool EqualsUpToSeconds(this DateTime dt1, DateTime dt2)
    {
        return dt1.Year == dt2.Year && dt1.Month == dt2.Month && dt1.Day == dt2.Day &&
               dt1.Hour == dt2.Hour && dt1.Minute == dt2.Minute && dt1.Second == dt2.Second;
    }   
}

Sample:

DateTime date1 = DateTime.Parse("2/27/2010 1:06:49 PM", CultureInfo.InvariantCulture);
DateTime date2 = date1.AddMilliseconds(100);
bool equals = date1.EqualsUpToSeconds(date2); // true
like image 190
Tim Schmelter Avatar answered Sep 20 '22 12:09

Tim Schmelter


DateTime.Equals (static or instance) will compare the Ticks property. While it may appear to you that both dates are same (due to the way it is displayed for human readability) they may or may not be same. Tick is rather high precision measurement (1 tick = 100 nanoseconds).

It the values in the KeyValuePair are coming from some system generated date time, it will have different value than you creating your own date time object with static values.

For instance, take a look at these two dates,

DateTime one = new DateTime(636614784317968133);
DateTime two = new DateTime(636614784317968134);

They have 100 nanosecond difference. In the add watch they both look same but Equals method will return false for both.

enter image description here

If you want to remove the values after say milliseconds, you can use the following code:

one = one.AddTicks(-one.Ticks % TimeSpan.TicksPerMillisecond);
two = two.AddTicks(-two.Ticks % TimeSpan.TicksPerMillisecond);

Once this is done, you can see that Ticks for both the date objects are same and can be compared now.

like image 33
danish Avatar answered Sep 19 '22 12:09

danish


Out of curiosity, just tested this and it works fine

public static void Main()
{
    Dictionary<DateTime, List<string>> Sample = new Dictionary<DateTime, List<string>>();
    Sample.Add( DateTime.Parse("5/8/2018 11:18:00 AM"), new List<string>());
    Sample.Add( DateTime.Parse("5/8/2018 11:17:46 AM"), new List<string>());
    Sample.Add( DateTime.Parse("2/27/2010 1:06:49 PM"), new List<string>());
    Sample.Add( DateTime.Parse("5/8/2018 11:18:08 AM"), new List<string>());    
    DateTime date = DateTime.Parse("2/27/2010 1:06:49 PM");
  foreach (KeyValuePair<DateTime, List<string>> k in Sample)
  {
    if (date.Equals(k.Key))
    {
       Console.WriteLine("Yes");
    }
    else {
       Console.WriteLine("No");
    }
   }
 }      

Output:

No

No

Yes

No

dotNetFiddle

EDIT:

As suggested by @Fabjan

Change one of your lines of code to: Sample.Add( DateTime.Parse("2/27/2010 1:06:49.123 PM"), new List<string>()); and try again

In such case of DateTime.Ticks:

if (date.Ticks/10000000 == k.Key.Ticks/10000000)
   {
      Console.WriteLine("Yes");
   }
   else {

      Console.WriteLine("No");
   }

dotNetFiddle

like image 37
DirtyBit Avatar answered Sep 19 '22 12:09

DirtyBit