Anitha Sundaramoorthy
Anitha Sundaramoorthy

Reputation: 203

c# DateTime.Equals() not working properly

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 :

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 ?

Upvotes: 12

Views: 14007

Answers (6)

Pranay Rana
Pranay Rana

Reputation: 176896

Equals for structure (DateTime) i.e. value type check values are equal or not , but for date time DateTime.Compare is already there , you can use it

if (DateTime.Compare(date.Equals,k.Key) == 0)
   {
      Console.WriteLine("Yes");
   }
   else {
      Console.WriteLine("No");
   }

Upvotes: 0

Tim Schmelter
Tim Schmelter

Reputation: 460138

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

Upvotes: 18

DirtyBit
DirtyBit

Reputation: 16772

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

Upvotes: 1

Amit
Amit

Reputation: 1857

here in your question, you have shown that even if your dates in sample are same as the date you are matching but still they are not Equal as per Equal()

you should debug and trying comparing Ticks of both dates.

Try below code

DateTime date = DateTime.Parse("2/27/2010 1:06:49 PM");
foreach (KeyValuePair<DateTime, List<string>> k in Sample)
{
   //if both Ticks are same, you should expect dates to be equal
   Console.WriteLine(date.Ticks + "-" + k.Key.Ticks);
   if (date.Equals(k.Key))
   {
      Console.WriteLine("Yes");
   }
   else {
      Console.WriteLine("No");
   }
}

This way you will log Ticks while matching dates.

your actual way to compare two dates here should be

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

Comment here if it doesn't solve your concern.

Upvotes: 0

danish
danish

Reputation: 5610

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.

Upvotes: 7

Could this be a cultural problem? Try specific the right CultureInfo for comparing.

static void Main(string[] args)
{
    var culture = new CultureInfo("en-US", false);
    Dictionary<DateTime, List<string>> Sample = new Dictionary<DateTime, List<string>>();

    Sample.Add( DateTime.Parse("5/8/2018 11:18:00 AM", culture), new List<string>());
    Sample.Add( DateTime.Parse("5/8/2018 11:17:46 AM", culture), new List<string>());
    Sample.Add( DateTime.Parse("2/27/2010 1:06:49 PM", culture), new List<string>());
    Sample.Add( DateTime.Parse("5/8/2018 11:18:08 AM", culture), new List<string>());

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

Upvotes: 0

Related Questions