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?

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

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

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


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.


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.


19

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

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

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


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

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.


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])

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

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 )

-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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.