Jak dodać 30 minut do obiektu daty JavaScript?


783

Chciałbym uzyskać obiekt Date, który jest 30 minut później niż inny obiekt Date. Jak to zrobić za pomocą JavaScript?


1
Zbudowałem mały skrypt wyskakujący kalendarza w js, na Githubie , może przejrzyj kod, aby zobaczyć, jak interektowany jest obiekt daty. Sprawdź także JavaScript Kit jako niesamowite odniesienie do js, ​​szczególnie dla obiektu date.
Christian

2
Wszystkie poniższe odpowiedzi wykorzystujące odmianę date.setMinutes(date.getMinutes() + ...)nie przekroczą granic czasu letniego. Na przykład (zakładając, że „2014-03-09” jest granicą czasu letniego): var d = new Date('2014-03-09 01:59:00'), f = new Date(d.getTime()); d.setMinutes(d.getMinutes() + 30); djest teraz 30 minut wcześniej, nie później niż f.
Spig

1
@Spig: 30 minut po 01:59 na granicy DST jest 01:29. Nie ma błędu. W przypadku drukowania fi dzobaczysz jeden mówi „GMT-0500” drugi mówi „GMT-0400” (lub cokolwiek jest strefa czasowa). Ponadto, jeśli włączysz .getTime()oba fi d, zobaczysz, że fjest większy niż d(tj. Później).
Kip

1
@Spig: ciekawe, wypróbowałem to na Firefoxie i działało. Myślę, że wpada w szary obszar w specyfikacji sposobu działania getMinutes (). 01:89stałby się 02:29, co nie istnieje w dniu, w którym „skaczesz do przodu”. Chrome decyduje, że tak powinno być 01:29, decyduje FF 03:29. W nocy, gdy „cofniesz się”, obie przeglądarki pomijają godzinę „cofania się” i przeskakują o 90 minut do przodu 02:29. Oto kilka wersji demonstracyjnych JSFiddle: „spring forward” / „fall back”
Kip

1
Jeśli jedna z poniższych odpowiedzi odpowiedziała na twoje pytanie, sposób działania tej witryny, „zaakceptujesz” odpowiedź, więcej tutaj: Co mam zrobić, gdy ktoś odpowie na moje pytanie? . Ale tylko jeśli twoje pytanie naprawdę zostało udzielone. Jeśli nie, rozważ dodanie więcej szczegółów do pytania.
Do widzenia StackExchange

Odpowiedzi:


950

Korzystanie z biblioteki

Jeśli wykonujesz dużo pracy związanej z datami, możesz zajrzeć do bibliotek dat JavaScript, takich jak Datejs lub Moment.js . Na przykład w przypadku Moment.js jest to po prostu:

var newDateObj = moment(oldDateObj).add(30, 'm').toDate();

Waniliowy Javascript

To odpowiedź chaosu , ale w jednym wierszu:

var newDateObj = new Date(oldDateObj.getTime() + diff*60000);

Gdzie diffjest różnica w minutach, którą chcesz od oldDateObjczasu. Może być nawet negatywny.

Lub jako funkcja wielokrotnego użytku, jeśli musisz to zrobić w wielu miejscach:

function addMinutes(date, minutes) {
    return new Date(date.getTime() + minutes*60000);
}

I na wypadek, gdyby nie było to oczywiste, mnożymy minuty przez 60000konwersję minut na milisekundy.

Uważaj na Vanilla Javascript. Daty są trudne!

Możesz pomyśleć, że możesz dodać 24 godziny do daty, aby uzyskać jutrzejszą datę, prawda? Źle!

addMinutes(myDate, 60*24); //DO NOT DO THIS

Okazuje się, że jeśli użytkownik zauważy czas letni, dzień niekoniecznie musi trwać 24 godziny. Jest jeden dzień w roku, który ma tylko 23 godziny, i jeden dzień w roku, który ma 25 godzin. Na przykład w większości Stanów Zjednoczonych i Kanady, 24 godziny po północy, 2 listopada 2014 r., Wciąż jest 2 listopada:

const NOV = 10; //because JS months are off by one...
addMinutes(new Date(2014, NOV, 2), 60*24); //In USA, prints 11pm on Nov 2, not 12am Nov 3!

Dlatego korzystanie z jednej z wyżej wymienionych bibliotek jest bezpieczniejszym wyborem, jeśli musisz dużo z tym zrobić.

Poniżej znajduje się bardziej ogólna wersja tej funkcji, którą napisałem. Nadal polecam korzystanie z biblioteki, ale może to być przesada / niemożliwe dla twojego projektu. Składnia jest modelowana na podstawie funkcji MySQL DATE_ADD .

