Hinzufügen von Stunden zum JavaScript-Datumsobjekt?

399

Es wundert mich, dass das Date-Objekt von JavaScript keinerlei Add-Funktion implementiert.

Ich möchte einfach eine Funktion, die dies kann:

var now = Date.now();
var fourHoursLater = now.addHours(4);

function Date.prototype.addHours(h) {

   // how do I implement this?  

}

Ich möchte einfach ein paar Hinweise in eine Richtung.

  • Muss ich String-Parsing durchführen?

  • Kann ich setTime verwenden?

  • Wie wäre es mit Millisekunden?

So was:

new Date(milliseconds + 4*3600*1000 /*4 hrs in ms*/)?  

Das scheint aber wirklich hackisch - und funktioniert es überhaupt?

Jeff Fleischbällchen Yang
quelle

Antworten:

423

JavaScript selbst hat schreckliche Datums- / Zeit-APIs. Sie können dies jedoch in reinem JavaScript tun:

Date.prototype.addHours = function(h) {
  this.setTime(this.getTime() + (h*60*60*1000));
  return this;
}
Jason Harwig
quelle
Klappt wunderbar! Vielen Dank
moreirapontocom
Wenn Sie pro Stunde eine Stunde hinzufügen würden, um sie auf den nächsten Tag zu übertragen, würde dies sie dann fangen und alles richtig erhöhen (Tag, Monat, Jahr)?
14.
@cdoern Ich denke, es würde, da getTime () Millisekunden zurückgibt und Sie nur weitere Millisekunden hinzufügen
The1993
370
Date.prototype.addHours= function(h){
    this.setHours(this.getHours()+h);
    return this;
}

Prüfung:

alert(new Date().addHours(4));
kennebec
quelle
25
Ich glaube nicht, dass das funktioniert - testen Sie es zum Beispiel mit Stunde 23? Die Antwort von Jason Harwig kam mir in den Sinn.
Domenic
11
Es ist eine schlechte Praxis, einem Objektprototyp in Javascript Dinge hinzuzufügen, und Domenic ist korrekt, dies funktioniert nicht. Die unten stehende Lösung von Jason Harwig ist besser.
iKode
19
@Domenic Dies funktioniert gut mit 23:00, getestet in der JavaScript-Konsole von Firefox 10, Chrome 21 und IE 8/9. Hier der Code, den ich zum Testen verwendet habe: var date = new Date(2012, 10, 22, 23, 0, 1); date.toString(); // Thu Nov 22 2012 23:00:01 GMT+0100 (CET) date.setHours(date.getHours() + 1); date.toString(); // Fri Nov 23 2012 00:00:01 GMT+0100 (CET) Es funktioniert auch gut mit setMinutes ()
tanguy_k
4
Bei dieser Lösung sind Probleme aufgetreten. Die Inkrementierung um 1 ist am Sommerzeit-Umschaltpunkt für mich fehlgeschlagen (Uhr eine Stunde vorwärts stellen).
Andrewb
2
Auch das hat mich gebissen - ich habe Stunden mit setHours (getHours-1) durchlaufen: Jetzt, in der ersten Sommerzeit, ist dies eine Endlosschleife. Überprüfen Sie also das Ergebnis!
CFstras
165

Der folgende Code dient zum Hinzufügen von 4 Stunden zum Datum (Beispiel des heutigen Datums).

var today = new Date();
today.setHours(today.getHours() + 4);

Es wird kein Fehler verursacht, wenn Sie versuchen, 4 bis 23 hinzuzufügen (siehe Dokumentation ):

Wenn ein von Ihnen angegebener Parameter außerhalb des erwarteten Bereichs liegt, versucht setHours (), die Datumsinformationen im Date-Objekt entsprechend zu aktualisieren

SuperNova
quelle
Ich habe das nicht gesehen und eine doppelte Antwort gegeben. Ich mag diese Methode. Präzise und nützlich.
Gandalf der Weiße
Dies scheint nicht zu funktionieren, wenn die Stunden eine Dezimalzahl (keine Ganzzahl) sind
Gregmagdits
3
Dies ist hier die beste Antwort. Das Hinzufügen von "addHours" zum Date-Prototyp ist besorgniserregend, da JS diese Funktion möglicherweise irgendwann unterstützt und Sie dann einen widersprüchlichen Prototyp haben. Dadurch erhalten Sie eine Funktionalität, bei der Sie genau so viel Code verwenden.
Kris Boyd
überrascht, aber es erhöht tatsächlich Tage, Monate, wenn es benötigt wird, Link zu den Dokumenten wäre nützlich
2oppin
4
Die Verwendung von Stundenwerten> 23 unterbricht dies zwar nicht, ist jedoch an den Grenzen der Sommerzeit unterbrochen . Da es kaputt ist, gibt es keinen Grund, es zu benutzen. bevorzugen setTimeoder setUTCHour.
Mark Amery
40

