Harsh Vyas
Harsh Vyas

Reputation: 326

How to compare datetime (only dd/mm/yyyy hh:mm:ss tt not whole fff section in datetime) in linq C#?

I want to compare datetime which comes from kendo filter in (DD/MM/YYYY hh:mm:ss tt) format and wanted to compare with my database using linq expression.

IEnumerable<ValidateTaskSummaryDetails> source;
source = source.Where(o => o.TaskStartDate.Value == dtStartDate);

Here dtStartDate comes from Kendo, the date i have got from kendo is '10/11/2016 15:34:45' and the date in my database is '10/11/2016:15:34:45' but then also i have got error like 'Enumeration yielded no results' I think it must take the whole lot of a date with .fff section also but I don't get that from kendo (i.e. I don't want to get it).

The problem here is When i tried to compare both dates which are identical, But in comparison system compared with 'DD/MM/YYYY hh:mm:ss.fff tt' now the problem is with '.fff' due to this dates are not compared and hence yielded no result.

Do any have any solution?.

Upvotes: 1

Views: 1732

Answers (2)

Mikhail Tulubaev
Mikhail Tulubaev

Reputation: 4281

When you perform equality comparison, you are right that compares the complete representation of DateTime, to be honest it compares the equality of Ticks property of each DateTime object.

public static bool operator ==(DateTime d1, DateTime d2) {
    return d1.InternalTicks == d2.InternalTicks;
}

(from reference source)

If you need the equality only of Date (year, month, day) and Time (hours, minute, seconds) you need to implement something like the following:

IEnumerable<ValidateTaskSummaryDetails> source;
source = source.Where(o => o.TaskStartDate.Value.Year == dtStartDate.Year && 
                        o.TaskStartDate.Value.Month == dtStartDate.Month && 
                        o.TaskStartDate.Value.Day == dtStartDate.Day &&
                        o.TaskStartDate.Value.Hour == dtStartDate.Hour &&
                        o.TaskStartDate.Value.Minute == dtStartDate.Minute &&
                        o.TaskStartDate.Value.Second == dtStartDate.Second);

Or comparing equality of string representation in required format.

var format = "dd/MM/yyyy HH:mm:ss";
source = source.Where(o => o.TaskStartDate.Value.ToString(format) == dtStartDate.ToString(format));

The first approach will be faster, because it requires to compare numeric fields instead of string. It should be noted (as it noted from comments) that converting DateTime to string and comparing it's string representation is a kind of bad idea and it is good example of bad smell code. It will give required results but you should avoid it - string comparison is always worse than numeric comparison.

It is recommended to avoid equality comparison of DateTime objects, because there are too much variables which affecting the result (Hour, Minute, Second, Day, Month, Year, Millisecond) and perform only inequality comparisons (<, <=, >, >=). Or compare only Date component of DateTime as following:

source = source.Where(o => o.TaskStartDate.Value.Date == dtStartDate.Date);

It is frequently enough for most common usages of this.

Upvotes: 1

Soner G&#246;n&#252;l
Soner G&#246;n&#252;l

Reputation: 98858

both DateTime are same if you remove the millisecond portion.

If so, you can truncate the milliseconds part of your TaskStartDate.Value like;

source = source.Where(o => 
                      o.TaskStartDate.Value.AddTicks(-(o.TaskStartDate.Value.Ticks % TimeSpan.TicksPerSecond)) 
                      == dtStartDate);

Upvotes: 2

Related Questions