Как добавить 30 минут к объекту JavaScript Date?

785

Я хотел бы получить объект Date, который на 30 минут позже, чем другой объект Date. Как мне сделать это с помощью JavaScript?

Морган Ченг
источник
1
Я построил небольшой скрипт всплывающего календаря в js, его на Github , возможно, просмотрите код, чтобы увидеть, как объект date взаимодействует с. Кроме того, проверьте Javascript Kit как его замечательную ссылку на js, особенно для объекта date.
Кристиан
2
Все приведенные ниже ответы, в которых используется вариант date.setMinutes(date.getMinutes() + ...), не будут пересекать границы перехода на летнее время. Например (при условии, что '2014-03-09' является границей перехода на летнее время): var d = new Date('2014-03-09 01:59:00'), f = new Date(d.getTime()); d.setMinutes(d.getMinutes() + 30); dсейчас на 30 минут раньше, а не позже f.
Spig
1
@Spig: 30 минут после 1:59 утра на границе летнего времени 1:29 утра. Там нет ошибки. Если вы напечатаете, fи dвы увидите, что один говорит «GMT-0500», другой говорит «GMT-0400» (или любой другой часовой пояс). Кроме того, если вы вызовете .getTime()оба fи d, вы увидите, что fэто больше, чем d(то есть позже).
Кип
1
@Spig: интересно, попробовал на Firefox и все заработало. Я думаю, что в спецификации того, как должен работать getMinutes (), он попадает в серую область. 01:89станет 02:29, чего не существует в тот день, когда вы «прыгаете вперед». Хром решает, что должно быть 01:29, FF решает 03:29. В ту ночь, когда вы «откатываетесь», оба браузера пропускают «откат» и переходят на 90 минут вперед 02:29. Вот некоторые демонстрации JSFiddle: «весна вперед» / «падение назад»
Кип
1
Если один из ответов ниже ответил на ваш вопрос, как работает этот сайт, вы бы «приняли» ответ, подробнее здесь: Что мне делать, если кто-то отвечает на мой вопрос? , Но только если на ваш вопрос действительно ответили. Если нет, попробуйте добавить больше деталей к вопросу.
До свидания, StackExchange

Ответы:

952

Использование библиотеки

Если вы выполняете много работы с датами, вы можете посмотреть библиотеки дат JavaScript, такие как Datejs или Moment.js . Например, с Moment.js это просто:

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

Ванильный Javascript

Это как ответ хаоса , но в одной строке:

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

Где diffразница в минутах вы хотите от oldDateObjвремени. Это может быть даже отрицательным.

Или как функция многократного использования, если вам нужно сделать это в нескольких местах:

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

И на случай, если это не очевидно, причина, по которой мы умножаем минуты, 60000заключается в том, чтобы преобразовать минуты в миллисекунды.

Будьте осторожны с ванильным Javascript. Даты трудны!

Вы можете подумать, что можете добавить 24 часа к дате, чтобы получить завтрашнюю дату, верно? Неправильно!

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

Оказывается, если пользователь соблюдает переход на летнее время, день не обязательно должен длиться 24 часа. Один день в году длится всего 23 часа, а один день в году - 25 часов. Например, в большинстве Соединенных Штатов и Канады 24 часа после полуночи, 2 ноября 2014 года, по-прежнему 2 ноября:

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!

Вот почему использование одной из вышеупомянутых библиотек безопаснее, если вам придется много работать с этим.

Ниже приведена более общая версия этой функции, которую я написал. Я бы по-прежнему рекомендовал использовать библиотеку, но это может быть излишним / невозможным для вашего проекта. Синтаксис смоделирован после функции 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;
}

Рабочая демоверсия jsFiddle .

