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.