Como comparar apenas Data sem hora nos tipos DateTime no Linq to SQL com o Entity Framework?


303

Existe uma maneira de comparar duas DateTimevariáveis, Linq2Sqlmas desconsiderando a parte Time.

O aplicativo armazena itens no banco de dados e adiciona uma data publicada. Quero manter a hora exata, mas ainda assim posso conseguir a data.

Eu quero comparar 12/3/89 12:43:34e 12/3/89 11:22:12ignorar a hora real do dia, para que ambos sejam considerados iguais.

Acho que posso definir todas as horas do dia como 00:00:00antes da comparação, mas na verdade quero saber a hora do dia em que também quero poder comparar apenas por data.

Encontrei um código com o mesmo problema e eles comparam o ano, o mês e o dia separadamente. Existe uma maneira melhor de fazer isso?

Respostas:


534

tente usar a Datepropriedade no DateTimeobjeto ...

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

25
Se você acabar aqui depois do início de 2017, procurando uma maneira de comparar datas em um ambiente do Entity Framework, como eu fiz, verifique a resposta abaixo de Alejandro e o comentário de wasatchWizard.
18717 Mike Onsen

8
Se você acabar aqui depois de meados de 2018, procurando uma maneira de ler outro comentário extremamente útil como o descrito acima, estará sem sorte.
Nardnob 01/06/19

4
Se você acabar aqui algum tempo depois do início de 2019 procurando alívio em quadrinhos, você o encontrou.
Phil Ringsmuth 28/03/19

1
Esta não é absolutamente a resposta correta. O OP disse especificamente Linq to SQL e datetime.date NÃO é permitido em expressões linq.
Philip Vaughn

2
Se você acabar aqui depois do início de 2020, espero que você se cuide e fique em casa durante as crises de pandemia de coronavírus. Volte aqui em 2021!
Sr. Ott

61

Para uma comparação verdadeira, você pode usar:

dateTime1.Date.CompareTo(dateTime2.Date);

18
O que exatamente você quer dizer com "comparação verdadeira"?
31909 Randolpho

6
Randolpho: Usar == fornecerá igualdade, portanto, se as duas datas são iguais ou diferentes. CompareTo irá compará-los, ou seja, fornecerá uma maneira de informar se date1> date2, date1 <date2 ou date1 == date2.
Reed Copsey

6
@ReedCopsey Você não pode simplesmente usar (dateTime1.Date <dateTime1.Date)?
David

14
Mas quem quer -1, 0e 1, realmente? Eles são apenas números mágicos representando "menos", "igual" e "maior". E você terá que "comparar" o número inteiro resultante com algo depois, porque existem três valores possíveis. Tenho de concordar com @ David que é muito mais natural para usar dateTime1.Date < dateTime1.Date, e da mesma forma, com <=, >e >=, na maioria das aplicações.
Jeppe Stig Nielsen

8
@JeppeStigNielsen Se você estiver usando isso em qualquer coisa que classifique ou faça uma prisão em coma, então você deseja - caso contrário, normalmente você quer apenas os operadores.
Reed Copsey

45

É assim que faço isso para trabalhar com o 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));

Se você usá dtOne.Date == dtTwo.Date- lo apenas , não funcionará com o LINQ (erro: o membro do tipo especificado 'Data' não é suportado no LINQ to Entities)


22
Isso funciona muito bem com o LINQ to Entities. No entanto, EntityFunctionsfoi preterido no .NET 4.5.2. Utilize este em vez disso: DbFunctions.TruncateTime. Ele parece ser o método idêntico, apenas movido ..
wasatchwizard

25

Se você estiver usando o Entity Framework <v6.0, use EntityFunctions.TruncateTime Se você estiver usando o Entity Framework> = v6.0, useDbFunctions.TruncateTime

Use (com base na sua versão EF) em torno de qualquer DateTimepropriedade de classe que você deseja usar dentro da sua consulta Linq

Exemplo

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

Apenas um lembrete aqui: desde que seja o Linq to Entity.
curiousBoy

Essa deve ser a resposta correta (a partir de 2019). EntityFunctions é depreciado e você não tem permissão para usar datetime.date em uma expressão lambda (por qualquer motivo - quero dizer sério ... por que eles não corrigiram isso ?!).
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....");
}

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

Você pode usar isso se estiver usando DateFields anuláveis.


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

O valor diff representa o número de dias para a idade. Se o valor for negativo, a data de início cai após a data de término. Esta é uma boa verificação.


1

Você pode usar Equals ou CompareTo .

Igual a : Retorna um valor indicando se duas instâncias DateTime têm o mesmo valor de data e hora.

CompareTo Return Value :

  1. Menos que zero : se esta instância for anterior ao valor.
  2. Zero : se esta instância for igual ao valor.
  3. Maior que zero : se essa instância for posterior ao valor.

DateTime é anulável:

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ão é anulável:

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

0

Na sua cláusula join ou where, use a Datepropriedade da coluna Nos bastidores, isso executa uma CONVERT(DATE, <expression>)operação. Isso deve permitir comparar datas sem o horário.


0

Podes tentar

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: Por que não apenas analisar o DateTime e usar o método do @Quintin Robinson? Este é um código que eu esperaria ver no The Daily WTF.
William Hurst

Não é necessário criar tantas variáveis, pois aumenta o tempo de resposta para uma tarefa tão fácil.
Nayan Katkani #
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.