DateTime.Compare cómo verificar si una fecha tiene menos de 30 días.

86

Estoy tratando de averiguar si una cuenta vence en menos de 30 días. ¿Estoy usando DateTime Compare correctamente?

if (DateTime.Compare(expiryDate, now) < 30)

{
     matchFound = true;
}
David Basarab
fuente

Respuestas:

232

¿Estoy usando DateTime Compare correctamente?

No. Comparesolo ofrece información sobre la posición relativa de dos fechas: menor, igual o mayor. Lo que quieres es algo como esto:

if ((expiryDate - DateTime.Now).TotalDays < 30)
    matchFound = true;

Esto resta dos DateTimes. El resultado es un TimeSpanobjeto que tiene una TotalDayspropiedad.

Además, el condicional se puede escribir directamente como:

matchFound = (expiryDate - DateTime.Now).TotalDays < 30;

No es ifnecesario.

Konrad Rudolph
fuente
2
Debería poder darle 2+;) uno para la respuesta y otro para la forma más corta de expresarlo
CheGueVerra
4
Uh ... Acabo de alargar mi respuesta, así que siéntete libre de restar un voto imaginario. ;-)
Konrad Rudolph
1
Utilice en TotalDayslugar de días.
João Portela
2
Es conceptualmente más preciso. No hace ninguna diferencia porque Dayses el componente más importante de TimeSpan. Las personas que lean esto pueden extrapolarlo para pensar que la Secondspropiedad funciona de la misma manera.
João Portela
2
Además de lo que señaló João Portela, incluso él Daysmismo también puede estar equivocado. Daysy TotalDaysson iguales aquí solo porque la condición es < 30, pero habría una diferencia obvia si lo fuera <= 30, porque TotalDaysmay devuelve algo como 30.421while Daysstill returns 30.
Racil Hilan
15

debiera ser

matchFound = (expiryDate - DateTime.Now).TotalDays < 30;

tenga en cuenta el total de días, de lo contrario obtendrá un comportamiento horrible

Luke
fuente
¡Esta respuesta fue más de un año después de la última edición de la respuesta aceptada!
Mitch Wheat
@Mitch: esta es la respuesta correcta, observe que está usando TotalDays en lugar de Days.
Marcelo Mason
La respuesta aceptada es correcta. TotalDays también devuelve una parte fraccionaria, que es redundante cuando se compara con un número entero.
Mitch Wheat
1
@MitchWheat TotalDayses un campo conceptualmente correcto para usar. En la práctica, dan el mismo resultado, pero solo porque Dayses el componente más grande de TimeSpan, si hubiera habido un componente de meses o años y esto hubiera sido una historia diferente. Simplemente tratar con Hours, Secondso Millisecondspara ver cómo funcionan.
João Portela
7

Bueno, lo haría así en su lugar:

TimeSpan diff = expiryDate - DateTime.Today;
if (diff.Days > 30) 
   matchFound = true;

Compare solo responde con un número entero que indica el tiempo, el primero es anterior, igual o posterior ...

haqwin
fuente
6

Prueba esto en su lugar

if ( (expiryDate - DateTime.Now ).TotalDays < 30 ) { 
  matchFound = true;
}
JaredPar
fuente
1
Hmm, debe invertir el orden de sus fechas o tomar el valor absoluto, a menos que la fecha de vencimiento ya haya pasado.
Konrad Rudolph
3

Compare devuelve 1, 0, -1 para mayor que, igual a, menor que, respectivamente.

Usted quiere:

    if (DateTime.Compare(expiryDate, DateTime.Now.AddDays(30)) <= 0) 
    { 
        bool matchFound = true;
    }
Trigo Mitch
fuente
1

Esto le dará un resultado preciso:

if ((expiryDate.Date - DateTime.Now.Date).Days < 30)
    matchFound = true;
Jayant
fuente
en realidad, lo que sucede hr es, por ejemplo, expryDte es 28/4/2011 si U rito (expiryDate-DateTime.now) también tomará el tiempo (28/4/2011 12:00:00 AM - 26/4/2011 11 : 47: 00 AM) y el código anterior toma el valor 28/4/2011 12:00:00 AM -26/4/2011 12:00:00 AM, lo que dará una diferencia precisa.
Jayant
1

