Reputation: 4480
I am trying to get all dates in a Linq query between StartDate
and EndDate
. Both my StartDate
and EndDate
are the right dates, but my results are inconsistent. Everything else in the query works, just not the comparison of the dates. What am I doing wrong?
where (startDate == null || DateTime.Compare((DateTime)startDate,
o.FirstAirDate) < 0) && (endDate == null|| DateTime.Compare(
o.FirstAirDate, (DateTime)endDate) > 0)
Dates are showing up outside of the range and when I move the dates closer together nothing appears. For example If I search from December 21-26 I get results between those two dates but also a date for the 27th shows up. If I search from December 23-26 nothing shows up, even though I saw dates in this range show up when I searched from December 21-26
Upvotes: 4
Views: 2909
Reputation: 61952
Your last inequality:
DateTime.Compare(o.FirstAirDate, (DateTime)endDate) > 0
is the wrong way. Compared to the first inequality, which looks correct, you can either swap the two arguments to Compare
, or change < 0
into > 0
. But you do both, which cancels each other.
It is easier to simply use comparison between DateTime
values directly, for example:
where (startDate == null || (DateTime)startDate < o.FirstAirDate)
&& (endDate == null || o.FirstAirDate < (DateTime)endDate)
May I ask, is the declared C# type (compile-time type) of startDate
, and endDate
, object
or DateTime?
(i.e. Nullable<DateTime>
). If they are Nullable<>
, if you dare, you can use negation and lifted operators and turn this into:
where !(o.FirstAirDate <= startDate) && !(endDate <= o.FirstAirDate)
Note that the null
checks are included here. If an operand to <=
is null
, the result is false
, and because of the negation it will work in the null
cases because of that.
Upvotes: 2
Reputation: 1469
If you're trying to get all instances where FirstAirDate
is between startDate
and endDate
(and either startDate
or endDate
can be null) and they are all DateTime
objects you might want to try something like:
var objects = MyObjectsList.Where(o =>
(!startDate.HasValue || o.FirstAirDate >= startDate.Value)
&& (!endDate.HasValue || o.FirstAirDate <= endDate.Value))
You can compare dates with simple comparison operators, just have to use the .Value
for the nullable DateTime properties when doing the comparison - in which case it's best to null check first.
Upvotes: 7