Comment comparer uniquement Date sans heure dans les types DateTime de Linq à SQL avec Entity Framework?

304

Existe-t-il un moyen de comparer deux DateTimevariables Linq2Sqlmais de ne pas tenir compte de la partie Time.

L'application stocke des éléments dans la base de données et ajoute une date de publication. Je veux garder l'heure exacte mais toujours pouvoir tirer par la date elle-même.

Je veux comparer 12/3/89 12:43:34et 12/3/89 11:22:12et ne pas tenir compte de l'heure réelle de la journée, donc les deux sont considérés comme identiques.

Je suppose que je peux régler toutes les heures de la journée 00:00:00avant de comparer, mais je veux vraiment savoir l'heure de la journée que je veux aussi pouvoir comparer uniquement par date.

J'ai trouvé un code qui a le même problème et ils comparent l'année, le mois et le jour séparément. Y a-t-il une meilleure manière de faire cela?

Vraiment
la source

Réponses:

535

essayez d'utiliser la Datepropriété sur l' DateTimeobjet ...

if(dtOne.Date == dtTwo.Date)
    ....
Quintin Robinson
la source
25
Si vous vous retrouvez ici quelque temps après le début de 2017 à la recherche d'un moyen de comparer les dates dans un environnement Entity Framework comme j'ai vérifié la réponse ci-dessous d'Alejandro et le commentaire de wasatchWizard.
Mike Devenney
8
Si vous vous retrouvez ici quelque temps après la mi-2018 à la recherche d'un moyen de lire un autre commentaire extrêmement utile comme celui ci-dessus, vous n'avez pas de chance.
nardnob
4
Si vous vous retrouvez ici quelque temps après le début de 2019 à la recherche d'un soulagement comique, vous l'avez trouvé.
Phil Ringsmuth
1
Ce n'est absolument PAS la bonne réponse. L'OP a spécifiquement déclaré Linq à SQL et datetime.date n'est PAS autorisé dans les expressions linq.
Philip Vaughn
2
Si vous vous retrouvez ici quelque temps après le début de 2020, j'espère que vous prenez soin de vous et que vous restez à la maison pendant les crises de pandémie de coronavirus. Revenez ici en 2021!
M. Ott
61

Pour une vraie comparaison, vous pouvez utiliser:

dateTime1.Date.CompareTo(dateTime2.Date);
Reed Copsey
la source
18
Qu'entendez-vous exactement par «vraie comparaison»?
Randolpho
6
Randolpho: L'utilisation de == vous donnera l'égalité, donc si les deux dates sont identiques ou différentes. CompareTo va ~ les comparer ~, c'est-à-dire: vous donner un moyen en un seul passage de dire si date1> date2, date1 <date2 ou date1 == date2.
Reed Copsey
6
@ReedCopsey Ne pouvez-vous pas simplement utiliser (dateTime1.Date <dateTime1.Date)?
David
14
Mais qui veut -1, 0et 1vraiment? Ce ne sont que des nombres magiques représentant "moins", "égal" et "plus". Et vous devrez ensuite "comparer" l'entier résultant à quelque chose car il y a trois valeurs possibles. Je suis d' accord avec ce qu'il est @ David beaucoup plus naturel d'utiliser dateTime1.Date < dateTime1.Date, de même avec <=, >et >=, dans la plupart des applications.
Jeppe Stig Nielsen
8
@JeppeStigNielsen Si vous utilisez ceci dans tout ce qui trie ou prend une comparaison, alors vous le voulez - sinon, vous voulez généralement juste les opérateurs.
Reed Copsey
45

Voici comment je fais cela pour travailler avec 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));

Si vous ne l'utilisez dtOne.Date == dtTwo.Dateque ne fonctionnera pas avec LINQ (Erreur: le membre de type spécifié 'Date' n'est pas pris en charge dans LINQ to Entities)

Alejandro del Río
la source
22
Cela fonctionne très bien avec LINQ to Entities. Cependant, EntityFunctionsa été déconseillé dans .NET 4.5.2. Utilisez ceci: DbFunctions.TruncateTime. Il semble que ce soit la même méthode, juste déplacé ..
wasatchwizard
25

Si vous utilisez Entity Framework <v6.0, puis utilisez EntityFunctions.TruncateTime Si vous utilisez Entity Framework> = v6.0, puis utilisezDbFunctions.TruncateTime

Utilisez soit (en fonction de votre version EF) autour de toute DateTimepropriété de classe que vous souhaitez utiliser dans votre requête Linq

Exemple

var list = db.Cars.Where(c=> DbFunctions.TruncateTime(c.CreatedDate) 
                                       >= DbFunctions.TruncateTime(DateTime.UtcNow));
Korayem
la source
Juste un rappel ici: tant qu'il s'agit de Linq to Entity.
curiousBoy
Cela devrait être la bonne réponse (à partir de 2019). EntityFunctions est déprécié et vous n'êtes pas autorisé à utiliser datetime.date dans une expression lambda (pour une raison quelconque - je veux dire sérieusement ... pourquoi n'ont-ils pas corrigé cela?!).
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
la source
9
DateTime? NextChoiceDate = new DateTime();
DateTIme? NextSwitchDate = new DateTime();
if(NextChoiceDate.Value.Date == NextSwitchDate.Value.Date)
{
Console.WriteLine("Equal");
}

Vous pouvez l'utiliser si vous utilisez DateFields nullable.

Code Geek
la source
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
la source
2
DateTime econvertedDate = Convert.ToDateTime(end_date);
DateTime sconvertedDate = Convert.ToDateTime(start_date);

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

La valeur diff représente le nombre de jours pour l'âge. Si la valeur est négative, la date de début tombe après la date de fin. C'est un bon chèque.

dgsjr
la source
1

Vous pouvez utiliser Equals ou CompareTo .

Equals : renvoie une valeur indiquant si deux instances DateTime ont la même valeur de date et d'heure.

CompareTo Return Value :

  1. Inférieur à zéro : si cette instance est antérieure à la valeur.
  2. Zéro : si cette instance est identique à la valeur.
  3. Supérieur à zéro : si cette instance est postérieure à la valeur.

DateTime est nullable:

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

ou

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 n'est pas annulable:

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

ou

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
la source
0

Dans votre clause join ou where, utilisez la Datepropriété de la colonne. Dans les coulisses, cela exécute une CONVERT(DATE, <expression>)opération. Cela devrait vous permettre de comparer les dates sans l'heure.

Adam Robinson
la source
0

Tu peux essayer

if(dtOne.Year == dtTwo.Year && dtOne.Month == dtTwo.Month && dtOne.Day == dtTwo.Day)
  ....
Cristian
la source
-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
la source
5
-1: Pourquoi ne pas simplement analyser DateTime et utiliser la méthode de @Quintin Robinson? C'est le code que je m'attendrais à voir sur le Daily WTF.
William Hurst le
Pas besoin de créer autant de variables car cela augmente le temps de réponse pour une tâche aussi simple.
Nayan Katkani