How to compare DateTime without time via LINQ?

前端 未结 9 620
夕颜
夕颜 2020-12-08 18:03

I have

var q = db.Games.Where(t => t.StartDate >= DateTime.Now).OrderBy(d => d.StartDate);

But it compares including time part of

9条回答
  •  抹茶落季
    2020-12-08 18:51

    Just use the Date property:

    var today = DateTime.Today;
    
    var q = db.Games.Where(t => t.StartDate.Date >= today)
                    .OrderBy(t => t.StartDate);
    

    Note that I've explicitly evaluated DateTime.Today once so that the query is consistent - otherwise each time the query is executed, and even within the execution, Today could change, so you'd get inconsistent results. For example, suppose you had data of:

    Entry 1: March 8th, 8am
    Entry 2: March 10th, 10pm
    Entry 3: March 8th, 5am
    Entry 4: March 9th, 8pm
    

    Surely either both entries 1 and 3 should be in the results, or neither of them should... but if you evaluate DateTime.Today and it changes to March 9th after it's performed the first two checks, you could end up with entries 1, 2, 4.

    Of course, using DateTime.Today assumes you're interested in the date in the local time zone. That may not be appropriate, and you should make absolutely sure you know what you mean. You may want to use DateTime.UtcNow.Date instead, for example. Unfortunately, DateTime is a slippery beast...

    EDIT: You may also want to get rid of the calls to DateTime static properties altogether - they make the code hard to unit test. In Noda Time we have an interface specifically for this purpose (IClock) which we'd expect to be injected appropriately. There's a "system time" implementation for production and a "stub" implementation for testing, or you can implement it yourself.

    You can use the same idea without using Noda Time, of course. To unit test this particular piece of code you may want to pass the date in, but you'll be getting it from somewhere - and injecting a clock means you can test all the code.

提交回复
热议问题