C# 如何通过LINQ比较没有时间的DateTime?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9626348/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to compare DateTime without time via LINQ?
提问by Developer
I have
我有
var q = db.Games.Where(t => t.StartDate >= DateTime.Now).OrderBy(d => d.StartDate);
But it compares including time part of DateTime. I really don't need it.
但它比较包括时间部分DateTime。我真的不需要它。
How to do it without time?
没有时间怎么办?
Thank you!
谢谢!
采纳答案by Jon Skeet
Just use the Dateproperty:
只需使用该Date属性:
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.Todayonceso that the query is consistent - otherwise each time the query is executed, and even withinthe execution, Todaycould change, so you'd get inconsistent results. For example, suppose you had data of:
请注意,我已经明确评估DateTime.Today过一次,以便查询保持一致 - 否则每次执行查询时,甚至在执行期间,Today都可能发生变化,因此您会得到不一致的结果。例如,假设您有以下数据:
Entry 1: March 8th, 8am
Entry 2: March 10th, 10pm
Entry 3: March 8th, 5am
Entry 4: March 9th, 8pm
Surely either bothentries 1 and 3 should be in the results, or neitherof them should... but if you evaluate DateTime.Todayand it changesto March 9th after it's performed the first two checks, you could end up with entries 1, 2, 4.
当然无论是两个条目1和3应该是结果,或者没有人应该...但如果你评估DateTime.Today它改变它执行的第一个两次检查后,3月9日,你可以用条目1,2,4落得.
Of course, using DateTime.Todayassumes you're interested in the date in the localtime zone. That may not be appropriate, and you should make absolutelysure you know what you mean. You maywant to use DateTime.UtcNow.Dateinstead, for example. Unfortunately, DateTimeis a slippery beast...
当然,使用DateTime.Today假定您对本地时区中的日期感兴趣。这可能不适合,你应该绝对确保你知道你的意思。例如,您可能想改用它DateTime.UtcNow.Date。不幸的是,DateTime是一只滑溜的野兽......
EDIT: You may also want to get rid of the calls to DateTimestatic properties altogether - they make the code hard to unit test. In Noda Timewe 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.
编辑:您可能还想完全摆脱对DateTime静态属性的调用- 它们使代码难以进行单元测试。在Noda Time 中,我们有一个专门用于此目的的接口 ( IClock),我们希望适当地注入它。有一个用于生产的“系统时间”实现和一个用于测试的“存根”实现,或者您可以自己实现它。
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 allthe code.
当然,您可以在不使用 Noda Time 的情况下使用相同的想法。要对这段特定的代码进行单元测试,您可能希望传入日期,但您将从某处获取它- 注入时钟意味着您可以测试所有代码。
回答by Matt Burland
Try
尝试
var q = db.Games.Where(t => t.StartDate.Date >= DateTime.Now.Date).OrderBy(d => d.StartDate);
回答by Duane Theriot
The Date property is not supported by LINQ to Entities -- you'll get an error if you try to use it on a DateTime field in a LINQ to Entities query. You can, however, trim dates using the DbFunctions.TruncateTime method.
LINQ to Entities 不支持 Date 属性——如果您尝试在 LINQ to Entities 查询中的 DateTime 字段上使用它,则会收到错误消息。但是,您可以使用 DbFunctions.TruncateTime 方法修剪日期。
var today = DateTime.Today;
var q = db.Games.Where(t => DbFunctions.TruncateTime(t.StartDate) >= today);
回答by Caesar
I found that in my case this is the only way working: (in my application I want to remove old log entries)
我发现在我的情况下,这是唯一有效的方法:(在我的应用程序中,我想删除旧的日志条目)
var filterDate = dtRemoveLogs.SelectedDate.Value.Date;
var loadOp = context.Load<ApplicationLog>(context.GetApplicationLogsQuery()
.Where(l => l.DateTime.Year <= filterDate.Year
&& l.DateTime.Month <= filterDate.Month
&& l.DateTime.Day <= filterDate.Day));
I don't understand why the Jon's solution is not working ....
我不明白为什么 Jon 的解决方案不起作用......
回答by Ramanand Potdar
DateTime dt=DateTime.Now.date;
var q = db.Games.Where(
t =>EntityFunction.TruncateTime(t.StartDate.Date >=EntityFunction.TruncateTime(dt)).OrderBy(d => d.StartDate
);
回答by Cagdas
Try this code
试试这个代码
var today = DateTime.Today;
var q = db.Games.Where(t => DbFunctions.TruncateTime(t.StartDate) <= today);
回答by Joao Arruda
It happens that LINQ doesn't like properties such as DateTime.Date. It just can't convert to SQL queries. So I figured out a way of comparing dates using Jon's answer, but without that naughty DateTime.Date. Something like this:
碰巧 LINQ 不喜欢DateTime.Date. 它只是无法转换为 SQL 查询。所以我想出了一种使用 Jon 的答案来比较日期的方法,但没有那种顽皮的DateTime.Date. 像这样的东西:
var q = db.Games.Where(t => t.StartDate.CompareTo(DateTime.Today) >= 0).OrderBy(d => d.StartDate);
var q = db.Games.Where(t => t.StartDate.CompareTo(DateTime.Today) >= 0).OrderBy(d => d.StartDate);
This way, we're comparing a full database DateTime, with all that date and time stuff, like 2015-03-04 11:49:45.000 or something like this, with a DateTime that represents the actual first millisecond of that day, like 2015-03-04 00:00:00.0000.
这样,我们将完整的数据库 DateTime 与所有日期和时间内容(例如 2015-03-04 11:49:45.000 或类似内容)与表示当天实际第一毫秒的 DateTime 进行比较,例如2015-03-04 00:00:00.0000。
Any DateTime we compare to that DateTime.Todaywill return us safely if that date is later or the same. Unless you want to compare literally the same day, in which case I think you should go for Caesar's answer.
DateTime.Today如果该日期晚于或相同,我们与之比较的任何 DateTime都会安全地返回我们。除非您想在同一天进行字面上的比较,否则我认为您应该选择凯撒的答案。
The method DateTime.CompareTo()is just fancy Object-Oriented stuff. It returns -1 if the parameter is earlier than the DateTime you referenced, 0 if it is LITERALLY EQUAL (with all that timey stuff) and 1 if it is later.
该方法DateTime.CompareTo()只是花哨的面向对象的东西。如果参数早于您引用的 DateTime,则返回 -1,如果它是 LITERALLY EQUAL(带有所有这些时间的东西),则返回 0,如果晚则返回 1。
回答by Sushmit Saxena
I found this question while I was stuck with the same query. I finally found it without using DbFunctions. Try this:
当我遇到相同的查询时,我发现了这个问题。我终于在不使用 DbFunctions 的情况下找到了它。尝试这个:
var q = db.Games.Where(t => t.StartDate.Day == DateTime.Now.Day && t.StartDate.Month == DateTime.Now.Month && t.StartDate.Year == DateTime.Now.Year ).OrderBy(d => d.StartDate);
var q = db.Games.Where(t => t.StartDate.Day == DateTime.Now.Day && t.StartDate.Month == DateTime.Now.Month && t.StartDate.Year == DateTime.Now.Year ).OrderBy(d => d.StartDate);
This way by bifurcating the date parts we effectively compare only the dates, thus leaving out the time.
通过分叉日期部分,我们可以有效地仅比较日期,从而忽略时间。
Hope that helps. Pardon me for the formatting in the answer, this is my first answer.
希望有帮助。请原谅我在答案中的格式,这是我的第一个答案。
回答by Tomá? Florek
The .Dateanswer is misleading since you get the error mentioned before. Another way to compare, other than mentioned DbFunctions.TruncateTime, may also be:
该.Date答案是误导,因为你得到之前提到的错误。除了提到的DbFunctions.TruncateTime,另一种比较方式也可能是:
DateTime today = DateTime.Now.date;
var q = db.Games.Where(t => SqlFunctions.DateDiff("dayofyear", today, t.StartDate) <= 0
&& SqlFunctions.DateDiff("year", today, t.StartDate) <= 0)
It looks better(more readable) in the generated SQL query. But I admit it looks worse in the C# code XD. I was testing something and it seemed like TruncateTimewas not working for me unfortunately the fault was between keyboard and chair, but in the meantime I found this alternative.
在生成的 SQL 查询中看起来更好(更具可读性)。但我承认它在 C# 代码中看起来更糟 XD。我正在测试一些东西,但TruncateTime不幸的是,它似乎对我不起作用,问题出在键盘和椅子之间,但与此同时,我找到了这个替代方案。

