Добавление часов в объект JavaScript Date?


403

Меня удивляет, что объект Date в JavaScript не реализует какую-либо функцию добавления.

Я просто хочу функцию, которая может сделать это:

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

function Date.prototype.addHours(h) {

   // how do I implement this?  

}

Я просто хотел бы получить несколько указателей в направлении.

  • Нужно ли делать разбор строк?

  • Могу ли я использовать setTime?

  • Как насчет миллисекунд?

Нравится:

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

Это кажется действительно взломанным, хотя - и это даже работает?

Ответы:


425

У самого JavaScript есть ужасные API Date / Time. Тем не менее, вы можете сделать это в чистом JavaScript:

Date.prototype.addHours = function(h) {
  this.setTime(this.getTime() + (h*60*60*1000));
  return this;
}

Работает как шарм! Спасибо
— moreirapontocom

если, скажем, вы добавляете час, заставляя его перенести на следующий день, будет ли это ловить его и увеличивать все должным образом (день, месяц, год)?
— cdoern

@cdoern Я думаю, что так и будет, поскольку getTime () будет возвращать миллисекунды, а вы просто добавляете к этому еще миллисекунды
— The1993

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

Тестовое задание:

alert(new Date().addHours(4));

25
Я не думаю, что это работает --- протестируйте что-нибудь с часом 23, например? Ответ Джейсона Харвига - то, что пришло мне в голову.
— Доменик

11
Это плохая практика - добавлять вещи в прототип объекта в Javascript, и Domenic верен, это не работает. Приведенное ниже решение Джейсона Харвига лучше.
— iKode

19
@Domenic Это прекрасно работает с 23:00, протестировано в консоли JavaScript Firefox 10, Chrome 21 и IE 8/9. Вот код, который я использовал для тестирования: 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) Он также отлично работает с setMinutes ()
— tanguy_k

4
У меня возникли проблемы с этим решением - мне не удалось увеличить на 1 в точке перехода на летнее время (перевести часы на час вперед).
— Andrewb

2
Также меня это укусило - я перебирал часы с помощью setHours (getHours-1): теперь, в первый час летнего времени, это заканчивается бесконечным циклом. Итак, проверьте результат!
— cfstras

165

Приведенный ниже код должен добавить 4 часа к дате (пример сегодняшней даты)

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

Это не приведет к ошибке, если вы попытаетесь добавить 4 к 23 (см. Документы ):

Если указанный параметр находится за пределами ожидаемого диапазона, setHours () пытается соответствующим образом обновить информацию о дате в объекте Date


Я не видел этого и сделал дубликат ответа. Мне нравится этот метод. Точно и полезно.
— Гэндальф Белый

Кажется, что это не работает, когда часы десятичные (не целые)
— gregmagdits

3
Это лучший ответ здесь ... добавление addHours к прототипу Date вызывает беспокойство, поскольку в какой-то момент JS может добавить поддержку этой функции, и тогда у вас будет конфликтующий прототип. Это дает вам функциональность с использованием примерно столько же кода.
— Крис Бойд

Удивлен, но на самом деле это увеличение дней, месяцев, если это необходимо, ссылка на документы была бы полезна
— 2oppin

4
Хотя использование значений часов> 23 не нарушает этого, оно тем не менее нарушает границы перехода на летнее время . Учитывая, что он сломан, нет причин использовать его; предпочитаю setTimeили setUTCHour.
— Марк Амери

40

Вероятно, лучше сделать метод addHours неизменным, возвращая копию объекта Date, а не изменяя его параметр.

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

Таким образом, вы можете связать несколько вызовов методов, не беспокоясь о состоянии.


Эта функция имеет те же проблемы, что и здесь. Stackoverflow.com/questions/1050720/… Дело не в том, работает ли она в определенных браузерах, но в других местах, использующих Javascript, это рассматривается как проблема. объединение вашего решения с этим stackoverflow.com/a/1050782/295535 представляется наилучшим решением
— Ressu

1
Вы должны рассмотреть возможность изменения имени функции, так как слово add*обычно используется для изменения самого объекта.
— mr5

@ mr5 - не уверен в этом, addчасто используется в классе .NET Framework DateTimeи имеет то же значение, что и +(плюс) в Math.
— Тахир Хасан

1
currentDate.addHours(1)<- Исходя из моего программного инстинкта, я ожидаю, что currentDateзначение изменится, но в вашей реализации этого не произойдет. Что касается того, почему я предлагаю переименовать или изменить свою подпись на что-то
— mr5

1
@TahirHassan не имеет ничего общего с техническими деталями, но при выборе правильного слова для использования в качестве имени функции. Я все еще предпочитаю изменчивую версию, когда перед функцией стоит префиксadd
— mr5

23

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

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

добавит hчасы к thisнезависимым от времени системным особенностям. Метод Джейсона Харвига также работает.


19

Вы можете использовать моментальные http://momentjs.com/ Библиотека.

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

7

Я также думаю, что оригинальный объект не должен быть изменен. Таким образом, чтобы спасти будущую рабочую силу, вот комбинированное решение, основанное на ответах Джейсона Харвига и Тахира Хасана :

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


4

Проверьте, не определен ли он, иначе определите его в прототипе Date:

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

3

Другой способ справиться с этим - преобразовать дату в unixtime (эпоху), затем добавить эквивалент в (милли) секундах, а затем преобразовать его обратно. Таким образом, вы можете обрабатывать переходы дня и месяца, например добавление 4 часов к 21, что должно привести к следующему дню, 01:00.


Ты прав - но ты тоже на пару лет опоздал. Ответ Джейсона Харвига показал этот метод за 2 года до вас; этот ответ не добавляет ничего нового.
— Марк Амери

3

Для простого добавления / вычитания функции часа / минуты в javascript попробуйте это:

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

Это можно использовать без параметров, чтобы получить текущее время

getTime();

или с параметрами, чтобы получить время с добавленными минутами / часами

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

даже негативное время работает

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

эта функция возвращает массив

array([Hour], [Minute], [Meridian])

Какое преимущество имеет этот 56-строчный монстр функции по сравнению с двухстрочным подходом в ответе с наибольшим количеством голосов ? -1 потому что здесь есть огромная дополнительная сложность, которую я не вижу.
— Марк Амери

1

СПРБРН правильный. Для того чтобы учесть начало / конец месяца и года, вам необходимо перейти в эпоху и обратно.

Вот как вы это делаете:

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


или сделать это в одной строке (где имена переменных такие же, как указано выше:

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

0

Это простой способ получить увеличенное или уменьшенное значение данных.

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

Немного грязно, но это работает!

Учитывая формат даты как это: 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+"");

Ваш вывод будет: 2019-04-03T16: 58

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.