Ajout d'heures à l'objet Date JavaScript?


402

Cela m'étonne que l'objet Date de JavaScript n'implémente aucune fonction d'ajout d'aucune sorte.

Je veux simplement une fonction qui puisse le faire:

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

function Date.prototype.addHours(h) {

   // how do I implement this?  

}

Je voudrais simplement quelques indications dans une direction.

  • Dois-je faire une analyse de chaîne?

  • Puis-je utiliser setTime?

  • Que diriez-vous des millisecondes?

Comme ça:

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

Cela semble vraiment hackeux - et ça marche même?

Réponses:


425

JavaScript lui-même a de terribles API de date / heure. Néanmoins, vous pouvez le faire en JavaScript pur:

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

Fonctionne comme un charme! Merci
moreirapontocom

si, par exemple, vous ajoutiez une heure pour la reporter au lendemain, est-ce que cela la rattraperait et incrémenterait tout correctement (jour, mois, année)?
cdoern

@cdoern Je pense que oui, puisque getTime () renverra des millisecondes et que vous
ajouterez

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

Tester:

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

25
Je ne pense pas que cela fonctionne --- testez-le sur quelque chose avec l'heure 23, par exemple? La réponse de Jason Harwig est ce qui m'est venu à l'esprit.
Domenic

11
C'est une mauvaise pratique d'ajouter des choses à un prototype d'objet en Javascript, et Domenic est correct, cela ne fonctionne pas. La solution de Jason Harwig ci-dessous est meilleure.
iKode

19
@Domenic Cela fonctionne très bien avec 23:00, testé dans la console JavaScript de Firefox 10, Chrome 21 et IE 8/9 Voici le code que j'ai utilisé pour tester: 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) Cela fonctionne également très bien avec setMinutes ()
tanguy_k

4
J'ai rencontré des problèmes avec cette solution - L'incrémentation de 1 a échoué pour moi au point de passage à l'heure d'été (déplacer l'horloge d'une heure).
andrewb

2
J'ai également été mordu par cela - je parcourais des heures en utilisant setHours (getHours-1): maintenant, à la première heure DST, cela finit par être une boucle infinie. Alors, vérifiez le résultat!
cfstras

165

Le code ci-dessous est d'ajouter 4 heures à ce jour (exemple la date du jour)

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

Cela ne provoquera pas d'erreur si vous essayez d'ajouter 4 à 23 (voir la documentation ):

Si un paramètre que vous spécifiez est en dehors de la plage attendue, setHours () tente de mettre à jour les informations de date dans l'objet Date en conséquence


Je ne l'ai pas vu et j'ai fait une réponse en double. J'aime cette méthode. Précis et utile.
Gandalf le Blanc

Cela ne semble pas fonctionner lorsque les heures sont décimales (pas un entier)
gregmagdits

3
C'est la meilleure réponse ici ... ajouter "addHours" au prototype Date est inquiétant car à un moment donné, JS pourrait ajouter le support de cette fonction et vous avez alors un prototype conflictuel. Cela vous donne une fonctionnalité avec l'utilisation de presque autant de code.
Kris Boyd

surpris, mais il incrémente en fait des jours, des mois s'il le faut, un lien vers les documents serait utile
2oppin

4
Bien que l'utilisation de valeurs d'heure> 23 ne brise pas cela, il est néanmoins cassé aux limites de l'heure d'été . Étant donné qu'il est cassé, il n'y a aucune raison de l'utiliser; préférez setTimeou setUTCHour.
Mark Amery

40

Il est probablement préférable de rendre la méthode addHours immuable en renvoyant une copie de l'objet Date plutôt que de muter son paramètre.

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

De cette façon, vous pouvez chaîner un tas d'appels de méthode sans vous soucier de l'état.


Cette fonction a les mêmes problèmes énoncés ici stackoverflow.com/questions/1050720/...~~V~~number=plural~~singular~~3rd Ce n'est pas vraiment si cela fonctionne sur certains navigateurs, mais d' autres endroits qui utilisent Javascript voir cela comme un problème. peigner votre solution avec celle-ci stackoverflow.com/a/1050782/295535 semble être la meilleure solution
Ressu

1
Vous devriez envisager de changer le nom de la fonction, car le mot add*est couramment utilisé pour muter l'objet lui-même.
mr5

@ mr5 - pas sûr de cela, addest DateTimebeaucoup utilisé dans la classe de framework .NET , et a la même signification que le +(plus) en mathématiques.
Tahir Hassan

1
currentDate.addHours(1)<- De mon instinct de programmation, je m'attends à ce que la currentDatevaleur change, mais dans votre implémentation, ce ne serait pas le cas. Quant à savoir pourquoi je
propose

1
@TahirHassan n'a rien à voir avec les détails techniques mais à choisir le bon mot à utiliser pour le nom de la fonction. Je préfère toujours la version mutable lorsque la fonction est préfixée avecadd
mr5

23

La version suggérée par kennebec échouera lors du passage vers ou depuis l'heure d'été, car c'est le numéro de l'heure qui est défini.

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

ajoutera des hheures aux particularités thisindépendantes du système de temps. La méthode de Jason Harwig fonctionne également.


19

Vous pouvez utiliser la bibliothèque momentjs http://momentjs.com/ .

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

7

Je pense également que l'objet d'origine ne doit pas être modifié. Donc, pour économiser de la main-d'œuvre future, voici une solution combinée basée sur les réponses de Jason Harwig et Tahir Hasan :

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


4

Vérifiez si ce n'est pas déjà défini, sinon définissez-le sur le prototype Date:

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

3

Une autre façon de gérer cela est de convertir la date en unixtime (epoch), puis d'ajouter l'équivalent en (milli) secondes, puis de la reconvertir. De cette façon, vous pouvez gérer les transitions de jour et de mois, comme ajouter 4 heures à 21, ce qui devrait se traduire par le lendemain, 01h00.


Vous avez raison - mais vous avez également quelques années de retard. La réponse de Jason Harwig a montré cette méthode 2 ans avant vous; cette réponse n'ajoute rien de nouveau.
Mark Amery

3

Pour une simple fonction d'ajout / soustraction d'heure / minute en javascript, essayez ceci:

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

Cela peut être utilisé sans paramètres pour obtenir l'heure actuelle

getTime();

ou avec des paramètres pour obtenir l'heure avec les minutes / heures ajoutées

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

même le temps négatif fonctionne

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

cette fonction renvoie un tableau de

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

Quel avantage ce monstre de 56 lignes d'une fonction a-t-il sur l' approche à deux lignes dans la réponse la plus votée ? -1 car il y a une énorme complexité supplémentaire ici sans aucun avantage que je puisse voir.
Mark Amery

1

SPRBRN est correct. Afin de prendre en compte le début / la fin du mois et de l'année, vous devez vous convertir en Epoch et inversement.

Voici comment procéder:

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 faites-le sur une seule ligne (où les noms de variables sont les mêmes que ci-dessus:

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

0

C'est un moyen facile d'obtenir une valeur de données incrémentée ou décrémentée.

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 peu en désordre, mais ça marche!

Étant donné un format de date comme celui-ci: 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+"");

Votre sortie serait: 2019-04-03T16: 58

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.