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

304

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

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

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

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

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

Sruly
источник

Ответы:

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));
Korayem
источник
Просто напоминание: пока это 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....");
}
Devarajan.T
источник
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 представляет количество дней для возраста. Если значение отрицательное, дата начала падает после даты окончания. Это хорошая проверка.

dgsjr
источник
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)
  ....
Cristian
источник
-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.
Уильям Херст
Не нужно создавать столько переменных, поскольку это увеличивает время отклика для такой простой задачи.
Наян Каткани