/**
 * Adds time to a date. Modelled after MySQL DATE_ADD function.
 * Example: dateAdd(new Date(), 'minute', 30)  //returns 30 minutes from now.
 * https://stackoverflow.com/a/1214753/18511
 * 
 * @param date  Date to start with
 * @param interval  One of: year, quarter, month, week, day, hour, minute, second
 * @param units  Number of units of the given interval to add.
 */
function dateAdd(date, interval, units) {
  if(!(date instanceof Date))
    return undefined;
  var ret = new Date(date); //don't change original date
  var checkRollover = function() { if(ret.getDate() != date.getDate()) ret.setDate(0);};
  switch(String(interval).toLowerCase()) {
    case 'year'   :  ret.setFullYear(ret.getFullYear() + units); checkRollover();  break;
    case 'quarter':  ret.setMonth(ret.getMonth() + 3*units); checkRollover();  break;
    case 'month'  :  ret.setMonth(ret.getMonth() + units); checkRollover();  break;
    case 'week'   :  ret.setDate(ret.getDate() + 7*units);  break;
    case 'day'    :  ret.setDate(ret.getDate() + units);  break;
    case 'hour'   :  ret.setTime(ret.getTime() + units*3600000);  break;
    case 'minute' :  ret.setTime(ret.getTime() + units*60000);  break;
    case 'second' :  ret.setTime(ret.getTime() + units*1000);  break;
    default       :  ret = undefined;  break;
  }
  return ret;
}

Działające demo jsFiddle .


14
To jest bardzo potężne; Działa przez dowolną liczbę minut, nawet jeśli liczba była ujemna.
Wahid Bitar

3
Przez sekundy pomnóż przez 1000 zamiast 60k.
ashes999

2
Funkcja dateAdd () jest świetna! Ale jest jedna nuta ode mnie - semantycznie jednostka powinna wynosić „minuta”, „sekunda” itd., A interwał powinien być kwotą (2, 10, 45, ...), a nie odwrotnie. W przeciwnym razie pomysł jest dobry.
Wasil Popow

1
Ta odpowiedź nie uwzględnia przeniesień z miesiąca, więc 31 stycznia plus jeden miesiąc daje 2 lub 3 marca w zależności od tego, czy jest to rok przestępny, czy nie. Funkcje addMonths i addYears w odpowiedzi Jacobiego sobie z tym radzą, więc dla mnie jest to lepsza odpowiedź.
RobG

1
@RobG Dobra uwaga. Dodałem do tego poprawkę i dodatkowo podkreśliłem punkt „użyj biblioteki, jeśli to możliwe”.
Kip

237
var d1 = new Date ();
var d2 = new Date ( d1 );
d2.setMinutes ( d1.getMinutes() + 30 );
alert ( d2 );

114
@Jamie: Nie potrzebujesz dwóch Dateobiektów. var d = new Date(); d.setMinutes(d.getMinutes() + 30);
Grant Wagner

15
@Grant: Zakładałem, że d2 = "Chciałbym dostać obiekt Date", a d1 = "do innego obiektu Date"
Jamie

7
@CKeene, setMinutes i getMinutes są częścią zwykłego starego Javascript (chociaż datejs dostarcza całą masę innych rzeczy).
s29

4
Do Twojej wiadomości - może przekroczyć granice czasu letniego. Wersje demonstracyjne JSFiddle: „spring forward” / „fall back” (dzięki za @Spig za to)
Kip

@trevorgrayson Jeśli określony parametr jest poza oczekiwanym zakresem, setMinutes () próbuje odpowiednio zaktualizować informacje o dacie. Na przykład, jeśli użyjesz 100, godziny zostaną zwiększone o 1, a 40 zostanie wykorzystanych na minuty.
Mihai Crăiță

155

var oldDateObj = new Date();
var newDateObj = new Date();
newDateObj.setTime(oldDateObj.getTime() + (30 * 60 * 1000));
console.log(newDateObj);


3
Zwróć uwagę, że setTimezwraca numeryczny milisekundowy znacznik czasu, a nie obiekt daty. (Nie sądzę, że możesz zrobić jedno-linijkę.)
Alan H.

12
var in30Mins = new Date(+new Date() + 1.8e6)jest jedno-liniowy, ale nie jestem pewien, czy jest lepszy niż dwuwarstwowy. ;-)
RobG

112

var now = new Date();
now.setMinutes(now.getMinutes() + 30); // timestamp
now = new Date(now); // Date object
console.log(now);


