Dodawanie godzin do obiektu JavaScript Data?

399

Dziwi mnie, że obiekt Date JavaScript nie implementuje żadnej funkcji dodawania.

Chcę po prostu funkcji, która może to zrobić:

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

function Date.prototype.addHours(h) {

   // how do I implement this?  

}

Chciałbym tylko kilka wskazówek w jednym kierunku.

  • Czy muszę parsować ciągi znaków?

  • Czy mogę używać setTime?

  • Co powiesz na milisekundy?

Lubię to:

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

Wydaje się to jednak naprawdę hackerskie - i czy to w ogóle działa?

Jeff Meatball Yang
źródło

Odpowiedzi:

422

Sam JavaScript ma okropne API Data / Czas. Niemniej jednak możesz to zrobić w czystym JavaScript:

Date.prototype.addHours = function(h) {
  this.setTime(this.getTime() + (h*60*60*1000));
  return this;
}
Jason Harwig
źródło
Działa jak marzenie! Dziękuję
moreirapontocom
jeśli powiedzmy, że dodajesz godzinę powodującą, że przesuwa się ona na następny dzień, czy to złapie i zwiększy wszystko poprawnie (dzień miesiąc rok)?
cdoern
@cdoern Myślę, że tak, ponieważ getTime () zwróci milisekundy, a ty po prostu dodajesz do tego więcej milisekund
The1993
370
Date.prototype.addHours= function(h){
    this.setHours(this.getHours()+h);
    return this;
}

Test:

alert(new Date().addHours(4));
Kennebec
źródło
25
Nie sądzę, żeby to działało - przetestować to na przykład na godzinie 23? Odpowiedzią Jasona Harwiga jest to, co przyszło mi do głowy.
Domenic,
11
Złą praktyką jest dodawanie elementów do prototypu obiektu w JavaScript, a Domenic ma rację, to nie działa. Rozwiązanie Jasona Harwiga poniżej jest lepsze.
iKode,
19
@Domenic Działa to dobrze z 23:00, przetestowane w konsoli JavaScript Firefox 10, Chrome 21 i IE 8/9 Oto kod, którego użyłem do testowania: 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) Działa również dobrze z setMinutes ()
tanguy_k
4
Wystąpiły problemy z tym rozwiązaniem - Zwiększenie o 1 nie powiodło się dla mnie w punkcie zmiany czasu letniego (przesuń zegar do przodu o godzinę).
andrewb
2
Ugryzł mnie również ten - zapętlałem godziny używając setHours (getHours-1): teraz, przy pierwszej godzinie DST, kończy się to nieskończoną pętlą. Sprawdź wynik!
cfstras
165

Poniższy kod ma dodać 4 godziny do tej pory (przykład dzisiejszej daty)

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

Nie spowoduje błędu, jeśli spróbujesz dodać 4 do 23 (zobacz dokumenty ):

Jeśli określony parametr jest poza oczekiwanym zakresem, setHours () próbuje odpowiednio zaktualizować informacje o dacie w obiekcie Date

SuperNova
źródło
Nie widziałem tego i podwoiłem odpowiedź. Podoba mi się ta metoda. Precyzyjne i przydatne.
Gandalf Biały
Wydaje się, że to nie działa, gdy godziny są dziesiętne (nie liczba całkowita)
gregmagdits
3
To najlepsza odpowiedź tutaj ... dodanie „addHours” do prototypu Date jest niepokojące, ponieważ w pewnym momencie JS może dodać obsługę tej funkcji, a następnie masz konfliktowy prototyp. Zapewnia to funkcjonalność przy użyciu prawie tyle samo kodu.
Kris Boyd
zaskoczony, ale tak naprawdę zwiększa dni, miesiące, jeśli będzie to potrzebne, przydatny byłby link do dokumentów
2oppin
4
Chociaż stosowanie wartości godzin> 23 nie psuje tego, jest ono jednak łamane na granicach czasu letniego . Biorąc pod uwagę, że jest zepsuty, nie ma powodu, aby go używać; wolę setTimelub setUTCHour.
Mark Amery
40

Prawdopodobnie lepiej jest uczynić metodę addHours niezmienną, zwracając kopię obiektu Date, zamiast mutować jego parametr.

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

W ten sposób możesz połączyć wiele wywołań metod bez martwienia się o stan.

