programing tip

LINQ를 통해 시간없이 DateTime을 비교하는 방법은 무엇입니까?

itbloger 2021. 1. 9. 09:34
반응형

LINQ를 통해 시간없이 DateTime을 비교하는 방법은 무엇입니까?


나는 가지고있다

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

그러나 시간 부분을 포함하여 비교합니다 DateTime. 정말 필요하지 않습니다.

시간없이하는 방법?

감사합니다!


다음 Date속성을 사용하십시오 .

var today = DateTime.Today;

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

쿼리가 일관되도록 DateTime.Today 한 번 명시 적으로 평가 했습니다. 그렇지 않으면 쿼리가 실행될 때마다, 심지어 실행 내에서도Today 변경 될 수 있으므로 일관성없는 결과를 얻을 수 있습니다. 예를 들어 다음과 같은 데이터가 있다고 가정합니다.

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

확실히 항목 1과 3이 모두 결과에 있어야 하거나 둘 다 결과에 포함 되지 않아야합니다 ...하지만 평가 DateTime.Today하고 처음 두 번의 확인을 수행 한 후 3 월 9 일로 변경 되면 항목 1, 2, 4로 끝날 수 있습니다. .

물론를 사용 DateTime.Today하면 현지 시간대 의 날짜에 관심이 있다고 가정합니다 . 그것은 적절하지 않을 수 있으며, 당신이 의미하는 바를 절대적으로 알고 있어야합니다. 예를 들어 대신 사용할 있습니다DateTime.UtcNow.Date . 불행히도 DateTime미끄러운 짐승입니다 ...

편집 : DateTime정적 속성 에 대한 호출을 모두 제거하고 싶을 수도 있습니다 -코드를 단위 테스트하기 어렵게 만듭니다. 에서 노다 시간 우리는이 목적을 (위해 특별히 인터페이스를 가지고 IClock우리가 적절하게 주입하는 기대). 프로덕션을위한 "시스템 시간"구현과 테스트를위한 "스텁"구현이 있거나 직접 구현할 수 있습니다.

물론 Noda Time을 사용하지 않고도 동일한 아이디어를 사용할 수 있습니다. 이 특정 코드 조각을 단위 테스트하려면 날짜를 전달하고 싶을 수 있지만 어딘가 에서 날짜를 가져 오게됩니다. 시계를 삽입하면 모든 코드를 테스트 할 수 있습니다 .


Date 속성은 LINQ to Entities에서 지원되지 않습니다. LINQ to Entities 쿼리의 DateTime 필드에서 사용하려고하면 오류가 발생합니다. 그러나 DbFunctions.TruncateTime 메서드를 사용하여 날짜를자를 수 있습니다.

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

이 코드 시도

var today = DateTime.Today;
var q = db.Games.Where(t => DbFunctions.TruncateTime(t.StartDate) <= today);

내 경우에는 이것이 유일한 방법이라는 것을 알았습니다. (내 응용 프로그램에서 오래된 로그 항목을 제거하고 싶습니다)

 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));

Jon의 솔루션이 작동하지 않는 이유를 이해할 수 없습니다.


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:

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.

Any DateTime we compare to that DateTime.Today will 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.

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.


The .Date answer is misleading since you get the error mentioned before. Another way to compare, other than mentioned DbFunctions.TruncateTime, may also be:

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 TruncateTime was not working for me unfortunately the fault was between keyboard and chair, but in the meantime I found this alternative.


Try

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

DateTime dt=DateTime.Now.date;

var q = db.Games.Where(
    t =>EntityFunction.TruncateTime(t.StartDate.Date >=EntityFunction.TruncateTime(dt)).OrderBy(d => d.StartDate
);

I found this question while I was stuck with the same query. I finally found it without using DbFunctions. Try this:

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.

ReferenceURL : https://stackoverflow.com/questions/9626348/how-to-compare-datetime-without-time-via-linq

반응형