Aggiunta di ore all'oggetto Date JavaScript?


401

Mi stupisce che l'oggetto Date di JavaScript non implementi una funzione add di alcun tipo.

Voglio semplicemente una funzione che possa fare questo:

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

function Date.prototype.addHours(h) {

   // how do I implement this?  

}

Vorrei semplicemente alcuni puntatori in una direzione.

  • Devo eseguire l'analisi delle stringhe?

  • Posso usare setTime?

  • Che ne dici di millisecondi?

Come questo:

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

Questo sembra davvero molto hack - e funziona anche?

Risposte:


424

JavaScript stesso ha terribili API Data / Ora. Tuttavia, puoi farlo in puro JavaScript:

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

Funziona come un fascino! Grazie
moreirapontocom

se dicessi che stavi aggiungendo un'ora facendolo scorrere al giorno successivo, questo lo catturerebbe e aumenterebbe tutto correttamente (giorno mese anno)?
cdoern

@cdoern Penso che sarebbe, dal momento che getTime () restituirà millisecondi e hai appena aggiunto altri millisecondi a quello
The1993

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

Test:

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

25
Non penso che funzioni --- testalo su qualcosa con l'ora 23, per esempio? La risposta di Jason Harwig è ciò che mi è venuto in mente.
Domenic,

11
È una cattiva pratica aggiungere cose a un prototipo di oggetto in Javascript, e Domenic ha ragione, non funziona. La soluzione di Jason Harwig di seguito è migliore.
iKode,

19
@Domenic Funziona bene con le 23:00, testato all'interno della console JavaScript di Firefox 10, Chrome 21 e IE 8/9 Qui il codice che ho usato per testare: 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) Funziona anche bene con setMinutes ()
tanguy_k

4
Ho riscontrato problemi con questa soluzione: l'incremento di 1 non è riuscito per me nel punto di cambio dell'ora legale (spostare l'orologio in avanti di un'ora).
Andrewb,

2
Anche questo mi ha morso: stavo facendo un giro attraverso le ore usando setHours (getHours-1): ora, alla prima ora legale, questo finisce per essere un ciclo infinito. Quindi, controlla il risultato!
cfr

165

Il codice seguente è aggiungere 4 ore ad oggi (esempio data odierna)

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

Non provocherà errori se si tenta di aggiungere da 4 a 23 (consultare i documenti ):

Se un parametro specificato è al di fuori dell'intervallo previsto, setHours () tenta di aggiornare di conseguenza le informazioni sulla data nell'oggetto Date


Non l'ho visto e ho fatto una risposta duplicata. Mi piace questo metodo Preciso e utile
Gandalf the White,

Questo non sembra funzionare quando le ore sono un decimale (non un numero intero)
gregmagdits

3
Questa è la risposta migliore qui ... l'aggiunta di "addHours" al prototipo Date è preoccupante perché ad un certo punto JS potrebbe aggiungere il supporto per quella funzione e quindi hai un prototipo in conflitto. Questo ti dà una funzionalità con l'utilizzo di altrettanti codici.
Kris Boyd,

sorpreso, ma in realtà aumenterebbe i giorni, i mesi se necessario, il collegamento ai documenti sarebbe utile
2oppin

4
Mentre l'utilizzo di valori dell'ora> 23 non rompe questo, è comunque rotto ai limiti dell'ora legale . Dato che è rotto, non c'è motivo di usarlo; preferire setTimeo setUTCHour.
Mark Amery,

40

Probabilmente è meglio rendere immutabile il metodo addHours restituendo una copia dell'oggetto Date anziché mutarne il parametro.

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

In questo modo puoi concatenare un sacco di chiamate di metodo senza preoccuparti dello stato.


Questa funzione ha gli stessi problemi indicati qui stackoverflow.com/questions/1050720/… Non si tratta in realtà se funziona su alcuni browser, ma altri luoghi che utilizzano Javascript lo considerano un problema. combinare la tua soluzione con questo stackoverflow.com/a/1050782/295535 sembra essere la soluzione migliore
Ressu

1
Dovresti considerare di cambiare il nome della funzione, poiché la parola add*è comunemente usata per mutare l'oggetto stesso.
sig. 5

@ mr5 - non ne sono sicuro, addviene usato molto nella DateTimeclasse .NET framework e ha lo stesso significato del +(più) in Math.
Tahir Hassan,

1
currentDate.addHours(1)<- Dal mio istinto di programmazione, mi aspetto che il currentDatevalore cambi, ma nella tua implementazione non lo farebbe. Quanto al motivo per cui sto suggerendo di rinominare o cambiare la sua firma in qualcosa
mr5

1
@TahirHassan non ha nulla a che fare con i dettagli tecnici, ma sulla scelta della parola giusta da usare per il nome della funzione. Preferisco ancora la versione modificabile quando la funzione ha il prefissoadd
mr5,

23

La versione suggerita da Kennebec fallirà quando si passa da o verso l'ora legale, poiché è il numero dell'ora impostato.

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

aggiungerà hore thisindipendentemente dalle peculiarità del sistema temporale. Anche il metodo di Jason Harwig funziona.


19

Puoi utilizzare la http://momentjs.com/ Library di momentjs .

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

7

Penso anche che l'oggetto originale non debba essere modificato. Quindi per salvare la forza lavoro futura ecco una soluzione combinata basata sulle risposte di Jason Harwig e Tahir Hasan :

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


4

Verifica se non è già definito, altrimenti lo definisce sul prototipo Data:

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

3

Un altro modo per gestirlo è convertire la data in unixtime (epoca), quindi aggiungere l'equivalente in (milli) secondi, quindi riconvertirlo. In questo modo è possibile gestire le transizioni di giorno e mese, come l'aggiunta di 4 ore a 21, che dovrebbe comportare il giorno successivo, 01:00.


Hai ragione, ma sei anche in ritardo di un paio d'anni. La risposta di Jason Harwig ha mostrato questo metodo 2 anni prima di te; questa risposta non aggiunge nulla di nuovo.
Mark Amery,

3

Per una semplice funzione di aggiunta / sottrazione di ore / minuti in javascript, prova questo:

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

Questo può essere usato senza parametri per ottenere l'ora corrente

getTime();

o con parametri per ottenere l'ora con i minuti / ore aggiunti

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

anche il tempo negativo funziona

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

questa funzione restituisce una matrice di

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

Quale vantaggio ha questo mostro a 56 righe di una funzione rispetto all'approccio a due righe nella risposta più votata ? -1 perché c'è un'enorme complessità extra qui per nessun beneficio che posso vedere.
Mark Amery,

1

SPRBRN è corretto. Per tenere conto dell'inizio / fine del mese e dell'anno, è necessario convertire in epoca e viceversa.

Ecco come lo fai:

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


o fallo in una riga (dove i nomi delle variabili sono gli stessi di cui sopra:

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

0

Questo è un modo semplice per ottenere un valore di dati incrementato o decrementato.

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

Un po 'disordinato, ma funziona!

Dato un formato data come questo: 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+"");

La tua uscita sarebbe: 2019-04-03T16: 58

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.