DateTime.Compare como verificar se uma data tem menos de 30 dias?

86

Estou tentando descobrir se uma conta expira em menos de 30 dias. Estou usando a comparação DateTime corretamente?

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

{
     matchFound = true;
}
David Basarab
fonte

Respostas:

232

Estou usando a comparação DateTime corretamente?

Não Compare. Oferece apenas informações sobre a posição relativa de duas datas: menor, igual ou maior. O que você quer é algo assim:

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

Isso subtrai dois DateTimes. O resultado é um TimeSpanobjeto que possui uma TotalDayspropriedade.

Além disso, a condicional pode ser escrita diretamente como:

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

Não é ifnecessário.

Konrad Rudolph
fonte
2
Deve ser permitido fornecer a você 2+;) um para a resposta e outro para a forma abreviada de expressá-la
CheGueVerra
4
Uh ... Acabei de deixar minha resposta mais longa, então fique à vontade para subtrair um voto imaginário. ;-)
Konrad Rudolph
1
Use em TotalDaysvez de dias.
João Portela
2
É conceitualmente mais preciso. Não faz diferença porque Daysé o maior componente do TimeSpan. As pessoas que estão lendo isso podem extrapolar pensando que a Secondspropriedade funciona da mesma maneira.
João Portela
2
Acrescentando ao ponto que João Portela fez, até Daysele próprio pode estar errado. Dayse TotalDayssão iguais aqui apenas porque a condição é < 30, mas haveria uma diferença óbvia se fosse <= 30, porque TotalDayspode retornar algo como 30.421while Daysainda retorna 30.
Racil Hilan
15

deveria estar

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

anote o total de dias, caso contrário, você obterá um comportamento werid

Lucas
fonte
esta resposta foi mais de um ano após a última edição para resposta aceita!
Mitch Wheat
@Mitch - Esta é a resposta correta, observe que ele está usando TotalDays em vez de Dias.
Marcelo Mason
A resposta aceita está correta. TotalDays retorna uma parte fracionária também, que é redundante ao comparar com um inteiro.
Mitch Wheat de
1
@MitchWheat TotalDaysé o campo conceitualmente correto a ser usado. Na prática, eles dão o mesmo resultado, mas apenas porque Daysé o maior componente de TimeSpan, se houvesse um componente Meses ou Anos e isso teria sido uma história diferente. Apenas tente com Hours, Secondsou Millisecondspara ver como eles funcionam.
João Portela
7

Bem, eu faria assim em vez disso:

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

Compare apenas responde com um número inteiro indicando se o primeiro é anterior, igual ou posterior ...

haqwin
fonte
6

Em vez disso, tente isso

if ( (expiryDate - DateTime.Now ).TotalDays < 30 ) { 
  matchFound = true;
}
JaredPar
fonte
1
Hmm, você precisa inverter a ordem das datas ou usar o valor absoluto, a menos que a data de vencimento já tenha passado.
Konrad Rudolph
3

Compare retorna 1, 0, -1 para maior que, igual a, menor que, respectivamente.

Você quer:

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

Isso lhe dará um resultado preciso:

if ((expiryDate.Date - DateTime.Now.Date).Days < 30)
    matchFound = true;
Jayant
fonte
na verdade, o que acontece hr é eg.expryDte é 28/4/2011 se U rite (expiryDate-DateTime.now) também levará o tempo (28/4/2011 12:00:00 AM - 26/4/2011 11 : 47: 00 AM) e o código acima assume o valor 28/4/2011 12:00:00 AM -26/4/2011 12:00:00 AM, o que dará uma diferença precisa.
Jayant
1

Comparar é desnecessário, Dias / TotalDays são desnecessários.

Tudo o que você precisa é

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

observe que isso funcionará se você decidir usar minutos ou meses ou mesmo anos como seu critério de expiração.

roubar
fonte
1
Não é uma boa resposta porque agora você também está levando em consideração horas, minutos e segundos. DateTime.Today seria mais correto para a situação de OPs.
JL.
1

Supondo que você queira atribuir false(se aplicável) a matchtime, uma maneira mais simples de escrever seria ..

matchtime = ((expiryDate - DateTime.Now).TotalDays < 30);
Magic Mick
fonte
O operador ternário aqui é completamente redundante, pois ((expiryDate - DateTime.Now) .TotalDays <30) já retorna um booleano.
Fabio
@Fabio Obrigado amigo os removeu para atribuir o valor booleano por meio do tipo de retorno.
Magic Mick
0

Não, a função Comparar retornará 1, 0 ou -1. 0 quando os dois valores são iguais, -1 e 1 significam menor e maior, acredito nessa ordem, mas costumo confundi-los.

Timothy Carter
fonte
0

Não, você não está usando corretamente.

Veja aqui os detalhes.

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

O que você quer fazer é subtrair os dois DateTimes (expiryDate e DateTime.Now). Isso retornará um objeto do tipo TimeSpan. O TimeSpan possui uma propriedade "Dias". Compare esse número com 30 para sua resposta.

GWLlosa
fonte
0

Não, não está correto, tente isto:

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

Na verdade, nenhuma dessas respostas funcionou para mim. Eu resolvi isso fazendo assim:

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

Quando tentei fazer isso:

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

Hoje, 2011-11-14 e minha expiryDate foi 2011-10-17, recebi esse matchFound = -28. Em vez de 28. Então, inverti a última verificação.

SBergstrom
fonte
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
fonte
1
Não é um pouco complicado?
Máx.
Onde está a menção de accountExpireDates na pergunta? Você copiou e colou uma solução ruim. matchFound soa quase como se você estivesse mixando Pattern ou RegEx. A propósito, você precisa interromper quando uma correspondência for encontrada ou ele continuar a repetir. E se for -2? O MSDN não diz que os valores possíveis são -1, 0 e 1.
Mukus
0

Você pode tentar fazer assim:

var daysPassed = (DateTime.UtcNow - expiryDate).Days;
if (daysPassed > 30)
{ 
    // ...
}
vlad
fonte
6
Por favor, tente ser mais descritivo em sua explicação.
borchvm