DateTime.Compare, um zu überprüfen, ob ein Datum weniger als 30 Tage alt ist?

82

Ich versuche herauszufinden, ob ein Konto in weniger als 30 Tagen abläuft. Benutze ich DateTime Compare richtig?

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

{
     matchFound = true;
}
David Basarab
quelle

Antworten:

228

Benutze ich DateTime Compare richtig?

Nein Comparebietet nur Informationen über die relative Position von zwei Daten: kleiner, gleich oder größer. Was Sie wollen, ist ungefähr so:

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

Dies subtrahiert zwei DateTimes. Das Ergebnis ist ein TimeSpanObjekt mit einer TotalDaysEigenschaft.

Zusätzlich kann die Bedingung direkt geschrieben werden als:

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

Nicht ifbenötigt.

Konrad Rudolph
quelle
2
Sollte erlaubt sein, Ihnen 2+ zu geben;) eine für die Antwort und eine für die kurze Art, sie auszudrücken
CheGueVerra
4
Äh ... Ich habe meine Antwort nur länger gemacht, also zögern Sie nicht, eine imaginäre Stimme abzuziehen. ;-)
Konrad Rudolph
1
Bitte verwenden Sie TotalDaysanstelle von Tagen.
João Portela
2
Es ist konzeptionell genauer. Es macht keinen Unterschied, weil Dayses die größte Komponente von ist TimeSpan. Leute, die dies lesen, können das extrapolieren, um zu glauben, dass die SecondsEigenschaft genauso funktioniert.
João Portela
2
Hinzu kommt, dass João Portela darauf hingewiesen hat, dass auch er Daysselbst falsch sein kann. Daysund TotalDayssind hier nur deshalb gleich, weil die Bedingung ist < 30, aber es würde einen offensichtlichen Unterschied geben, wenn es wäre <= 30, weil TotalDaysmöglicherweise so etwas zurückgibt, 30.421während Daysnoch zurückkehrt 30.
Racil Hilan
15

sollte sein

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

Beachten Sie die Gesamtzahl der Tage, sonst erhalten Sie werid Verhalten

Luke
quelle
Diese Antwort war über ein Jahr nach der letzten Bearbeitung der akzeptierten Antwort!
Mitch Wheat
@Mitch - Dies ist die richtige Antwort. Beachten Sie, dass er TotalDays anstelle von Days verwendet.
Marcelo Mason
Die akzeptierte Antwort ist richtig. TotalDays gibt auch einen Bruchteil zurück, der im Vergleich zu einer Ganzzahl redundant ist.
Mitch Wheat
1
@MitchWheat TotalDaysist ein konzeptionell korrektes Feld. In der Praxis liefern sie das gleiche Ergebnis, aber nur, weil dies Daysdie größte Komponente von ist TimeSpan, wenn es eine Monats- oder Jahreskomponente gegeben hätte und dies eine andere Geschichte gewesen wäre. Versuchen Sie einfach mit Hours, Secondsoder Millisecondsum zu sehen , wie sie funktionieren.
João Portela
7

Nun, ich würde es stattdessen so machen:

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

Vergleichen antwortet nur mit einer Ganzzahl, die angibt, ob das erste früher, gleich oder später ist ...

Haqwin
quelle
6

Versuchen Sie dies stattdessen

if ( (expiryDate - DateTime.Now ).TotalDays < 30 ) { 
  matchFound = true;
}
JaredPar
quelle
1
Hmm, Sie müssen entweder die Reihenfolge Ihrer Daten umkehren oder den absoluten Wert annehmen, es sei denn, das Ablaufdatum ist bereits überschritten.
Konrad Rudolph
3

Compare gibt 1, 0, -1 für größer als, gleich bzw. kleiner als zurück.

Sie wollen:

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

Dadurch erhalten Sie ein genaues Ergebnis:

if ((expiryDate.Date - DateTime.Now.Date).Days < 30)
    matchFound = true;
Jayant
quelle
Tatsächlich ist das, was in der Stunde passiert, zB : 47: 00 AM) & höher Code hat den Wert 28/4/2011 12:00:00 AM -26/4/2011 12:00:00 AM, was einen genauen Unterschied ergibt.
Jayant
1

Vergleichen ist nicht erforderlich , Tage / Gesamttage sind nicht erforderlich .

Alles was Sie brauchen ist

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

Beachten Sie, dass dies funktioniert, wenn Sie Minuten, Monate oder sogar Jahre als Ablaufkriterien verwenden.

rauben
quelle
1
Keine gute Antwort, denn jetzt berücksichtigen Sie auch Stunden, Minuten und Sekunden. DateTime.Today wäre für die OP-Situation korrekter.
JL.
1

Angenommen, Sie möchten false(falls zutreffend) zuweisen matchtime, wäre eine einfachere Schreibweise ..

matchtime = ((expiryDate - DateTime.Now).TotalDays < 30);
Magischer Mick
quelle
Der ternäre Operator ist hier vollständig redundant, da ((expiryDate - DateTime.Now) .TotalDays <30) bereits einen Booleschen Wert zurückgibt.
Fabio
@Fabio Thanks Buddy hat sie entfernt, um den Booleschen Wert über den Rückgabetyp zuzuweisen.
Magic Mick
0

Nein, die Vergleichsfunktion gibt entweder 1, 0 oder -1 zurück. 0 Wenn die beiden Werte gleich sind, bedeuten -1 und 1 kleiner als und größer als, ich glaube an diese Reihenfolge, aber ich vermische sie oft.

Timothy Carter
quelle
0

Nein, Sie verwenden es nicht richtig.

Siehe hier für Details.

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

Sie möchten die beiden DateTimes (expiryDate und DateTime.Now) subtrahieren. Dies gibt ein Objekt vom Typ TimeSpan zurück. Der TimeSpan hat die Eigenschaft "Days". Vergleichen Sie diese Zahl mit 30 für Ihre Antwort.

GWLlosa
quelle
0

Nein, es ist nicht korrekt. Versuchen Sie Folgendes:

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

Eigentlich hat keine dieser Antworten bei mir funktioniert. Ich habe es so gelöst:

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

Als ich das versuchte:

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

Heute, 2011-11-14 und mein Ablaufdatum war 2011-10-17. Ich habe das matchFound = -28. Anstelle von 28. Also habe ich den letzten Scheck umgekehrt.

SBergstrom
quelle
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
quelle
1
Ist das nicht ein bisschen kompliziert?
Max
Wo ist die Erwähnung von accountExpireDates in der Frage? Sie kopieren eine schlechte Lösung eingefügt. matchFound klingt fast so, als würden Sie Pattern oder RegEx mischen. Übrigens müssen Sie eine Pause einlegen, wenn eine Übereinstimmung gefunden wird oder die Schleife fortgesetzt wird. Was ist auch, wenn es -2 ist? MSDN sagt nicht, dass die möglichen Werte -1, 0 und 1 sind.
Mukus
0

Sie können versuchen, dies folgendermaßen zu tun:

var daysPassed = (DateTime.UtcNow - expiryDate).Days;
if (daysPassed > 30)
{ 
    // ...
}
vlad
quelle
6
Bitte versuchen Sie, Ihre Erklärung aussagekräftiger zu gestalten.
Borchvm