койка
источник
14
Это очень сильно; Это работает в течение любого количества минут, даже если число было отрицательным.
Вахид Битар
3
Для секунд умножьте на 1000 вместо 60 КБ.
ashes999
2
Функция dateAdd () великолепна! Но есть одно замечание от меня - семантически, единица должна быть «минута», «секунда» и т. Д., А интервал должен быть величиной (2, 10, 45, ...), а не наоборот. В противном случае идея хорошая.
Васил Попов
1
В этом ответе не учитываются месячные переносы, поэтому 31 января плюс один месяц дают 2 или 3 марта в зависимости от того, високосный год или нет. Функции addMonths и addYears в ответе Якоби справляются с этим, поэтому для меня это лучший ответ.
RobG
1
@RobG Хороший вопрос. Я добавил исправление для этого и дополнительно подчеркнул пункт «использовать библиотеку, если это возможно».
Кип
238
var d1 = new Date ();
var d2 = new Date ( d1 );
d2.setMinutes ( d1.getMinutes() + 30 );
alert ( d2 );
Джейми
источник
114
@ Джейми: Вам не нужны два Dateобъекта. var d = new Date(); d.setMinutes(d.getMinutes() + 30);
Грант Вагнер
15
@Grant: я предположил, что d2 = "я хотел бы получить объект Date" и d1 = "другому объекту Date"
Джейми
7
@CKeene, setMinutes & getMinutes являются частью простого старого Javascript (хотя datejs предоставляет целую кучу других вещей).
с29
4
К вашему сведению - это может выйти за границы летнего времени. Демонстрации JSFiddle: «весна вперед» / «падение назад» (спасибо @Spig за это)
Кип
@trevorgrayson Если указанный вами параметр находится за пределами ожидаемого диапазона, setMinutes () пытается соответствующим образом обновить информацию о дате. Например, если вы используете 100, часы будут увеличены на 1, а 40 будут использоваться для минут.
Михай Крэйцэ
156

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

хаос
источник
3
Обратите внимание, что setTimeвозвращается числовая метка времени в миллисекундах, а не объект даты. (Не думаю, что вы можете сделать одну строчку.)
Алан Х.
12
var in30Mins = new Date(+new Date() + 1.8e6)однострочный, но не уверен, что он лучше двухслойного. ;-)
RobG
112

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

Тео Граца
источник
9
Заметил, что я разместил дубликат этого. Удалено и + 1 вместо.
Иззи
3
Простейший ответ на этот вопрос
Виджай
Я думаю, setMinutesвозвращает nowDatenow = new Date(now)
отметку
46

Может как то так?

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

console.log(v)

Тайлер Картер
источник
6
@ Chacha102: Вам не нужны два Dateобъекта. var d = new Date(); d.setMinutes(d.getMinutes() + 30);
Грант Вагнер
12
Он хотел два объекта даты. Прочитайте вопрос. Один объект Date, который на 30 минут опережает другой объект Date.
Тайлер Картер
5
Работает ли это нормально, если он проходит за час? Так что, если я позвоню в 11:59, будет ли это нормально в 12:29?
Крис Рей
1
@ChrisRae да, это так. 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

Я всегда создаю 7 функций для работы с датой в JS: addSeconds, addMinutes, addHours, addDays, addWeeks, addMonths, addYears.

Вы можете увидеть пример здесь: http://jsfiddle.net/tiagoajacobi/YHA8x/

Как пользоваться:

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

Это функции:

        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;
        };
Якоби
источник
Кто-нибудь может увидеть какие-либо проблемы с этим подходом?
The Dembinski
1
вместо этого используйте moment.js
Виктор Пудеев
@ TheDembinski - какие проблемы вы ожидаете? Расширение встроенных модулей обычно не нравится, но я не вижу проблемы с датой. Было бы неплохо, если бы каждый основной инкремент также опционально устанавливал свои незначительные инкременты (как это делают методы set * ), поэтому addHours опционально занимал минуты, секунды и миллисекунды, чтобы вы могли date.addHours(3, 30)добавить 3 часа и 30 минут. Для addYears потребуются годы, месяцы и дни, для addMonth - месяцы и дни, для addMinutes - минуты, секунды, миллисекунды и т. д.
RobG
1
Привет @transformer Я бы сделал что-то вроде этого. new Date().addHours(4).addMinutes(45);Вы можете вызывать столько, сколько хотите, потому что методы возвращают «this», который является текущим объектом Date.
Якоби,
1
Привет @transformer, я не уверен, что понял твою проблему, но это функция-прототип, которую можно использовать в любом порядке, например: var dt = new Date();тогда dt.addMinutes(45); dt.addHours(4);или даже, dt.addMinutes(285);или dt.addMinutes(45).addHours(4);все будет работать. Если у вас есть вопрос с примером кода, для вашей проблемы опубликуйте его здесь, я буду рад вам помочь.
Якоби
13

