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.

953voto

nexar Punkte 10676

Ich lerne immer noch JavaScript, und der einzige Weg, den ich gefunden habe, der für mich funktioniert, um zwei Daten ohne die Zeit zu vergleichen, ist die Verwendung der setHours Methode des Date-Objekts und setzen Sie die Stunden, Minuten, Sekunden und Millisekunden auf Null. Dann vergleichen Sie die beiden Daten.

Zum Beispiel,

date1 = new Date()
date2 = new Date(2011,8,20)

date2 wird mit Stunden, Minuten, Sekunden und Millisekunden auf Null gesetzt, aber bei date1 werden sie auf die Zeit gesetzt, zu der date1 erstellt wurde. Um die Stunden, Minuten, Sekunden und Millisekunden für date1 zu entfernen, gehen Sie wie folgt vor:

date1.setHours(0,0,0,0)

Jetzt können Sie die beiden Daten nur als DATEN vergleichen, ohne sich um die Zeitelemente zu kümmern.

86 Stimmen

Bitte beachten Sie, dass die Prüfung durch date1 === date2 scheint kein konsistentes Verhalten zu bieten; es ist besser, die date1.valueOf() === b.valueOf() oder sogar date1.getTime() === date2.getTime() . Seltsamkeit.

7 Stimmen

Vorsicht: Wenn date1 und date2 im Winter bzw. im Sommer liegen und Sie mit addDays(1) von einem zum anderen iterieren wollen, besteht das Problem darin, dass sie wegen der Sommerzeit nicht dieselbe Zeitzone haben, so dass der letzte Vergleich, der gleiche Daten ergeben sollte, nicht funktioniert, weil die beiden Daten nicht wirklich um 00:00:00:0 liegen.

14 Stimmen

Ich weiß, dass dies eine alte Frage ist, aber sie taucht bei der Suche in Google als erstes auf. Seien Sie vorsichtig mit dieser Antwort. Sie gibt falsche Antworten, wenn der Benutzer sich nicht in der gleichen Zeitzone befindet wie der Ersteller des Datumsobjekts. Ändern Sie zum Beispiel die Zeitzone im Betriebssystem Ihres Computers auf Ostküstenzeit (US-Zeit). Öffnen Sie die Konsole Ihres Browsers und geben Sie var date2 = new Date(2011,8,20) . Ändern Sie nun die Zeitzone des Betriebssystems auf Pazifikzeit (USA). Geben Sie in der gleichen Browserkonsole date2.toDateString() und du bekommst zurück Mon Sep 19 2011 und nicht am Dienstag, den 20.

256voto

bbsimonbb Punkte 23637

BEACHTEN SIE DIE ZEITZONE

Wenn man das Datumsobjekt verwendet, um ein einfaches Datum darzustellen, hat man sofort ein großes Problem mit der übermäßigen Genauigkeit. Sie müssen die Zeit und die Zeitzone verwalten, um sie herauszuhalten, und sie können sich jederzeit wieder einschleichen. Die gängige Antwort auf diese Frage führt in die Falle.

Ein Javascript-Datum hat keine Kenntnis der Zeitzone . Es handelt sich um einen Moment in der Zeit (Ticks seit der Epoche) mit praktischen (statischen) Funktionen für die Übersetzung in und aus Zeichenketten, wobei standardmäßig die "lokale" Zeitzone des Geräts oder, falls angegeben, UTC oder eine andere Zeitzone verwendet wird. Um just-a-date™ mit einem Datumsobjekt darzustellen, Sie möchten, dass Ihre Daten UTC-Mitternacht zu Beginn des betreffenden Datums entsprechen. Dies ist eine gängige und notwendige Konvention, die es Ihnen ermöglicht, mit Daten unabhängig von der Jahreszeit oder Zeitzone ihrer Erstellung zu arbeiten. Sie müssen also sehr wachsam sein, um den Begriff der Zeitzone zu verwalten, sowohl bei der Erstellung Ihres Mitternachts-UTC-Datumsobjekts als auch bei dessen Serialisierung.

Viele Leute sind durch das Standardverhalten der Konsole verwirrt. Wenn Sie ein Datum in die Konsole sprühen, enthält die Ausgabe, die Sie sehen, Ihre Zeitzone. Das liegt einfach daran, dass die Konsole die Funktion toString() bei Ihrem Date, und toString() gibt Ihnen eine lokale Repräsentanz. Das zugrunde liegende Datum hat keine Zeitzone ! (Solange die Zeit mit dem Zeitzonen-Offset übereinstimmt, haben Sie immer noch ein Mitternachts-UTC-Datumsobjekt)

Deserialisierung (oder Erstellung von Mitternachts-UTC-Datumsobjekten)

