¿Cómo comparar solo Fecha sin hora en tipos de fecha y hora en Linq a SQL con Entity Framework?

304

¿Hay alguna manera de comparar dos DateTimevariables Linq2Sqlpero ignorar la parte de Tiempo?

La aplicación almacena elementos en la base de datos y agrega una fecha de publicación. Quiero mantener la hora exacta, pero aún así puedo obtener la fecha en sí.

Quiero comparar 12/3/89 12:43:34y 12/3/89 11:22:12no tener en cuenta la hora real del día, por lo que ambos se consideran iguales.

Supongo que puedo configurar todas las horas del día 00:00:00antes de comparar, pero en realidad quiero saber la hora del día, solo quiero poder comparar solo por fecha.

Encontré un código que tiene el mismo problema y comparan el año, mes y día por separado. ¿Hay una mejor manera de hacer esto?

Sruly
fuente

Respuestas:

535

intente usar la Datepropiedad en el DateTimeobjeto ...

if(dtOne.Date == dtTwo.Date)
    ....
Quintin Robinson
fuente
25
Si terminas aquí en algún momento después de principios de 2017, buscas una forma de comparar fechas en un entorno de Entity Framework como lo hice con la respuesta a continuación de Alejandro y el comentario de wasatchWizard.
Mike Devenney el
8
Si terminas aquí en algún momento después de mediados de 2018 buscando una manera de leer otro comentario extremadamente útil como el anterior, no tienes suerte.
nardnob
44
Si terminas aquí en algún momento después de principios de 2019 buscando alivio cómico, lo has encontrado.
Phil Ringsmuth
1
Esta NO es la respuesta correcta. El OP específicamente dijo Linq a SQL y datetime.date NO está permitido en expresiones linq.
Philip Vaughn
2
Si terminas aquí en algún momento después de principios de 2020, espero que te estés cuidando y que te quedes en casa durante las crisis pandémicas de coronavirus. ¡Vuelve aquí en 2021!
Sr. Ott
61

Para una verdadera comparación, puede usar:

dateTime1.Date.CompareTo(dateTime2.Date);
Reed Copsey
fuente
18
¿Qué quiere decir exactamente con "comparación verdadera"?
Randolpho
66
Randolpho: Usar == le dará igualdad, por lo tanto, si las dos fechas son iguales o diferentes. CompareTo los ~ comparará ~, es decir: le dará una manera en una pasada para saber si date1> date2, date1 <date2 o date1 == date2.
Reed Copsey
66
@ReedCopsey ¿No puedes usar (dateTime1.Date <dateTime1.Date)?
David
14
Pero, ¿quién quiere -1, 0y 1, en realidad? Son solo números mágicos que representan "menos", "igual" y "mayor". Y luego tendrá que "comparar" el entero resultante con algo porque hay tres valores posibles. Debo estar de acuerdo con @David en que es mucho más natural de usar dateTime1.Date < dateTime1.Date, y de manera similar con <=, >y >=, en la mayoría de las aplicaciones.
Jeppe Stig Nielsen
8
@JeppeStigNielsen Si está usando esto en algo que ordena o toma un comaprison, entonces lo quiere; de ​​lo contrario, generalmente solo quiere los operadores.
Reed Copsey
45

Así es como hago esto para trabajar con 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 solo lo usa dtOne.Date == dtTwo.Date, no funcionará con LINQ (Error: el miembro de tipo especificado 'Fecha' no es compatible con LINQ to Entities)

Alejandro del Río
fuente
22
Esto funciona muy bien con LINQ to Entities. Sin embargo, EntityFunctionsha quedado en desuso en .NET 4.5.2. Use este lugar: DbFunctions.TruncateTime. Parece ser el mismo método, recién movido ..
wasatchwizard
25

Si está usando Entity Framework <v6.0, luego use EntityFunctions.TruncateTime Si está usando Entity Framework> = v6.0, luego useDbFunctions.TruncateTime

Use cualquiera (basado en su versión EF) alrededor de cualquier DateTime propiedad de clase que desee usar dentro de su consulta Linq

Ejemplo

var list = db.Cars.Where(c=> DbFunctions.TruncateTime(c.CreatedDate) 
                                       >= DbFunctions.TruncateTime(DateTime.UtcNow));
Korayem
fuente
Solo un recordatorio aquí: siempre y cuando sea Linq to Entity.
curiousBoy
Esta debería ser la respuesta correcta (a partir de 2019). EntityFunctions se deprecia y no se le permite usar datetime.date en una expresión lambda (por alguna razón, quiero decir en serio ... ¡¿por qué no han solucionado esto ?!).
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
fuente
9
DateTime? NextChoiceDate = new DateTime();
DateTIme? NextSwitchDate = new DateTime();
if(NextChoiceDate.Value.Date == NextSwitchDate.Value.Date)
{
Console.WriteLine("Equal");
}

Puede usar esto si está usando DateFields anulables.

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

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

El valor de diferencia representa el número de días para la edad. Si el valor es negativo, la fecha de inicio es posterior a la fecha de finalización. Este es un buen cheque.

dgsjr
fuente
1

Puede usar Equals o CompareTo .

Igual : devuelve un valor que indica si dos DateTime instancias tienen el mismo valor de fecha y hora.

Comparar para devolver el valor :

  1. Menos de cero : si esta instancia es anterior al valor.
  2. Cero : si esta instancia es igual al valor.
  3. Mayor que cero : si esta instancia es posterior al valor.

DateTime es anulable:

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

o

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 no es anulable:

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

o

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
fuente
0

En su cláusula join o where, use la Datepropiedad de la columna. Detrás de escena, esto ejecuta una CONVERT(DATE, <expression>)operación. Esto debería permitirle comparar fechas sin el tiempo.

Adam Robinson
fuente
0

Puedes probar

if(dtOne.Year == dtTwo.Year && dtOne.Month == dtTwo.Month && dtOne.Day == dtTwo.Day)
  ....
Cristian
fuente
-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
fuente
55
-1: ¿Por qué no simplemente analizar DateTime y usar el método @Quintin Robinson? Este es el código que esperaría ver en The Daily WTF.
William Hurst
No es necesario crear tantas variables, ya que aumenta el tiempo de respuesta para una tarea tan fácil.
Nayan Katkani