Самый простой способ решить эту проблему - распознать, что в javascript даты - это просто числа. Это начинается 0или 'Wed Dec 31 1969 18:00:00 GMT-0600 (CST). Каждый 1представляет миллисекунду. Вы можете добавлять или вычитать миллисекунды, получая значение и создавая новую дату, используя это значение. С этим умом вы можете справиться довольно легко.

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)
tsacodes
источник
10

Это то, что я делаю, что, кажется, работает довольно хорошо:

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

Тогда вы можете просто назвать это так:

var now = new Date();
console.log(now.addMinutes(50));
Джонатан
источник
2
Вы могли бы просто сделать return new Date(this.getTime() + minutes * 60000);, я временная копия не нужна. ;-)
RobG
5

Вот версия ES6 :

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

Назовите это как:

getTimeAfter30Mins();
xameeramir
источник
У меня есть пользователи, которые вводят 4:30 ч. + 2:15 ч. / Мин. Как я могу позволить пользователям пропускать часы и минуты и добавлять их к существующим минутам.
трансформатор
@transformer Вы можете указать разные поля ввода для часов, минут и т. д., имея проверки номера.
xameeramir
5

Я чувствую, что во многих ответах здесь отсутствует креативная составляющая, очень необходимая для расчетов путешествий во времени. Я представляю свое решение для временного перевода 30 минут.

(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]());
}
синхронизирован
источник
Я должен признать, что это творческий подход. Но человек .. Это трудно читать!
Эрик Баан
2

Для ленивых, как я:

Ответ Кипа (сверху) в coffeescript, использующий enum и работающий над тем же объектом:

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
Blaskovicz
источник
2

Использовать известную библиотеку для обработки причуд, связанных с расчетами времени. Мой текущий фаворит - 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>
Ouroborus
источник
3
Ответы не могут улучшиться, если вы отрицаете голос без объяснения причин.
Уроборус
ОП попросил решение JavaScript, а не фреймворк / библиотеку.
mattpark22
2
@ mattpark22 Хотя я понимаю, к чему вы клоните, библиотека javascript все еще остается javascript. Я мог бы вырезать только соответствующие фрагменты библиотеки и представить их как решение кода. У OP был бы ответ, который был бы javascript, в том смысле, в каком вы его имеете в виду, но не знал бы (возможно) приемлемого решения общего назначения. Кроме того, добавление 30 минут не так тривиально, так как большинство ответов делают его звучащим, так как существует множество крайних случаев, которые не обрабатываются объектом Date. Например, самый популярный ответ ломается при пересечении границ летнего времени.
Уроборус
@ Ouroborus - библиотеки не должны быть единственным решением, если ОП не запросил библиотеку в ОП или тегах. В противном случае ответы могут стать просто списком способов сделать что-то в разных библиотеках, и ОП остается не мудрее для их реальной проблемы (которая в этом случае довольно тривиально решить).
RobG
1
@RobG Никто не предлагает предоставлять только библиотечные решения. ОП не может специально запрашивать библиотеку, поскольку это может привести к тому, что вопрос будет не по теме. Спрашивая "Как мне сделать это с помощью JavaScript?" может быть истолковано как указание, что это специфично для javascript (запросить решение на конкретном языке, а не запросить решение для необработанного кода), особенно учитывая, что эта деталь повторяется в заголовке и тегах.
Уроборус
1

Просто еще один вариант, о котором я написал:

Библиотека DP_DateExtensions

Это излишне, если вам нужна вся обработка дат, но она будет делать то, что вы хотите.

Поддерживает форматирование даты / времени, математику даты (сложение / вычитание частей даты), сравнение даты, разбор даты и т. Д. Это свободно открытый источник.

Джим Дэвис
источник
1

Вы могли бы сделать это:

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

rayalois22
источник
1

Вот мой однострочник:

console.log('time: ', new Date(new Date().valueOf() + 60000))

Джейсон Маллингс
источник
1

Вы должны получить значение текущей даты, чтобы получить дату с (мс) и добавить к ней (30 * 60 * 1000). Теперь у вас есть (текущая дата + 30 минут) с мс

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

Абдулрахман Фаузи
источник
0

Я знаю, что тема слишком старая. Но я почти уверен, что некоторые разработчики все еще нуждаются в этом, поэтому я сделал этот простой сценарий для вас. Я надеюсь, вам понравится это!

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>

Аднане Ар
источник