Dies ist der Rundungsschritt mit dem Trick, dass es zwei "richtige" Antworten gibt. In den meisten Fällen möchten Sie, dass Ihr Datum die lokale Zeitzone des Benutzers widerspiegelt. Was ist das Datum hier, wo ich bin. . Nutzer in Neuseeland und den USA können gleichzeitig klicken und erhalten in der Regel unterschiedliche Daten. In diesem Fall, tun Sie dies...

// create a date (utc midnight) reflecting the value of myDate and the environment's timezone offset.
new Date(Date.UTC(myDate.getFullYear(),myDate.getMonth(), myDate.getDate()));

Manchmal übertrifft die internationale Vergleichbarkeit die lokale Genauigkeit. In diesem Fall sollten Sie dies tun...

// the date in London of a moment in time. Device timezone is ignored.
new Date(Date.UTC(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate()));

Deserialisieren eines Datums

Häufig werden die Daten auf der Leitung im Format JJJJ-MM-TT angegeben. Um sie zu deserialisieren, tun Sie Folgendes...

var midnightUTCDate = new Date( dateString + 'T00:00:00Z');

Serialisierung

Nachdem Sie bei der Erstellung darauf geachtet haben, die Zeitzone zu verwalten, müssen Sie nun sicherstellen, dass die Zeitzone bei der Rückkonvertierung in eine String-Darstellung nicht berücksichtigt wird. So können Sie sicher verwenden...

  • toISOString()
  • getUTCxxx()
  • getTime() //returns a number with no time or timezone.
  • .toLocaleDateString("fr",{timeZone:"UTC"}) // whatever locale you want, but ALWAYS UTC.

Und vermeiden Sie alles andere, vor allem...

  • getYear() , getMonth() , getDate()

Um also Ihre Frage zu beantworten: 7 Jahre zu spät...

<input type="date" onchange="isInPast(event)">
<script>
var isInPast = function(event){
  var userEntered = new Date(event.target.valueAsNumber); // valueAsNumber has no time or timezone!
  var now = new Date();
  var today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() ));
  if(userEntered.getTime() < today.getTime())
    alert("date is past");
  else if(userEntered.getTime() == today.getTime())
    alert("date is today");
  else
    alert("date is future");

}
</script>

Sehen Sie es laufen...

Update 2019... kostenlose Sachen...

In Anbetracht der Beliebtheit dieser Antwort habe ich alles in Code geschrieben. Die folgende Funktion gibt ein umhülltes Datumsobjekt zurück und stellt nur die Funktionen zur Verfügung, die sicher mit just-a-date™ verwendet werden können.

Rufen Sie es mit einem Date-Objekt auf, und es wird in JustADate aufgelöst, das die Zeitzone des Benutzers widerspiegelt. Aufruf mit einer Zeichenkette: Wenn die Zeichenkette eine ISO 8601-Zeichenkette mit angegebener Zeitzone ist, wird nur der Zeitteil abgerundet. Wenn die Zeitzone nicht angegeben ist, wird sie in ein Datum konvertiert, das die lokale Zeitzone widerspiegelt, genau wie bei Datumsobjekten.

function JustADate(initDate){
  var utcMidnightDateObj = null
  // if no date supplied, use Now.
  if(!initDate)
    initDate = new Date();

  // if initDate specifies a timezone offset, or is already UTC, just keep the date part, reflecting the date _in that timezone_
  if(typeof initDate === "string" && initDate.match(/((\+|-)\d{2}:\d{2}|Z)$/gm)){  
     utcMidnightDateObj = new Date( initDate.substring(0,10) + 'T00:00:00Z');
  } else {
    // if init date is not already a date object, feed it to the date constructor.
    if(!(initDate instanceof Date))
      initDate = new Date(initDate);
      // Vital Step! Strip time part. Create UTC midnight dateObj according to local timezone.
      utcMidnightDateObj = new Date(Date.UTC(initDate.getFullYear(),initDate.getMonth(), initDate.getDate()));
  }

  return {
    toISOString:()=>utcMidnightDateObj.toISOString(),
    getUTCDate:()=>utcMidnightDateObj.getUTCDate(),
    getUTCDay:()=>utcMidnightDateObj.getUTCDay(),
    getUTCFullYear:()=>utcMidnightDateObj.getUTCFullYear(),
    getUTCMonth:()=>utcMidnightDateObj.getUTCMonth(),
    setUTCDate:(arg)=>utcMidnightDateObj.setUTCDate(arg),
    setUTCFullYear:(arg)=>utcMidnightDateObj.setUTCFullYear(arg),
    setUTCMonth:(arg)=>utcMidnightDateObj.setUTCMonth(arg),
    addDays:(days)=>{
      utcMidnightDateObj.setUTCDate(utcMidnightDateObj.getUTCDate + days)
    },
    toString:()=>utcMidnightDateObj.toString(),
    toLocaleDateString:(locale,options)=>{
      options = options || {};
      options.timeZone = "UTC";
      locale = locale || "en-EN";
      return utcMidnightDateObj.toLocaleDateString(locale,options)
    }
  }
}

