539 Stimmen

Vergleich nur des Datumsteils ohne Zeitvergleich in JavaScript

Was ist mit dem unten stehenden Code falsch?

Vielleicht wäre es einfacher, nur das Datum und nicht die Uhrzeit zu vergleichen. Ich bin mir auch nicht sicher, wie man das macht, und ich habe gesucht, aber ich konnte mein Problem nicht genau finden.

Übrigens, wenn ich die beiden Daten in einer Warnmeldung anzeige, sind sie genau gleich.

Mein Code:

window.addEvent('domready', function() {
    var now = new Date();
    var input = $('datum').getValue();
    var dateArray = input.split('/');
    var userMonth = parseInt(dateArray[1])-1;
    var userDate = new Date();
    userDate.setFullYear(dateArray[2], userMonth, dateArray[0], now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds());

    if (userDate > now)
    {
        alert(now + '\n' + userDate);
    }
});

Gibt es eine einfachere Möglichkeit, Daten zu vergleichen, ohne die Uhrzeit anzugeben?

8 Stimmen

date1.toDateString() === date2.toDateString()

0 Stimmen

Von den Toten auferstanden: Ich erhalte fehlerhafte Ergebnisse von date.setFullYear(yyyy,mm,dd) Wenn ich toSting auf das Datum anwende, wird der Monat um 1 erhöht. Getestet auf dieser Seite Link sowohl in FireFox als auch in Edge.

18voto

brittohalloran Punkte 3434

Wenn Sie wirklich nur das Datum ohne Zeitkomponente vergleichen wollen, gibt es eine andere Lösung, die sich vielleicht falsch anfühlt, aber funktioniert und alles vermeidet Date() Zeit und Zeitzone Kopfschmerzen ist es, die ISO-Zeichenfolge Datum direkt mit String-Vergleich zu vergleichen:

> "2019-04-22" <= "2019-04-23"
true
> "2019-04-22" <= "2019-04-22"
true
> "2019-04-22" <= "2019-04-21"
false
> "2019-04-22" === "2019-04-22"
true

Sie können das aktuelle Datum (UTC-Datum, nicht notwendigerweise das lokale Datum des Benutzers) mit:

> new Date().toISOString().split("T")[0]
"2019-04-22"

Mein Argument dafür ist die Einfachheit für den Programmierer - es ist viel unwahrscheinlicher, dass man dies verpfuscht, als zu versuchen, Datumszeiten und Offsets korrekt zu behandeln, wahrscheinlich auf Kosten der Geschwindigkeit (ich habe die Leistung nicht verglichen)

1 Stimmen

Sie können auch Folgendes tun new Date().toISOString().substr(0, 10) // "2019-04-22" .

0 Stimmen

Für das lokale Datum (nicht-UTC-Datum) können Sie verwenden new Date().toLocaleDateString() // "8/26/2019" . Aber dann wird der Vergleich des Textes nicht genau sein (wie "8/26/2019" >= "9/29/2001" falsch ist). Sie müssen es also umwandeln new Date(new Date().toLocaleDateString()) um einen genauen Vergleich mit einem anderen Datum durchzuführen.

16voto

Mike Feltman Punkte 5131

Verwenden Sie einfach toDateString() für beide Datumsangaben. toDateString enthält nicht die Uhrzeit, so dass die Werte für zwei Zeitpunkte am selben Datum gleich sind, wie unten gezeigt.

var d1 = new Date(2019,01,01,1,20)
var d2 = new Date(2019,01,01,2,20)
console.log(d1==d2) // false
console.log(d1.toDateString() == d2.toDateString()) // true

Natürlich sind einige der an anderer Stelle zu dieser Frage geäußerten Bedenken bezüglich der Zeitzonen berechtigt, aber in vielen Szenarien sind diese nicht relevant.

4 Stimmen

In meinem Fall ist diese Lösung viel besser als die ausgewählte Antwort und die Antworten, für die mehr Stimmen abgegeben wurden. In der Überschrift heißt es ausdrücklich "ohne Zeitvergleich", und genau das tut diese Lösung, denn sie erspart es, die Zeit einzustellen, um den Vergleich zu manipulieren. Um die Frage "Sind Ereignis X und Ereignis Y am selben Tag eingetreten?" zu beantworten, ist es sinnvoller, nur das Datum zu vergleichen, als die Frage "Ist 00:00:00.00 Uhr des Datums von Ereignis X genau dasselbe wie 00:00:00.00 Uhr des Datums von Ereignis Y?" zu beantworten, was viele andere Antwortende tun.

10voto

Useless Code Punkte 11234

Dies könnte eine etwas sauberere Version sein, beachten Sie auch, dass Sie immer ein Radix verwenden sollten, wenn Sie parseInt verwenden.