9
Zauważyłem, że opublikowałem duplikat tego. Zamiast tego usunięto i dano +1.
Izzy

3
najprostsza odpowiedź na to pytanie
vijay

Myślę, że setMinuteszwraca znacznik czasu, ale nowpozostaje Dateobiektem, więc now = new Date(now)jest przestarzały
p.boiko

46

Może coś takiego?

var d = new Date();
var v = new Date();
v.setMinutes(d.getMinutes()+30);

console.log(v)


6
@ Chacha102: Nie potrzebujesz dwóch Dateobiektów. var d = new Date(); d.setMinutes(d.getMinutes() + 30);
Grant Wagner,

12
Chciał dwóch obiektów randkowych. Przeczytaj pytanie. Jeden obiekt daty, który jest 30 minut przed innym obiektem daty.
Tyler Carter

5
Czy to działa dobrze, jeśli zapętla się po godzinie? Więc jeśli zadzwonię o 11:59, to czy będzie w porządku o 12:29?
Chris Rae,

1
@ChrisRae tak, robi. If a parameter you specify is outside of the expected range, setMinutes() attempts to update the date information in the Date object accordingly.
fridoo

35

Zawsze tworzę 7 funkcji do pracy z datą w JS: addSeconds, addMinutes, addHours, addDays, addWeeks, addMonths, addYears.

Przykład możesz zobaczyć tutaj: http://jsfiddle.net/tiagoajacobi/YHA8x/

Jak używać:

var now = new Date();
console.log(now.addMinutes(30));
console.log(now.addWeeks(3));

Oto funkcje:

        Date.prototype.addSeconds = function(seconds) {
            this.setSeconds(this.getSeconds() + seconds);
            return this;
        };

        Date.prototype.addMinutes = function(minutes) {
            this.setMinutes(this.getMinutes() + minutes);
            return this;
        };

        Date.prototype.addHours = function(hours) {
            this.setHours(this.getHours() + hours);
            return this;
        };

        Date.prototype.addDays = function(days) {
            this.setDate(this.getDate() + days);
            return this;
        };

        Date.prototype.addWeeks = function(weeks) {
            this.addDays(weeks*7);
            return this;
        };

        Date.prototype.addMonths = function (months) {
            var dt = this.getDate();

            this.setMonth(this.getMonth() + months);
            var currDt = this.getDate();

            if (dt !== currDt) {  
                this.addDays(-currDt);
            }

            return this;
        };

        Date.prototype.addYears = function(years) {
            var dt = this.getDate();

            this.setFullYear(this.getFullYear() + years);

            var currDt = this.getDate();

            if (dt !== currDt) {  
                this.addDays(-currDt);
            }

            return this;
        };

Czy ktoś może zobaczyć jakiś problem z tym podejściem?
The Dembinski

1
zamiast tego użyj moment.js
Victor Pudeyev,

@ TheDembinski - jakich problemów oczekujesz? Rozszerzanie wbudowanych jest ogólnie nielubiane, ale nie widzę problemu z datą. Byłoby miło, gdyby każdy większy przyrost opcjonalnie ustawiał również swoje mniejsze przyrosty (jak robią to metody set * ), więc addHours opcjonalnie zajmowało minuty, sekundy i milisekundy, więc możesz date.addHours(3, 30)dodać 3 godziny i 30 minut. addYears zajmie lata, miesiące i dni, addMonth zajmie miesiące i dni, addMinutes zajmie minuty, sekundy, milisekundy itp.
RobG

1
Cześć @transformer Zrobiłbym coś takiego new Date().addHours(4).addMinutes(45);Możesz wywołać tyle, ile chcesz, ponieważ metody zwracają „this”, który jest bieżącym obiektem Date.
Jacobi,

1
Cześć @transformer, nie jestem pewien, czy zrozumiałem twój problem, ale są to funkcje prototypowe, możesz użyć w dowolnej kolejności, na przykład: var dt = new Date();wtedy, dt.addMinutes(45); dt.addHours(4);a nawet, dt.addMinutes(285);a nawet dt.addMinutes(45).addHours(4);wszystko będzie działać. Jeśli masz pytanie z jakimś przykładem kodu, napisz tutaj problem, chętnie Ci pomogę.
Jacobi

13

Najłatwiejszym sposobem rozwiązania jest rozpoznanie, że w javascript daty są tylko liczbami. Zaczyna się 0lub 'Wed Dec 31 1969 18:00:00 GMT-0600 (CST). Każda 1reprezentuje milisekundę. Możesz dodawać lub odejmować milisekundy, pobierając wartość i tworząc nową datę przy użyciu tej wartości. Z tym umysłem możesz to zrobić całkiem łatwo.