// if initDate already has a timezone, we'll just use the date part directly
console.log(JustADate('1963-11-22T12:30:00-06:00').toLocaleDateString())

5 Stimmen

Ihre Antwort enthält wirklich wertvolle Informationen! Leider haben Sie die Antwort nicht in die eigentliche Frage des Auftraggebers eingefügt, was mich daran hindert, sie hochzustufen. Versuchen Sie, einen kleinen Codeschnipsel hinzuzufügen, der die Frage des Auftraggebers beantwortet.

2 Stimmen

Ha ha ha @ '7 Jahre zu spät'! Ich mag deinen Stil user1585345! Du hast meine Stimme!

0 Stimmen

Ich fand dies sehr hilfreich. Beachten Sie, dass sich im Abschnitt "Internationale Vergleichbarkeit" ein Tippfehler befindet. Ich denke, es sollte sein: new Date(Date.UTC(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate()));

103voto

AdEpt Punkte 1015

Wie wäre es damit?

Date.prototype.withoutTime = function () {
    var d = new Date(this);
    d.setHours(0, 0, 0, 0);
    return d;
}

Auf diese Weise können Sie den Datumsteil des Datums vergleichen, ohne den Wert Ihrer Variablen zu beeinflussen:

var date1 = new Date(2014,1,1);
new Date().withoutTime() > date1.withoutTime(); // true

0 Stimmen

Dies ist bei weitem die eleganteste Antwort auf den ursprünglichen Beitrag. Ich habe keine separate Funktion für meine Zwecke erstellt, sondern nur die beiden Codezeilen eingefügt.

4 Stimmen

Das Hinzufügen von benutzerdefinierten Funktionen zum Prototyp ist keine so gute Idee.

4 Stimmen

Warum @andrey.shedko? Zu sagen, dass etwas eine schlechte Idee oder der falsche Weg ist, ohne dies zu begründen, ist für alle schlecht. Wenn es funktioniert und etwas ist, das Sie in Ihrem Projekt wiederverwenden und Ihnen wiederholtes manuelles Beschneiden ersparen können, dann funktioniert es gut und ist gut zu verwenden.

29voto

Joshua Pinter Punkte 41335

Verwendung von Moment.js

Wenn Sie die Möglichkeit haben, eine Bibliothek eines Drittanbieters einzubinden, lohnt es sich auf jeden Fall, einen Blick darauf zu werfen Moment.js . Es macht die Arbeit mit Date y DateTime viel, viel einfacher.

Um zum Beispiel zu sehen, ob ein Datum nach einem anderen Datum kommt, aber ohne deren Zeiten, würden Sie etwa so vorgehen:

var date1 = new Date(2016,9,20,12,0,0); // October 20, 2016 12:00:00
var date2 = new Date(2016,9,20,12,1,0); // October 20, 2016 12:01:00

// Comparison including time.
moment(date2).isAfter(date1); // => true

// Comparison excluding time.
moment(date2).isAfter(date1, 'day'); // => false

Der zweite Parameter, den Sie an isAfter ist die Genauigkeit, mit der der Vergleich durchgeführt wird, und kann einer der folgenden Werte sein year , month , week , day , hour , minute o second .

6 Stimmen

Ich habe eine 100-fache Beschleunigung beim Wechsel von einer momentjs-Lösung zu einer Date() + sethours-Lösung.)

0 Stimmen

@2c2c Interessant. Es ist auf jeden Fall gut, die Auswirkungen auf die Leistung zu kennen. Wie viele Operationen haben Sie für Ihren Benchmark verwendet?

1 Stimmen

Ich war bei etwa 1 Million Vergleichen. Ich habe keinen aktuellen Benchmark erstellt.

26voto

Rahi Punkte 289

Vergleichen Sie einfach mit .toDateString wie unten:

new Date().toDateString();

Damit erhalten Sie nur das Datum, nicht aber die Uhrzeit oder die Zeitzone, etwa so:

"Fri Feb 03 2017"

Daher können beide Daten in diesem Format ebenfalls ohne Zeitanteil verglichen werden.

4 Stimmen

Das ist ein guter Anfang, ermöglicht aber keine Vergleiche, da es sich jetzt um eine Zeichenkette handelt. Um zu vergleichen, ändern Sie es zurück in ein Date-Objekt, indem Sie new Date(new Date().toDateString());

2 Stimmen

@GridTrekkor Stimmt, aber wenn Sie nur einen schnellen Gleichheitstest durchführen wollen, ist dies die einfachste Lösung.

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