La comparación es innecesaria, los días / días totales son innecesarios.

Todo lo que necesitas es

if (expireDate < DateTime.Now) {
    // has expired
} else {
    // not expired
}

tenga en cuenta que esto funcionará si decide utilizar minutos, meses o incluso años como criterio de caducidad.

robar
fuente
1
No es una gran respuesta porque ahora también está factorizando horas, minutos y segundos. DateTime.Today sería más correcto para la situación de los OP.
JL.
1

Suponiendo que desee asignar false(si corresponde) a matchtime, una forma más sencilla de escribirlo sería ..

matchtime = ((expiryDate - DateTime.Now).TotalDays < 30);
Mick mágico
fuente
El operador ternario aquí es completamente redundante ya que ((expiryDate - DateTime.Now) .TotalDays <30) ya devuelve un booleano.
Fabio
@Fabio Thanks buddy los eliminó para asignar el valor booleano a través del tipo de retorno.
Magic Mick
0

No, la función Comparar devolverá 1, 0 o -1. 0 cuando los dos valores son iguales, -1 y 1 significan menor que y mayor que, creo en ese orden, pero a menudo los mezclo.

Timothy Carter
fuente
0

No, no lo estás usando correctamente.

Consulte aquí para obtener más detalles.

DateTime t1 = new DateTime(100);
DateTime t2 = new DateTime(20);

if (DateTime.Compare(t1, t2) >  0) Console.WriteLine("t1 > t2"); 
if (DateTime.Compare(t1, t2) == 0) Console.WriteLine("t1 == t2"); 
if (DateTime.Compare(t1, t2) <  0) Console.WriteLine("t1 < t2");
David Basarab
fuente
0

Lo que quiere hacer es restar los dos DateTimes (expiryDate y DateTime.Now). Esto devolverá un objeto de tipo TimeSpan. El TimeSpan tiene una propiedad "Días". Compare ese número con 30 para su respuesta.

GWLlosa
fuente
0

No, no es correcto, intente esto:

DateTime expiryDate = DateTime.Now.AddDays(-31);
if (DateTime.Compare(expiryDate, DateTime.Now.AddDays(-30)) < 1)
{
    matchFound = true;
}
Canavar
fuente
0

En realidad, ninguna de estas respuestas funcionó para mí. Lo resolví haciendo así:

  if ((expireDate.Date - DateTime.Now).Days > -30)
  {
    matchFound = true;
  }

Cuando intenté hacer esto:

matchFound = (expiryDate - DateTime.Now).Days < 30;

Hoy, 2011-11-14 y mi fecha de vencimiento fue 2011-10-17 obtuve ese matchFound = -28. En lugar de 28. Así que invertí el último cheque.

SBergstrom
fuente
0
// this isn't set up for good processing.  
//I don't know what data set has the expiration 
//dates of your accounts.  I assume a list.
// matchfound is a single variablethat returns true if any 1 record is expired.

bool matchFound = false;
            DateTime dateOfExpiration = DateTime.Today.AddDays(-30);
            List<DateTime> accountExpireDates = new List<DateTime>();
            foreach (DateTime date in accountExpireDates)
            {
                if (DateTime.Compare(dateOfExpiration, date) != -1)
                {
                    matchFound = true;
            }
            }
Alex
fuente
1
¿No es un poco complicado?
Máximo
¿Dónde está la mención de accountExpireDates en la pregunta? Copias pegadas una mala solución. matchFound casi suena como si estuvieras mezclando Pattern o RegEx. Por cierto, debe interrumpir cuando se encuentra una coincidencia o continúa en bucle. Además, ¿qué pasa si es -2? MSDN no dice que los valores posibles sean -1, 0 y 1.
Mukus
0

Puedes intentar hacer esto:

var daysPassed = (DateTime.UtcNow - expiryDate).Days;
if (daysPassed > 30)
{ 
    // ...
}
vlad
fuente
6
Intente ser más descriptivo en su explicación.
borchvm