Jak porównać tylko datę bez godziny w typach DateTime w Linq do SQL z Entity Framework?

303

Czy istnieje sposób na porównanie dwóch DateTimezmiennych, Linq2Sqlale z pominięciem części Czas.

Aplikacja przechowuje elementy w bazie danych i dodaje opublikowaną datę. Chcę zachować dokładny czas, ale nadal będę w stanie przyciągnąć samą datę.

Chcę porównać 12/3/89 12:43:34i 12/3/89 11:22:12nie brać pod uwagę faktycznej pory dnia, więc oba są uważane za takie same.

Wydaje mi się, że mogę ustawić wszystkie pory dnia, 00:00:00zanim zacznę porównywać, ale tak naprawdę chcę znać porę dnia, chcę tylko móc porównywać tylko według daty.

Znalazłem kod, który ma ten sam problem i osobno porównują rok, miesiąc i dzień. Czy jest na to lepszy sposób?

Sruly
źródło

Odpowiedzi:

534

spróbuj użyć Datewłaściwości na obiekcie DateTime...

if(dtOne.Date == dtTwo.Date)
    ....
Quintin Robinson
źródło
25
Jeśli skończysz tu kiedyś po początku 2017 r., Szukając sposobu na porównanie dat w środowisku Entity Framework, takim jak ja, zapoznałem się z odpowiedzią Alejandro poniżej i komentarzem wasatchWizard.
Mike Devenney,
8
Jeśli skończysz tutaj gdzieś po połowie 2018 r. I szukasz sposobu na przeczytanie kolejnego niezwykle pomocnego komentarza, takiego jak ten powyżej, nie masz szczęścia.
nardnob
4
Jeśli skończysz tu kiedyś na początku 2019 r. I szukasz komicznej ulgi, to ją znalazłeś.
Phil Ringsmuth,
1
To absolutnie NIE jest poprawna odpowiedź. OP specjalnie powiedział Linq na SQL i datetime.date NIE jest dozwolone w wyrażeniach linq.
Philip Vaughn
2
Jeśli skończysz tu kiedyś po 2020 r., Mam nadzieję, że dbasz o siebie i zostajesz w domu podczas kryzysów pandemicznych wirusa koronawirusa. Wróć tutaj w 2021 roku!
Pan Ott
61

Aby uzyskać prawdziwe porównanie, możesz użyć:

dateTime1.Date.CompareTo(dateTime2.Date);
Reed Copsey
źródło
18
Co dokładnie rozumiesz przez „prawdziwe porównanie”?
Randolpho
6
Randolpho: użycie == da ci równość, więc czy dwie daty są takie same czy różne. CompareTo ~ porówna ~ je, tj .: da ci sposób w jednym przejściu, aby stwierdzić, czy date1> date2, date1 <date2 lub date1 == date2.
Reed Copsey,
6
@ReedCopsey Nie możesz po prostu użyć (dateTime1.Date <dateTime1.Date)?
David
14
Ale kto chce -1, 0i 1, naprawdę? Są to po prostu magiczne liczby reprezentujące „mniej”, „równe” i „większe”. I będziesz musiał później „porównać” wynikową liczbę całkowitą z czymś, ponieważ istnieją trzy możliwe wartości. Muszę zgodzić się z @David że jest o wiele bardziej naturalny w użyciu dateTime1.Date < dateTime1.Date, i podobnie z <=, >i >=, w większości zastosowań.
Jeppe Stig Nielsen
8
@JeppeStigNielsen Jeśli używasz tego w czymkolwiek, co sortuje lub bierze kombinację, to chcesz tego - w przeciwnym razie zwykle potrzebujesz operatorów.
Reed Copsey
45

Tak to robię, aby pracować z 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));

Jeśli dtOne.Date == dtTwo.Datego użyjesz, nie będzie działać z LINQ (Błąd: element członkowski określonego typu „Data” nie jest obsługiwany w LINQ do encji)

Alejandro del Río
źródło
22
Działa to świetnie z LINQ to Entities. Jednak EntityFunctionszostał wycofany w .NET 4.5.2. Użyj tego zamiast: DbFunctions.TruncateTime. Wygląda na to, że jest to identyczna metoda, właśnie się poruszyłem.
wasatchwizard 12.04.16
25

Jeśli używasz Entity Framework <v6.0, użyj EntityFunctions.TruncateTime Jeśli używasz Entity Framework> = v6.0, użyjDbFunctions.TruncateTime

Użyj albo (w zależności od wersji EF) wokół dowolnej DateTimewłaściwości klasy, której chcesz użyć w zapytaniu Linq

Przykład

var list = db.Cars.Where(c=> DbFunctions.TruncateTime(c.CreatedDate) 
                                       >= DbFunctions.TruncateTime(DateTime.UtcNow));
Korayem
źródło
Przypomnienie: o ile jest to Linq to Entity.
ciekawyBoy
To powinna być poprawna odpowiedź (od 2019 r.). EntityFunctions jest przestarzałe i nie wolno używać datetime.date w wyrażeniu lambda (z jakiegokolwiek powodu - mam na myśli poważnie ... dlaczego tego nie naprawili ?!).
Philip Vaughn
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
źródło
9
DateTime? NextChoiceDate = new DateTime();
DateTIme? NextSwitchDate = new DateTime();
if(NextChoiceDate.Value.Date == NextSwitchDate.Value.Date)
{
Console.WriteLine("Equal");
}

Możesz użyć tego, jeśli używasz zerowych pól DateField.

Code Geek
źródło
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
   }
Mohan Sharma
źródło
2
DateTime econvertedDate = Convert.ToDateTime(end_date);
DateTime sconvertedDate = Convert.ToDateTime(start_date);

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

Wartość różnicy reprezentuje liczbę dni dla wieku. Jeśli wartość jest ujemna, data rozpoczęcia wypada po dacie zakończenia. To dobry czek.

dgsjr
źródło
1

Możesz użyć Equals lub CompareTo .

Równa się : zwraca wartość wskazującą, czy dwa wystąpienia DateTime mają tę samą wartość daty i godziny.

Porównaj, aby zwrócić wartość :

  1. Mniej niż zero : jeśli to wystąpienie jest wcześniejsze niż wartość.
  2. Zero : jeśli to wystąpienie jest takie samo jak wartość.
  3. Większa niż zero : jeśli to wystąpienie jest późniejsze niż wartość.

DateTime ma wartość null:

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

lub

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 nie ma wartości null:

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

lub

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;
}
Reza Jenabi
źródło
0

W klauzuli join lub where użyj Datewłaściwości kolumny. Za kulisami wykonuje to CONVERT(DATE, <expression>)operację. Powinno to umożliwić porównanie dat bez czasu.

Adam Robinson
źródło
0

Możesz spróbować

if(dtOne.Year == dtTwo.Year && dtOne.Month == dtTwo.Month && dtOne.Day == dtTwo.Day)
  ....
Cristian
źródło
-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))
        {
        }
Hetuk Upadhyay
źródło
5
-1: Dlaczego nie przeanalizować DateTime i użyć metody @Quintin Robinson? To jest kod, który spodziewałbym się zobaczyć na The Daily WTF.
William Hurst
Nie trzeba tworzyć tak wielu zmiennych, ponieważ wydłuża to czas odpowiedzi na tak łatwe zadanie.
Nayan Katkani,