Hüten Sie sich vor der Zeitzone
Wenn Sie das Datumsobjekt verwenden, um nur ein Datum sofort darzustellen, geraten Sie in ein großes Problem mit übermäßiger Genauigkeit. Sie müssen Zeit und Zeitzone verwalten, um sie fernzuhalten, und sie können sich jederzeit wieder einschleichen. Die akzeptierte Antwort auf diese Frage fällt in die Falle.
Ein Javascript-Datum kennt keine Zeitzone . Es ist ein Moment in der Zeit (Ticks seit der Epoche) mit praktischen (statischen) Funktionen zum Übersetzen in und aus Zeichenfolgen, wobei standardmäßig die "lokale" Zeitzone des Geräts oder, falls angegeben, UTC oder eine andere Zeitzone verwendet wird. Um nur ein Datum ™ mit einem Datumsobjekt darzustellen , möchten Sie, dass Ihre Daten UTC Mitternacht zu Beginn des betreffenden Datums darstellen. Dies ist eine übliche und notwendige Konvention, mit der Sie unabhängig von der Jahreszeit oder der Zeitzone ihrer Erstellung mit Daten arbeiten können. Sie müssen also sehr wachsam sein, um den Begriff der Zeitzone zu verwalten, sowohl beim Erstellen Ihres Mitternachts-UTC-Datumsobjekts als auch beim Serialisieren.
Viele Leute sind durch das Standardverhalten der Konsole verwirrt. Wenn Sie ein Datum auf die Konsole sprühen, enthält die angezeigte Ausgabe Ihre Zeitzone. Dies liegt nur daran, dass die Konsole toString()
Ihr Datum anruft und toString()
Ihnen eine lokale Vertretung bietet. Das zugrunde liegende Datum hat keine Zeitzone ! (Solange die Zeit mit dem Zeitzonenversatz übereinstimmt, haben Sie immer noch ein Mitternachts-UTC-Datumsobjekt.)
Deserialisieren (oder Erstellen von UTC-Datumsobjekten um Mitternacht)
Dies ist der Rundungsschritt mit dem Trick, dass es zwei "richtige" Antworten gibt. In den meisten Fällen soll Ihr Datum die Zeitzone des Benutzers widerspiegeln. Klicken Sie, wenn heute Ihr Geburtstag ist . Benutzer in Neuseeland und den USA klicken gleichzeitig und erhalten 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 tun Sie dies ...
// the date in London of a moment in time. Device timezone is ignored.
new Date(Date.UTC(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate()));
Deserialisieren Sie ein Datum
Oft haben Daten auf dem Draht das Format JJJJ-MM-TT. Um sie zu deserialisieren, tun Sie dies ...
var midnightUTCDate = new Date( dateString + 'T00:00:00Z');
Serialisierung
Nachdem Sie beim Erstellen darauf geachtet haben, die Zeitzone zu verwalten, müssen Sie jetzt sicherstellen, dass die Zeitzone beim Zurückkonvertieren in eine Zeichenfolgendarstellung nicht angezeigt 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, besonders ...
getYear()
, getMonth()
,getDate()
Um 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 ...
Angesichts der Popularität dieser Antwort habe ich alles in Code eingefügt. Die folgende Funktion gibt ein umschlossenes Datumsobjekt zurück und macht nur die Funktionen verfügbar, die mit just-a-date ™ sicher 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. Nennen Sie es mit einer Zeichenfolge: Wenn es sich bei der Zeichenfolge um eine ISO 8601 mit angegebener Zeitzone handelt, runden wir den Zeitteil ab. Wenn keine Zeitzone angegeben ist, konvertieren wir sie in ein Datum, das die lokale Zeitzone widerspiegelt, genau wie für Datumsobjekte.
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())
date1 === date2
kein konsistentes Verhalten zu bieten scheint. es ist besser zu tundate1.valueOf() === b.valueOf()
oder sogardate1.getTime() === date2.getTime()
. Fremdheit.