window.addEvent('domready', function() {
    // Create a Date object set to midnight on today's date
    var today = new Date((new Date()).setHours(0, 0, 0, 0)),
    input = $('datum').getValue(),
    dateArray = input.split('/'),
    // Always specify a radix with parseInt(), setting the radix to 10 ensures that
    // the number is interpreted as a decimal.  It is particularly important with
    // dates, if the user had entered '09' for the month and you don't use a
    // radix '09' is interpreted as an octal number and parseInt would return 0, not 9!
    userMonth = parseInt(dateArray[1], 10) - 1,
    // Create a Date object set to midnight on the day the user specified
    userDate = new Date(dateArray[2], userMonth, dateArray[0], 0, 0, 0, 0);

    // Convert date objects to milliseconds and compare
    if(userDate.getTime() > today.getTime())
    {
            alert(today+'\n'+userDate);
    }
});

Besuchen Sie das MDC parseInt Seite für weitere Informationen über das Radix.

JSLint ist ein großartiges Werkzeug, um Dinge wie ein fehlendes Radix und viele andere Dinge, die obskure und schwer zu behebende Fehler verursachen können, zu erkennen. Es zwingt Sie dazu, bessere Codierungsstandards zu verwenden, damit Sie zukünftige Kopfschmerzen vermeiden. Ich verwende es bei jedem JavaScript-Projekt, das ich programmiere.

0 Stimmen

@EmKay Dies sollte jetzt nicht mehr so ein großes Problem sein, da ES5 in den meisten Browsern Standard ist und es verbietet die oktale Interpretation ABER einige Browser könnten aus Gründen der Abwärtskompatibilität immer noch die alte Oktalinterpretation verwenden, daher würde ich für die absehbare Zukunft weiterhin ein Radix verwenden.

0 Stimmen

Wenn Sie strenger Modus Oktalinterpretationen führen zu Fehlern, was gut ist, weil es Ihnen hilft, Fehler zu finden, die möglicherweise falsch interpretiert werden.

8voto

robocat Punkte 5047

Ein effizienter und korrekter Weg, Daten zu vergleichen, ist:

Math.floor(date1.getTime() / 86400000) > Math.floor(date2.getTime() / 86400000);

Die Zeitangabe wird ignoriert, es funktioniert für verschiedene Zeitzonen und man kann auf Gleichheit vergleichen == zu. 86400000 ist die Anzahl der Millisekunden an einem Tag ( = 24*60*60*1000 ).

Beachten Sie, dass der Gleichheitsoperator == sollte niemals für den Vergleich von Datumsobjekten verwendet werden, da er fehlschlägt, wenn man erwarten würde, dass ein Gleichheitstest funktioniert, weil er zwei Datumsobjekte vergleicht (und nicht die beiden Datumsangaben), z. B.:

> date1;
outputs: Thu Mar 08 2018 00:00:00 GMT+1300

> date2;
outputs: Thu Mar 08 2018 00:00:00 GMT+1300

> date1 == date2;
outputs: false

> Math.floor(date1.getTime() / 86400000) == Math.floor(date2.getTime() / 86400000);
outputs: true

Anmerkungen: Wenn Sie Datumsobjekte vergleichen, bei denen der Zeitanteil auf Null gesetzt ist, können Sie date1.getTime() == date2.getTime() aber das ist die Optimierung kaum wert. Sie können verwenden < , > , <= , oder >= beim direkten Vergleich von Datumsobjekten, da diese Operatoren das Datumsobjekt zunächst durch den Aufruf von .valueOf() bevor der Operator den Vergleich durchführt.

4voto

Max Yari Punkte 3437

Da ich hier keinen ähnlichen Ansatz sehe und es mir nicht gefällt, h/m/s/ms auf 0 zu setzen, da es Probleme mit dem genauen Übergang zur lokalen Zeitzone bei geänderten date Objekt (so nehme ich an), lassen Sie mich hier diese, vor wenigen Augenblicken geschriebene, lil-Funktion vorstellen:

+ : Einfach zu bedienen, macht einen grundlegenden Vergleich Operationen getan (Vergleich Tag, Monat und Jahr ohne Zeit.)
- : Dies scheint das genaue Gegenteil von "out of the box"-Denken zu sein.

function datecompare(date1, sign, date2) {
    var day1 = date1.getDate();
    var mon1 = date1.getMonth();
    var year1 = date1.getFullYear();
    var day2 = date2.getDate();
    var mon2 = date2.getMonth();
    var year2 = date2.getFullYear();
    if (sign === '===') {
        if (day1 === day2 && mon1 === mon2 && year1 === year2) return true;
        else return false;
    }
    else if (sign === '>') {
        if (year1 > year2) return true;
        else if (year1 === year2 && mon1 > mon2) return true;
        else if (year1 === year2 && mon1 === mon2 && day1 > day2) return true;
        else return false;
    }    
}

Verwendung:

datecompare(date1, '===', date2) für die Gleichheitsprüfung,
datecompare(date1, '>', date2) zur genaueren Überprüfung,
!datecompare(date1, '>', date2) für weniger oder gleiche Prüfung

Außerdem können Sie natürlich die date1 y date2 an einigen Stellen, um einen anderen einfachen Vergleich zu erreichen.

0 Stimmen

Gut gemacht, plus plus, hat mir geholfen, jetzt hoffentlich beißen die Iso-Konvertierungen nicht, haha, danke.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X