const minutesToAdjust = 10;
const millisecondsPerMinute = 60000;
const originalDate = new Date('11/20/2017 10:00 AM');
const modifiedDate1 = new Date(originalDate.valueOf() - (minutesToAdjust * millisecondsPerMinute));
const modifiedDate2 = new Date(originalDate.valueOf() + (minutesToAdjust * millisecondsPerMinute));

console.log(originalDate); // Mon Nov 20 2017 10:00:00 GMT-0600 (CST)
console.log(modifiedDate1); // Mon Nov 20 2017 09:50:00 GMT-0600 (CST)
console.log(modifiedDate2); // Mon Nov 20 2017 10:10:00 GMT-0600 (CST)

10

To, co robię, wydaje się działać całkiem dobrze:

Date.prototype.addMinutes = function(minutes) {
    var copiedDate = new Date(this.getTime());
    return new Date(copiedDate.getTime() + minutes * 60000);
}

Następnie możesz po prostu nazwać to tak:

var now = new Date();
console.log(now.addMinutes(50));

2
Możesz po prostu zrobić return new Date(this.getTime() + minutes * 60000);, że tymczasowy skopiowany Data nie jest konieczna. ;-)
RobG

5

Oto wersja ES6 :

let getTimeAfter30Mins = () => {
  let timeAfter30Mins = new Date();
  timeAfter30Mins = new Date(timeAfter30Mins.setMinutes(timeAfter30Mins.getMinutes() + 30));
};

Nazwij to tak:

getTimeAfter30Mins();

Mam użytkowników wprowadzających godzinę 4:30 + 2:15 godziny / min. Jak mogę pozwolić użytkownikom przejść godziny i minuty i dodać je do istniejących godzin min.
transformator

@transformer możesz podać różne pola wprowadzania dla godzin, minut i tak dalej, mając sprawdzanie poprawności liczb.
xameeramir

5

Wydaje mi się, że w wielu odpowiedziach brakuje kreatywnego elementu, który jest bardzo potrzebny do obliczeń w czasie. Przedstawiam swoje rozwiązanie na czasowe tłumaczenie trwające 30 minut.

( tutaj jsfiddle )

function fluxCapacitor(n) {
    var delta,sigma=0,beta="ge";
    (function(K,z){

        (function(a,b,c){
            beta=beta+"tT";
            switch(b.shift()) {
                case'3':return z('0',a,c,b.shift(),1);
                case'0':return z('3',a,c,b.pop());
                case'5':return z('2',a,c,b[0],1);
                case'1':return z('4',a,c,b.shift());
                case'2':return z('5',a,c,b.pop());
                case'4':return z('1',a,c,b.pop(),1);
            }
        })(K.pop(),K.pop().split(''),K.pop());
    })(n.toString().split(':'),function(b,a,c,b1,gamma){
       delta=[c,b+b1,a];sigma+=gamma?3600000:0; 
       beta=beta+"im";
    });
    beta=beta+"e";
    return new Date (sigma+(new Date( delta.join(':')))[beta]());
}

Muszę przyznać, że to kreatywne. Ale stary .. Trudno to przeczytać!
Erik Baan,

2

Dla leniwych jak ja:

Odpowiedź Kipa (z góry) w skrypcie coffeescript, wykorzystująca „wyliczenie” i działająca na tym samym obiekcie:

Date.UNIT =
  YEAR: 0
  QUARTER: 1
  MONTH: 2
  WEEK: 3
  DAY: 4
  HOUR: 5
  MINUTE: 6
  SECOND: 7
Date::add = (unit, quantity) ->
  switch unit
    when Date.UNIT.YEAR then @setFullYear(@getFullYear() + quantity)
    when Date.UNIT.QUARTER then @setMonth(@getMonth() + (3 * quantity))
    when Date.UNIT.MONTH then @setMonth(@getMonth() + quantity)
    when Date.UNIT.WEEK then @setDate(@getDate() + (7 * quantity))
    when Date.UNIT.DAY then @setDate(@getDate() + quantity)
    when Date.UNIT.HOUR then @setTime(@getTime() + (3600000 * quantity))
    when Date.UNIT.MINUTE then @setTime(@getTime() + (60000 * quantity))
    when Date.UNIT.SECOND then @setTime(@getTime() + (1000 * quantity))
    else throw new Error "Unrecognized unit provided"
  @ # for chaining

