Как сравнить только дату без времени в типах DateTime в Linq и SQL с Entity Framework?


304

Есть ли способ сравнить две DateTimeпеременные, Linq2Sqlно игнорировать часть времени.

Приложение сохраняет элементы в БД и добавляет опубликованную дату. Я хочу сохранить точное время, но все же смогу потянуть на саму дату.

Я хочу сравнить 12/3/89 12:43:34и 12/3/89 11:22:12не учитывать фактическое время суток, поэтому оба они считаются одинаковыми.

Я полагаю, что я могу установить все время суток 00:00:00перед сравнением, но я действительно хочу знать время суток, я просто хочу иметь возможность сравнивать только по дате.

Я нашел код, который имеет ту же проблему, и они сравнивают год, месяц и день отдельно. Есть лучший способ сделать это?

Ответы:


535

попробуйте использовать Dateсвойство DateTimeобъекта ...

if(dtOne.Date == dtTwo.Date)
    ....

25
Если вы окажетесь здесь где-то после начала 2017 года в поисках способа сравнения дат в среде Entity Framework, как я сделал, посмотрите ответ Алехандро ниже и комментарий wasatchWizard.
Майк Девенни

8
Если вы окажетесь здесь где-то после середины 2018 года в поисках способа прочитать еще один чрезвычайно полезный комментарий, такой как приведенный выше, вам не повезло.
nardnob

4
Если вы окажетесь здесь где-то после начала 2019 года в поисках комической помощи, вы ее нашли.
Фил Рингсмут

1
Это абсолютно НЕ правильный ответ. В OP специально сказано, что Linq to SQL и datetime.date не допускаются в выражениях linq.
Филипп Вон

2
Если вы окажетесь здесь где-то после начала 2020 года, я надеюсь, что вы заботитесь о себе и остаетесь дома во время пандемического кризиса коронавируса. Вернитесь сюда в 2021 году!
Мистер Отт

61

Для истинного сравнения вы можете использовать:

dateTime1.Date.CompareTo(dateTime2.Date);

18
Что именно вы подразумеваете под «истинным сравнением»?
Рандольфо

6
Рандольфо: Использование == даст вам равенство, поэтому, будут ли две даты одинаковыми или разными. CompareTo будет ~ сравнивать ~ их, то есть: даст вам способ за один проход определить, если date1> date2, date1 <date2 или date1 == date2.
Рид Копси

6
@ReedCopsey Разве вы не можете просто использовать (dateTime1.Date <dateTime1.Date)?
Дэвид

14
Но кто хочет -1, 0и 1, действительно? Это просто магические числа, представляющие «меньше», «равно» и «больше». И потом вам придется «сравнивать» полученное целое с чем-то, потому что есть три возможных значения. Я должен согласиться с @David, что это гораздо более естественно использовать dateTime1.Date < dateTime1.Date, и аналогично <=, >и >=в большинстве приложений.
Джеппе Стиг Нильсен

8
@JeppeStigNielsen Если вы используете это во всем, что сортирует или берет в комапрайоне, тогда вы хотите этого - в противном случае вы просто хотите операторов.
Рид Копси

45

Вот как я это делаю, чтобы работать с LINQ.

DateTime date_time_to_compare = DateTime.Now;
//Compare only date parts
context.YourObject.FirstOrDefault(r =>
                EntityFunctions.TruncateTime(r.date) == EntityFunctions.TruncateTime(date_to_compare));

Если вы используете dtOne.Date == dtTwo.Dateего только, он не будет работать с LINQ (Ошибка: указанный член типа «Дата» не поддерживается в LINQ to Entities)


22
Это прекрасно работает с LINQ to Entities. Тем EntityFunctionsне менее, устарела в .NET 4.5.2. Используйте вместо этого: DbFunctions.TruncateTime. Похоже, это идентичный метод, только что перенесенный.
wasatchwizard

25

Если вы используете Entity Framework <v6.0, то используйте EntityFunctions.TruncateTime Если вы используете Entity Framework> = v6.0, тогда используйтеDbFunctions.TruncateTime

Используйте любой (в зависимости от вашей версии EF) вокруг любого DateTimeсвойства класса, которое вы хотите использовать в вашем запросе Linq

пример

var list = db.Cars.Where(c=> DbFunctions.TruncateTime(c.CreatedDate) 
                                       >= DbFunctions.TruncateTime(DateTime.UtcNow));

Просто напоминание: пока это Linq to Entity.
curiousBoy

Это должен быть правильный ответ (по состоянию на 2019 год). EntityFunctions устарела, и вы не можете использовать datetime.date в лямбда-выражении (по любой причине - я имею в виду серьезно ... почему они не исправили это ?!).
Филипп Вон

