DateTime Porównaj, jak sprawdzić, czy data ma mniej niż 30 dni?


86

Próbuję dowiedzieć się, czy konto wygaśnie za mniej niż 30 dni. Czy prawidłowo używam porównania dat i godzin?

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

{
     matchFound = true;
}

Odpowiedzi:


232

Czy prawidłowo używam porównania dat i godzin?

Nie. CompareOferuje tylko informacje o względnym położeniu dwóch dat: mniej, równo lub więcej. To, czego chcesz, to coś takiego:

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

To odejmuje dwa DateTimes. Wynikiem jest TimeSpanobiekt, który ma TotalDayswłaściwość.

Dodatkowo warunek można zapisać bezpośrednio jako:

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

Nie ifpotrzeba.


2
Powinienem dać ci 2+;) jeden za odpowiedź i jeden za krótki sposób wyrażenia tego
CheGueVerra

4
Uh… właśnie przedłużyłem swoją odpowiedź, więc możesz odjąć jeden wyimaginowany głos. ;-)
Konrad Rudolph

1
Użyj TotalDayszamiast dni.
João Portela,

2
Jest koncepcyjnie dokładniejszy. Nie ma to znaczenia, ponieważ Daysjest największym składnikiem TimeSpan. Osoby czytające to mogą ekstrapolować to, sądząc, że Secondsnieruchomość działa w ten sam sposób.
João Portela,

2
Dodając do tego, co powiedział João Portela, nawet on Dayssam też może się mylić. Daysi TotalDayssą takie same tylko dlatego, że warunek jest < 30, ale byłaby oczywista różnica, gdyby tak było <= 30, ponieważ TotalDaysmoże zwrócić coś takiego 30.421, jak while Dayswciąż zwraca 30.
Racil Hilan

15

Powinien być

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

zanotuj całkowitą liczbę dni, w przeciwnym razie uzyskasz gorsze zachowanie


ta odpowiedź została udzielona ponad rok po ostatniej edycji zaakceptowanej odpowiedzi!
Mitch Wheat

@Mitch - To jest prawidłowa odpowiedź, zauważ, że używa TotalDays zamiast Days.
Marcelo Mason

Przyjęta odpowiedź jest prawidłowa. TotalDays zwraca również część ułamkową, która jest zbędna w porównaniu z liczbą całkowitą.
Mitch Wheat

1
@MitchWheat TotalDaysjest koncepcyjnie poprawnym polem do użycia. W praktyce dają ten sam wynik, ale tylko dlatego, że Daysjest to największy składnik TimeSpan, gdyby istniał składnik Miesiące lub Lata, a to byłaby inna historia. Tylko spróbuj Hours, Secondsalbo Millisecondszobaczyć, jak one działają.
João Portela,

7

Zamiast tego zrobiłbym to w ten sposób:

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

Porównaj odpowiada tylko liczbą całkowitą wskazującą, że pierwsza pogoda jest wcześniejsza, taka sama lub później ...


6

Spróbuj tego zamiast tego

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

1
Hmm, musisz albo odwrócić kolejność dat, albo przyjąć wartość bezwzględną, chyba że data ważności już minęła.
Konrad Rudolph

3

Porównaj zwraca 1, 0, -1 dla odpowiednio większego niż, równego, mniejszego niż.

Chcesz:

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

1

To da ci dokładny wynik:

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

faktycznie to co się dzieje hr to np. expryDte to 28.04.2011, jeśli U rite (expiryDate-DateTime.now) to również zajmie trochę czasu (28.04.2011 12:00:00 - 26.04.2011 11 : 47: 00), a powyższy kod przyjmuje wartość 28/4/2011 12:00:00 AM -26/4/2011 12:00:00, co nie daje dokładnej różnicy.
Jayant

1

Porównanie jest niepotrzebne, dni / suma dni są niepotrzebne.

Wszystko czego potrzebujesz to

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

pamiętaj, że zadziała, jeśli zdecydujesz się użyć minut, miesięcy lub nawet lat jako kryteriów wygaśnięcia.


1
Niezbyt dobra odpowiedź, ponieważ teraz bierzesz pod uwagę godziny, minuty i sekundy. Data i godzina Dzisiejszy dzień byłby bardziej odpowiedni dla sytuacji PO.
JL.

1

Zakładając, że chcesz przypisać false(jeśli ma to zastosowanie) do matchtime, prostszy sposób zapisu byłby ...

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

Operator trójargumentowy jest tutaj całkowicie zbędny, ponieważ ((expiryDate - DateTime.Now) .TotalDays <30) już zwraca wartość logiczną.
Fabio

@Fabio Dzięki znajomemu usunęli je, aby przypisać wartość logiczną za pośrednictwem zwracanego typu.
Magic Mick

0

Nie, funkcja Porównaj zwróci wartość 1, 0 lub -1. 0 gdy te dwie wartości są równe, -1 i 1 oznaczają mniej niż i więcej niż, wierzę w tej kolejności, ale często mylę je.


0

Nie, nie używasz go poprawnie.

Zobacz tutaj po szczegóły.

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

0

To, co chcesz zrobić, to odjąć dwa DateTimes (expiryDate i DateTime.Now). To zwróci obiekt typu TimeSpan. TimeSpan ma właściwość „Days”. Dla swojej odpowiedzi porównaj tę liczbę z 30.


0

Nie, to nie jest poprawne, spróbuj tego:

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

0

Właściwie żadna z tych odpowiedzi nie zadziałała dla mnie. Rozwiązałem to w ten sposób:

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

Kiedy próbowałem to zrobić:

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

Dzisiaj, 2011-11-14, a moja data ważności to 2011-10-17, otrzymałem to matchFound = -28. Zamiast 28. Więc odwróciłem ostatni czek.


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

1
Czy to nie jest trochę skomplikowane?
Max

Gdzie w pytaniu jest wzmianka o datach ważności konta? Skopiowałeś wklejone złe rozwiązanie. matchFound brzmi prawie tak, jakbyś miksował Pattern lub RegEx. Przy okazji, musisz przerwać, gdy zostanie znalezione dopasowanie lub kontynuuje zapętlenie. A jeśli to jest -2? MSDN nie podaje, że możliwe wartości to -1, 0 i 1.
Mukus,

0

Możesz spróbować zrobić tak:

var daysPassed = (DateTime.UtcNow - expiryDate).Days;
if (daysPassed > 30)
{ 
    // ...
}

6
Postaraj się, aby Twoje wyjaśnienie było bardziej opisowe.
borchvm
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.