2

Użyj istniejącej biblioteki znanej z obsługi dziwactw związanych z obliczeniami czasu. Moim ulubionym jest moment.js .

<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.js"></script>
<script>
 var now = moment(); // get "now"
 console.log(now.toDate()); // show original date
 var thirty = moment(now).add(30,"minutes"); // clone "now" object and add 30 minutes, taking into account weirdness like crossing DST boundries or leap-days, -minutes, -seconds.
 console.log(thirty.toDate()); // show new date
</script>

3
Odpowiedzi nie mogą ulec poprawie, jeśli przegłosujesz bez podania przyczyny.
Ouroborus

OP poprosił o rozwiązanie JavaScript, a nie framework / bibliotekę.
mattpark22

2
@ mattpark22 Rozumiem, o co ci chodzi, ale biblioteka javascript jest nadal javascript. Mógłbym wydrzeć tylko odpowiednie fragmenty biblioteki i przedstawić je jako rozwiązanie kodu. OP miałby odpowiedź javascript w tym sensie, że masz na myśli, ale nie byłby świadomy (prawdopodobnie) akceptowalnego rozwiązania ogólnego przeznaczenia. Ponadto dodanie 30 minut nie jest tak trywialne, jak brzmi większość odpowiedzi, ponieważ istnieje wiele przypadków krawędzi nieobsługiwanych przez obiekt Date. Na przykład najpopularniejsza odpowiedź łamie się podczas przekraczania granic czasu letniego.
Ouroborus

@ Ouroborus - biblioteki nie powinny być jedynym dostępnym rozwiązaniem, jeśli OP nie poprosił o bibliotekę w OP lub znacznikach. W przeciwnym razie odpowiedzi mogą stać się litanią sposobów na zrobienie czegoś w różnych bibliotekach, a OP nie jest mądrzejszy od ich rzeczywistego problemu (który w tym przypadku jest dość trywialny do rozwiązania).
RobG

1
@RobG Nikt nie sugeruje, że należy zapewnić tylko rozwiązania biblioteczne. OP nie może specjalnie poprosić o bibliotekę, ponieważ spowodowałoby to, że pytanie byłoby nie na temat. Pytanie „Jak to zrobić za pomocą JavaScript?” może być interpretowane jako określenie, że jest to specyficzne dla javascript (proszenie o rozwiązanie w konkretnym języku w przeciwieństwie do pytania o surowe rozwiązanie kodu), zwłaszcza biorąc pod uwagę, że ten szczegół jest powtarzany w tytule i znacznikach.
Ouroborus

1

Kolejna opcja, którą napisałem:

Biblioteka DP_DateExtensions

To przesada, jeśli to wszystko, czego potrzebujesz do przetwarzania daty, ale zrobi to, co chcesz.

Obsługuje formatowanie daty / godziny, matematykę dat (dodawanie / odejmowanie części daty), porównywanie dat, parsowanie dat itp. Jest to dowolnie otwarte źródło.


1

Możesz to zrobić:

let thirtyMinutes = 30 * 60 * 1000; // convert 30 minutes to milliseconds
let date1 = new Date();
let date2 = new Date(date1.getTime() + thirtyMinutes);
console.log(date1);
console.log(date2);



1

Powinieneś uzyskać wartość bieżącej daty, aby uzyskać datę za pomocą (ms) i dodać (30 * 60 * 1000) do niej. Teraz masz (aktualna data + 30 min) z ms

console.log('with ms', Date.now() + (30 * 60 * 1000))
console.log('new Date', new Date(Date.now() + (30 * 60 * 1000)))


0

Wiem, że temat jest zdecydowanie za stary. Ale jestem całkiem pewien, że są tacy programiści, którzy nadal tego potrzebują, więc stworzyłem ten prosty skrypt dla Ciebie. Mam nadzieję, że ci się spodoba!

function strtotime(date, addTime){
  let generatedTime=date.getTime();
  if(addTime.seconds) generatedTime+=1000*addTime.seconds; //check for additional seconds 
  if(addTime.minutes) generatedTime+=1000*60*addTime.minutes;//check for additional minutes 
  if(addTime.hours) generatedTime+=1000*60*60*addTime.hours;//check for additional hours 
  return new Date(generatedTime);
}

let futureDate = strtotime(new Date(), {
    hours: 1, //Adding one hour
    minutes: 45, //Adding fourty five minutes
    seconds: 0 //Adding 0 seconds return to not adding any second so  we can remove it.
});
<button onclick="alert(futureDate)">Travel to the future</button>

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.