12
DateTime dt1 = DateTime.Now.Date;
DateTime dt2 = Convert.ToDateTime(TextBox4.Text.Trim()).Date;
if (dt1 >= dt2)
{
    MessageBox.Show("Valid Date");
}
else
{
    MessageBox.Show("Invalid Date... Please Give Correct Date....");
}

9
DateTime? NextChoiceDate = new DateTime();
DateTIme? NextSwitchDate = new DateTime();
if(NextChoiceDate.Value.Date == NextSwitchDate.Value.Date)
{
Console.WriteLine("Equal");
}

Вы можете использовать это, если вы используете пустые поля даты.


3
DateTime dt1=DateTime.ParseExact(date1,"dd-MM-yyyy",null);
DateTime dt2=DateTime.ParseExact(date2,"dd-MM-yyyy",null);

int cmp=dt1.CompareTo(dt2);

   if(cmp>0) {
       // date1 is greater means date1 is comes after date2
   } else if(cmp<0) {
       // date2 is greater means date1 is comes after date1
   } else {
       // date1 is same as date2
   }

2
DateTime econvertedDate = Convert.ToDateTime(end_date);
DateTime sconvertedDate = Convert.ToDateTime(start_date);

TimeSpan age = econvertedDate.Subtract(sconvertedDate);
Int32 diff = Convert.ToInt32(age.TotalDays);

Значение diff представляет количество дней для возраста. Если значение отрицательное, дата начала падает после даты окончания. Это хорошая проверка.


1

Вы можете использовать Equals или CompareTo .

Равно : Возвращает значение, указывающее, имеют ли два экземпляра DateTime одинаковые значения даты и времени.

CompareTo Возвращаемое значение :

  1. Меньше нуля : если этот экземпляр раньше, чем значение.
  2. Ноль : если этот экземпляр совпадает со значением.
  3. Больше нуля : если этот экземпляр позже значения.

DateTime обнуляется:

DateTime? first = new DateTime(1992,02,02,20,50,1);
DateTime? second = new DateTime(1992, 02, 02, 20, 50, 2);

if (first.Value.Date.Equals(second.Value.Date))
{
    Console.WriteLine("Equal");
}

или

DateTime? first = new DateTime(1992,02,02,20,50,1);
DateTime? second = new DateTime(1992, 02, 02, 20, 50, 2);


var compare = first.Value.Date.CompareTo(second.Value.Date);

switch (compare)
{
    case 1:
        Console.WriteLine("this instance is later than value.");
        break;
    case 0:
        Console.WriteLine("this instance is the same as value.");
        break;
    default:
        Console.WriteLine("this instance is earlier than value.");
        break;
}

DateTime не обнуляется:

DateTime first = new DateTime(1992,02,02,20,50,1);
DateTime second = new DateTime(1992, 02, 02, 20, 50, 2);

if (first.Date.Equals(second.Date))
{
    Console.WriteLine("Equal");
}

или

DateTime first = new DateTime(1992,02,02,20,50,1);
DateTime second = new DateTime(1992, 02, 02, 20, 50, 2);


var compare = first.Date.CompareTo(second.Date);

switch (compare)
{
    case 1:
        Console.WriteLine("this instance is later than value.");
        break;
    case 0:
        Console.WriteLine("this instance is the same as value.");
        break;
    default:
        Console.WriteLine("this instance is earlier than value.");
        break;
}

0

В предложении join или where используйте Dateсвойство столбца. За кулисами это выполняет CONVERT(DATE, <expression>)операцию. Это должно позволить вам сравнивать даты без времени.


0

Можешь попробовать

if(dtOne.Year == dtTwo.Year && dtOne.Month == dtTwo.Month && dtOne.Day == dtTwo.Day)
  ....

-16
        int o1 = date1.IndexOf("-");
        int o2 = date1.IndexOf("-",o1 + 1);
        string str11 = date1.Substring(0,o1);
        string str12 = date1.Substring(o1 + 1, o2 - o1 - 1);
        string str13 = date1.Substring(o2 + 1);

        int o21 = date2.IndexOf("-");
        int o22 = date2.IndexOf("-", o1 + 1);
        string str21 = date2.Substring(0, o1);
        string str22 = date2.Substring(o1 + 1, o2 - o1 - 1);
        string str23 = date2.Substring(o2 + 1);

        if (Convert.ToInt32(str11) > Convert.ToInt32(str21))
        {
        }
        else if (Convert.ToInt32(str12) > Convert.ToInt32(str22))
        {
        }
        else if (Convert.ToInt32(str12) == Convert.ToInt32(str22) && Convert.ToInt32(str13) > Convert.ToInt32(str23))
        {
        }

5
-1: Почему бы просто не разобрать DateTime и использовать метод @Quintin Robinson? Это код, который я ожидаю увидеть на The Daily WTF.
Уильям Херст

Не нужно создавать столько переменных, поскольку это увеличивает время отклика для такой простой задачи.
Наян Каткани
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.