Es ist wahrscheinlich besser, die addHours-Methode unveränderlich zu machen, indem Sie eine Kopie des Date-Objekts zurückgeben, als dessen Parameter zu mutieren.

Date.prototype.addHours= function(h){
    var copiedDate = new Date(this.getTime());
    copiedDate.setHours(copiedDate.getHours()+h);
    return copiedDate;
}

Auf diese Weise können Sie eine Reihe von Methodenaufrufen verketten, ohne sich um den Status kümmern zu müssen.

Tahir Hassan
quelle
Diese Funktion hat die gleichen Probleme wie hier angegeben. Stackoverflow.com/questions/1050720/… Es geht nicht wirklich darum, ob sie in bestimmten Browsern funktioniert, aber an anderen Orten, die Javascript verwenden, wird dies als Problem angesehen. Das Kämmen Ihrer Lösung mit diesem einen stackoverflow.com/a/1050782/295535 scheint die beste Lösung zu sein
Ressu
1
Sie sollten in Betracht ziehen, den Funktionsnamen zu ändern, da das Wort add*häufig zum Mutieren des Objekts selbst verwendet wird.
Mr5 5.
@ mr5 - da bin ich mir nicht sicher, addwird häufig in der .NET Framework- DateTimeKlasse verwendet und hat die gleiche Bedeutung wie das +(Plus) in Math.
Tahir Hassan
1
currentDate.addHours(1)<- Aus meinem Programmierinstinkt erwarte ich, dass sich der currentDateWert ändert, in Ihrer Implementierung jedoch nicht. Warum
schlage
1
@TahirHassan hat nichts mit den technischen Details zu tun, sondern mit der Auswahl des richtigen Wortes für den Funktionsnamen. Ich bevorzuge immer noch die veränderbare Version, wenn der Funktionadd
mr5
23

Die von kennebec vorgeschlagene Version schlägt beim Wechsel von oder zu DST fehl, da die eingestellte Stundennummer festgelegt ist.

this.setUTCHours(this.getUTCHours()+h);

wird unabhängig von den Besonderheiten des Zeitsystems hStunden hinzufügen this. Die Methode von Jason Harwig funktioniert ebenfalls.

petter
quelle
19

Sie können die Bibliothek momentjs http://momentjs.com/ verwenden .

var moment = require('moment');
foo = new moment(something).add(10, 'm').toDate();
Cmag
quelle
7

Ich denke auch, dass das ursprüngliche Objekt nicht geändert werden sollte. Um zukünftige Arbeitskräfte zu sparen, gibt es hier eine kombinierte Lösung, die auf den Antworten von Jason Harwig und Tahir Hasan basiert :

Date.prototype.addHours= function(h){
    var copiedDate = new Date();
    copiedDate.setTime(this.getTime() + (h*60*60*1000)); 
    return copiedDate;
}
Edward Olamisan
quelle
5

Es gibt ein Add in den Datejs Bibliothek.

Und hier sind die JavaScript-Datumsmethoden . kennebec erwähnte weise getHours () und setHours ();

Nosredna
quelle
Beachten Sie, dass sich diese Bibliothek anscheinend im Alpha-Status befindet.
Sam
4

Überprüfen Sie, ob es nicht bereits definiert ist. Andernfalls wird es im Date-Prototyp definiert:

if (!Date.prototype.addHours) {
    Date.prototype.addHours = function(h) {
        this.setHours(this.getHours() + h);
        return this;
    };
}
Mikael Engver
quelle
3

Eine andere Möglichkeit, dies zu handhaben, besteht darin, das Datum in Unixtime (Epoche) zu konvertieren, dann das Äquivalent in (Milli) Sekunden hinzuzufügen und es dann zurück zu konvertieren. Auf diese Weise können Sie Tag- und Monatsübergänge verarbeiten, z. B. 4 bis 21 Stunden hinzufügen, was am nächsten Tag, 01:00 Uhr, erfolgen sollte.

SPRBRN
quelle
Du hast recht - aber du bist auch ein paar Jahre zu spät. Die Antwort von Jason Harwig zeigte diese Methode 2 Jahre vor Ihnen; Diese Antwort fügt nichts Neues hinzu.
Mark Amery
3

Versuchen Sie Folgendes, um eine einfache Funktion zum Hinzufügen / Entfernen von Stunden / Minuten in Javascript zu erhalten:

function getTime (addHour, addMin){
    addHour = (addHour?addHour:0);
    addMin = (addMin?addMin:0);
    var time = new Date(new Date().getTime());
    var AM = true;
    var ndble = 0;
    var hours, newHour, overHour, newMin, overMin;
    //change form 24 to 12 hour clock
    if(time.getHours() >= 13){
        hours = time.getHours() - 12;
        AM = (hours>=12?true:false);
    }else{
        hours = time.getHours();
        AM = (hours>=12?false:true);
    }
    //get the current minutes
    var minutes = time.getMinutes();
    // set minute
    if((minutes+addMin) >= 60 || (minutes+addMin)<0){
        overMin = (minutes+addMin)%60;
        overHour = Math.floor((minutes+addMin-Math.abs(overMin))/60);
        if(overMin<0){
            overMin = overMin+60;
            overHour = overHour-Math.floor(overMin/60);
        }
        newMin = String((overMin<10?'0':'')+overMin);
        addHour = addHour+overHour;
    }else{
        newMin = minutes+addMin;
        newMin = String((newMin<10?'0':'')+newMin);
    }
    //set hour
    if(( hours+addHour>=13 )||( hours+addHour<=0 )){
        overHour = (hours+addHour)%12;
        ndble = Math.floor(Math.abs((hours+addHour)/12));
        if(overHour<=0){
            newHour = overHour+12;
            if(overHour == 0){
                ndble++;
            }
        }else{
            if(overHour ==0 ){
                newHour = 12;
                ndble++;
            }else{
                ndble++;
                newHour = overHour;
            }
        }
        newHour = (newHour<10?'0':'')+String(newHour);
        AM = ((ndble+1)%2===0)?AM:!AM;
    }else{
        AM = (hours+addHour==12?!AM:AM);
        newHour = String((Number(hours)+addHour<10?'0':'')+(hours+addHour));
    }
    var am = (AM)?'AM':'PM';
    return new Array(newHour, newMin, am);
};

Dies kann ohne Parameter verwendet werden, um die aktuelle Zeit abzurufen

getTime();

oder mit Parametern, um die Zeit mit den hinzugefügten Minuten / Stunden zu erhalten

getTime(1,30); // adds 1.5 hours to current time
getTime(2);    // adds 2 hours to current time
getTime(0,120); // same as above

Auch negative Zeit funktioniert

getTime(-1, -30); // subtracts 1.5 hours from current time

Diese Funktion gibt ein Array von zurück

array([Hour], [Minute], [Meridian])
Durkinza
quelle
Welchen Vorteil hat dieses 56-zeilige Monster einer Funktion gegenüber dem zweizeiligen Ansatz in der Antwort mit der höchsten Abstimmung ? -1, weil es hier eine enorme zusätzliche Komplexität gibt, ohne dass ich einen Nutzen sehen kann.
Mark Amery
1

SPRBRN ist korrekt. Um den Anfang / das Ende des Monats und des Jahres zu berücksichtigen, müssen Sie in Epoche und zurück konvertieren.

So machen Sie das:

var milliseconds = 0;          //amount of time from current date/time
var sec = 0;                   //(+): future
var min = 0;                   //(-): past
var hours = 2;
var days = 0;

var startDate = new Date();     //start date in local time (we'll use current time as an example)

var time = startDate.getTime(); //convert to milliseconds since epoch

//add time difference
var newTime = time + milliseconds + (1000*sec) + (1000*60*min) + (1000*60*60*hrs) + (1000*60*60*24)

var newDate = new Date(newTime);//convert back to date; in this example: 2 hours from right now


oder machen Sie es in einer Zeile (wobei die Variablennamen die gleichen wie oben sind:

var newDate = 
    new Date(startDate.getTime() + millisecond + 
        1000 * (sec + 60 * (min + 60 * (hours + 24 * days))));
JED
quelle
0

Dies ist eine einfache Möglichkeit, inkrementierte oder dekrementierte Datenwerte zu erhalten.

const date = new Date()
const inc = 1000 * 60 * 60 // an hour
const dec = (1000 * 60 * 60) * -1 // an hour

const _date = new Date(date)
return new Date( _date.getTime() + inc )
return new Date( _date.getTime() + dec )
Henrique Van Klaveren
quelle
-1

Ein bisschen chaotisch, aber es funktioniert!

Bei einem Datumsformat wie diesem: 2019-04-03T15: 58

  //Get the start date.
  var start = $("#start_date").val();
  //Split the date and time.
  var startarray = start.split("T");
  var date = startarray[0];
  var time = startarray[1];

  //Split the hours and minutes.
  var timearray = time.split(":");

  var hour = timearray[0];
  var minute = timearray[1];
  //Add an hour to the hour.
  hour++;
  //$("#end_date").val = start;
  $("#end_date").val(""+date+"T"+hour+":"+minute+"");

Ihre Ausgabe wäre: 2019-04-03T16: 58

Carl Du Plessis
quelle