Adicionando horas ao objeto Data JavaScript?

401

Surpreende-me que o objeto Date do JavaScript não implemente uma função add de qualquer tipo.

Eu simplesmente quero uma função que pode fazer isso:

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

function Date.prototype.addHours(h) {

   // how do I implement this?  

}

Eu simplesmente gostaria de algumas dicas em uma direção.

  • Preciso fazer uma análise de string?

  • Posso usar o setTime?

  • Que tal milissegundos?

Como isso:

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

Isso parece realmente tolo - e isso funciona?

Jeff Meatball Yang
fonte

Respostas:

424

O próprio JavaScript possui APIs de Data / Hora terríveis. No entanto, você pode fazer isso em JavaScript puro:

Date.prototype.addHours = function(h) {
  this.setTime(this.getTime() + (h*60*60*1000));
  return this;
}
Jason Harwig
fonte
Funciona como um encanto! Obrigado
moreirapontocom 24/10/19
se, digamos, você estivesse adicionando uma hora fazendo com que ela rolasse para o dia seguinte, isso seria detectado e aumentaria tudo corretamente (dia mês ano)?
cdoern
@cdoern Eu acho que sim, já que getTime () retornará milissegundos e você apenas adicionará mais milissegundos a isso
The1993
370
Date.prototype.addHours= function(h){
    this.setHours(this.getHours()+h);
    return this;
}

Teste:

alert(new Date().addHours(4));
Kennebec
fonte
25
Eu não acho que isso funcione --- teste em algo com a hora 23, por exemplo? A resposta de Jason Harwig é o que me veio à mente.
Domenic
11
É uma prática ruim adicionar itens a um protótipo de objeto em Javascript, e Domenic está correto, isso não funciona. A solução de Jason Harwig abaixo é melhor.
iKode 6/07/12
19
@Domenic Isso funciona bem com das 23:00, testado dentro do console JavaScript do Firefox 10, Chrome 21 e IE 8/9 Aqui o código que usei para teste: 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) Ele também funciona bem com setMinutes ()
tanguy_k
4
Ocorreu um problema com esta solução - o aumento de 1 falhou para mim no ponto de mudança do horário de verão (avançar o relógio uma hora).
226156 Andrewb #
2
Também fui mordido por isso - eu estava repetindo horas usando setHours (getHours-1): agora, na primeira hora de horário de verão, isso acaba sendo um loop infinito. Então, confira o resultado!
cfstras 14/03
165

O código abaixo é adicionar 4 horas até a data (exemplo, a data de hoje)

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

Não causará erros se você tentar adicionar de 4 a 23 (consulte a documentação ):

Se um parâmetro que você especificar estiver fora do intervalo esperado, setHours () tentará atualizar as informações de data no objeto Date de acordo.

Super Nova
fonte
Não vi isso e fiz uma resposta duplicada. Eu gosto deste método Preciso e útil.
Gandalf, o Branco
Isto não parecem funcionar quando as horas é um decimal (não um inteiro)
gregmagdits
3
Esta é a melhor resposta aqui ... adicionar "addHours" ao protótipo Date é preocupante porque, em algum momento, o JS pode adicionar suporte para essa função e você tem um protótipo conflitante. Isso fornece uma funcionalidade ao usar praticamente o mesmo código.
Kris Boyd #
surpreendeu, mas na verdade dias de incremento, meses se ele precisa, link para os docs seria útil
2oppin
4
Embora o uso de valores de hora> 23 não resolva isso, ele é quebrado nos limites do horário de verão . Dado que está quebrado, não há razão para usá-lo; prefere setTimeou setUTCHour.
Mark Amery
40

Provavelmente é melhor tornar o método addHours imutável retornando uma cópia do objeto Date em vez de alterar seu parâmetro.

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

Dessa forma, você pode encadear várias chamadas de método sem se preocupar com o estado.

Tahir Hassan
fonte
Essa função tem os mesmos problemas que os descritos aqui stackoverflow.com/questions/1050720/… Não se trata realmente de funcionar em determinados navegadores, mas outros locais que usam Javascript consideram isso um problema. pentear sua solução com este stackoverflow.com/a/1050782/295535 parece ser a melhor solução
Ressu
11
Você deve alterar o nome da função, pois a palavra add*é comumente usada para alterar o próprio objeto.
Mr5
@ mr5 - não tenho certeza disso, addé usado no framework .NETDateTime classe de e tem o mesmo significado que o +(mais) em Math.
Tahir Hassan
11
currentDate.addHours(1)<- Do meu instinto de programação, espero que o currentDatevalor mude, mas na sua implementação, isso não aconteceria. Por que estou sugerindo renomear ou alterar sua assinatura para algo
mr5
11
@TahirHassan não tem nada a ver com os detalhes técnicos, mas com a escolha da palavra certa para o nome da função. Eu ainda prefiro a versão mutável quando a função é prefixada comadd
mr5
23

A versão sugerida por kennebec falhará ao mudar para ou do horário de verão, pois é o número da hora definido.

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

adicionará hhoras às thisindependentes das peculiaridades do sistema de tempo. O método de Jason Harwig também funciona.

petter
fonte
19

Você pode usar o momentjs http://momentjs.com/ Library.

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

Também acho que o objeto original não deve ser modificado. Então, para economizar mão de obra futura, aqui está uma solução combinada, com base nas respostas de Jason Harwig e Tahir Hasan :

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

Há um add no Datejs biblioteca .

E aqui estão os métodos de data do JavaScript . o kennebec mencionou sabiamente getHours () e setHours ();

Nosredna
fonte
Observe que essa biblioteca parece estar no status alfa.
Sam
4

Verifique se ainda não está definido, caso contrário o define no protótipo Data:

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

Outra maneira de lidar com isso é converter a data em unixtime (época), adicionar o equivalente em (mili) segundos e depois convertê-lo novamente. Dessa forma, você pode lidar com transições de dia e mês, como adicionar 4 horas a 21, o que deve resultar no dia seguinte, 01:00.

SPRBRN
fonte
Você está certo - mas também está atrasado alguns anos. A resposta de Jason Harwig mostrou esse método 2 anos antes de você; Esta resposta não acrescenta nada de novo.
Mark Amery
3

Para uma função simples de adicionar / subtrair horas / minutos em javascript, tente o seguinte:

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

Isso pode ser usado sem parâmetros para obter a hora atual

getTime();

ou com parâmetros para obter o tempo com os minutos / horas adicionados

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

mesmo o tempo negativo funciona

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

Esta função retorna uma matriz de

array([Hour], [Minute], [Meridian])
durkinza
fonte
Que vantagem esse monstro de 56 linhas de uma função tem sobre a abordagem de duas linhas na resposta mais votada ? -1 porque há uma enorme complexidade extra aqui, sem nenhum benefício que eu possa ver.
Mark Amery
1

SPRBRN está correto. Para contabilizar o início / fim do mês e ano, você precisa converter para a época e voltar.

Aqui está como você faz isso:

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


ou faça-o em uma linha (onde os nomes das variáveis ​​são os mesmos que acima:

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

Essa é uma maneira fácil de obter um valor de dados incrementado ou decrementado.

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
fonte
-1

Um pouco bagunçado, mas funciona!

Dado um formato de data como este: 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+"");

Sua saída seria: 2019-04-03T16: 58

Carl Du Plessis
fonte