Tahir Hassan
źródło
Ta funkcja ma te same problemy, co podane tutaj stackoverflow.com/questions/1050720/… Nie chodzi o to, czy działa w niektórych przeglądarkach, ale w innych miejscach, w których używa się Javascript, to problem. czesanie twojego rozwiązania z tym jednym stackoverflow.com/a/1050782/295535 wydaje się być najlepszym rozwiązaniem
Ressu,
1
Należy rozważyć zmianę nazwy funkcji, ponieważ słowo add*to jest powszechnie używane do mutowania samego obiektu.
mr5
@ mr5 - nie jestem pewien, addjest często używany w DateTimeklasie frameworka .NET i ma takie samo znaczenie jak +(plus) w matematyce.
Tahir Hassan
1
currentDate.addHours(1)<- Z mojego instynktu programistycznego oczekuję, że currentDatewartość się zmieni, ale w twojej implementacji tak się nie stanie. Co do tego, dlaczego sugeruję zmienić nazwę lub zmienić jej podpis na coś
mr5
1
@TahirHassan nie ma nic wspólnego ze szczegółami technicznymi, ale z wyborem odpowiedniego słowa dla nazwy funkcji. Nadal wolę wersję add
zmienną,
23

Wersja sugerowana przez kennebec nie powiedzie się przy zmianie na lub z czasu letniego, ponieważ jest to ustawiony numer godziny.

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

doda hgodziny do thisosobliwości systemu czasu. Metoda Jasona Harwiga również działa.

Peter
źródło
19

Możesz skorzystać z biblioteki momentjs http://momentjs.com/ Library.

var moment = require('moment');
foo = new moment(something).add(10, 'm').toDate();
Cmag
źródło
7

Myślę również, że oryginalny obiekt nie powinien być modyfikowany. Aby więc uratować przyszłą siłę roboczą, oto połączone rozwiązanie oparte na odpowiedziach Jasona Harwiga i Tahira Hasana :

Date.prototype.addHours= function(h){
    var copiedDate = new Date();
    copiedDate.setTime(this.getTime() + (h*60*60*1000)); 
    return copiedDate;
}
Edward Olamisan
źródło
5

W bibliotece Datejs znajduje się dodatek .

A oto metody daty JavaScript . kennebec mądrze wspominał getHours () i setHours ();

Nosredna
źródło
Zauważ, że ta biblioteka wydaje się mieć status alfa.
Sam
4

Sprawdź, czy nie jest jeszcze zdefiniowany, w przeciwnym razie zdefiniuje go w prototypie Data:

if (!Date.prototype.addHours) {
    Date.prototype.addHours = function(h) {
        this.setHours(this.getHours() + h);
        return this;
    };
}
Mikael Engver
źródło
3

Innym sposobem na poradzenie sobie z tym jest przekonwertowanie daty na czas uniksowy (epoka), następnie dodanie ekwiwalentu za (mili) sekundy, a następnie konwersja z powrotem. W ten sposób możesz obsługiwać przejścia dnia i miesiąca, na przykład dodając 4 godziny do 21, co powinno skutkować następnego dnia, 01:00.

SPRBRN
źródło
Masz rację - ale spóźniasz się również o kilka lat. Odpowiedź Jasona Harwiga pokazała tę metodę 2 lata przed tobą; ta odpowiedź nie dodaje nic nowego.
Mark Amery
3

Aby uzyskać prostą funkcję dodawania / odejmowania godziny / minuty w javascript, spróbuj tego:

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);
};

Można tego użyć bez parametrów, aby uzyskać bieżący czas

getTime();

lub z parametrami, aby uzyskać czas z dodanymi minutami / godzinami

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

działa nawet czas ujemny

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

ta funkcja zwraca tablicę

array([Hour], [Minute], [Meridian])
durkinza
źródło
Jaką przewagę ma ten 56-liniowy potwór funkcji nad dwuliniowym podejściem w najczęściej głosowanej odpowiedzi ? -1, ponieważ istnieje tutaj ogromna dodatkowa złożoność, bez widocznej korzyści.
Mark Amery
1

SPRBRN jest poprawny. Aby uwzględnić początek / koniec miesiąca i roku, musisz przejść na Epokę iz powrotem.

Oto jak to zrobić:

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


lub zrób to w jednym wierszu (gdzie nazwy zmiennych są takie same jak powyżej:

var newDate = 
    new Date(startDate.getTime() + millisecond + 
        1000 * (sec + 60 * (min + 60 * (hours + 24 * days))));
JED
źródło
0

Jest to prosty sposób na uzyskanie zwiększonej lub zmniejszonej wartości danych.

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
źródło
-1

Trochę bałagan, ale działa!

Biorąc pod uwagę taki format daty: 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+"");

Twój wynik wyniósłby: 2019-04-03T16: 58

Carl Du Plessis
źródło