Comment calculer la différence de date en JavaScript?

181

Je veux calculer la différence de date en jours, heures, minutes, secondes, millisecondes, nanosecondes. Comment puis-je le faire?

Farhan Siddiqui
la source
1
duplication possible de Obtenir la différence entre 2 dates en javascript?
Anderson Green
1
Les solutions ci-dessous seront interrompues si les deux dates impliquées sont dans des fuseaux horaires différents. Voir la question sur pour une solution plus précise stackoverflow.com/questions/3224834/… ?
Shyam Habarakada

Réponses:

219

En supposant que vous ayez deux Dateobjets , vous pouvez simplement les soustraire pour obtenir la différence en millisecondes:

var difference = date2 - date1;

À partir de là, vous pouvez utiliser une arithmétique simple pour dériver les autres valeurs.

icktoofay
la source
38
C'est donc la bonne réponse. Exemple: pour obtenir la différence en jours Math.floor((date2 - date1) / (1000*60*60*24))- pour une différence dans une autre unité, ajustez le dénominateur (la valeur de base est en ms).
trisweb
33
Il n'y a pas d'arithmétique «simple» pour convertir des millisecondes en années. Vous devez être au courant de l'année bissextile, du fuseau horaire, et certains jours ont 23 ou 25 heures. Certaines années ont 365,25 jours, il n'y a donc pas d'arithmétique simple ici (toujours à la recherche d'une solution précise).
Alexandre Salomé
6
@Alexandre: La question jamais posée depuis des années. En effet, calculer les écarts annuels n'est pas trivial. Pendant des jours, cependant, il est correct, en supposant que les dates sont dans le même fuseau horaire (une hypothèse non déraisonnable). Pour autant que je sache, un jour est défini comme 24 heures, et toute «variation» en raison de l'heure d'été est en fait un changement de fuseau horaire. Si vous ne faites pas déjà la distinction entre les fuseaux horaires, essayer de comprendre un décalage horaire va vous mettre dans un monde de douleur, notamment parce que le passage à l'heure d'été `` répète '' l'heure. Restez dans un fuseau horaire, cependant, et tout fonctionne.
icktoofay
12
@ trisweb - même quelque chose d'aussi simple que d'obtenir une différence en jours est plus complexe que votre commentaire. Combien de jours entre 22h mardi et 9h mercredi? Votre algorithme dit 0. D'autres pourraient penser 1.
RobG
Les relativistes @RobG pourraient même penser plus de 1 ou moins de 0. Tout dépend de l'observateur.
Innocent Bystander
78
var DateDiff = {

    inDays: function(d1, d2) {
        var t2 = d2.getTime();
        var t1 = d1.getTime();

        return parseInt((t2-t1)/(24*3600*1000));
    },

    inWeeks: function(d1, d2) {
        var t2 = d2.getTime();
        var t1 = d1.getTime();

        return parseInt((t2-t1)/(24*3600*1000*7));
    },

    inMonths: function(d1, d2) {
        var d1Y = d1.getFullYear();
        var d2Y = d2.getFullYear();
        var d1M = d1.getMonth();
        var d2M = d2.getMonth();

        return (d2M+12*d2Y)-(d1M+12*d1Y);
    },

    inYears: function(d1, d2) {
        return d2.getFullYear()-d1.getFullYear();
    }
}

var dString = "May, 20, 1984";

var d1 = new Date(dString);
var d2 = new Date();

document.write("<br />Number of <b>days</b> since "+dString+": "+DateDiff.inDays(d1, d2));
document.write("<br />Number of <b>weeks</b> since "+dString+": "+DateDiff.inWeeks(d1, d2));
document.write("<br />Number of <b>months</b> since "+dString+": "+DateDiff.inMonths(d1, d2));
document.write("<br />Number of <b>years</b> since "+dString+": "+DateDiff.inYears(d1, d2));

Échantillon de code tiré d' ici .

Paresh Mayani
la source
Cela ne renvoie que la différence de date au format donné si elle est utilisée comme compteur unique. Par exemple, si vous voulez 3 mois 4 jours et 5 heures, il ne produira PAS ces résultats. Plus dans la ligne de 3 mois 96 jours et beaucoup d'heures.
Joris Kroos
30

Une autre solution consiste à convertir la différence en un nouvel objet Date et à obtenir l'année de cette date (différente de 1970), le mois, le jour, etc.

var date1 = new Date(2010, 6, 17);
var date2 = new Date(2013, 12, 18);
var diff = new Date(date2.getTime() - date1.getTime());
// diff is: Thu Jul 05 1973 04:00:00 GMT+0300 (EEST)

console.log(diff.getUTCFullYear() - 1970); // Gives difference as year
// 3

console.log(diff.getUTCMonth()); // Gives month count of difference
// 6

console.log(diff.getUTCDate() - 1); // Gives day count of difference
// 4

Donc la différence est comme "3 ans et 6 mois et 4 jours". Si vous voulez faire la différence dans un style lisible par l'homme, cela peut vous aider.

Murat Çorlu
la source
Ce n'est pas le sens! Nous voulons toute la différence! Dans cet exemple, la différence en jours est de 1281 et non de 4!
chaim.dev
3
@ chaim.dev "Si vous voulez faire la différence dans un style lisible par l'homme, cela peut vous aider."
Murat Çorlu
7
Ce n'est pas fiable. Il ne tient pas compte des différentes longueurs de mois, des années bissextiles et d'autres anomalies.
Marc Durdin
2
Merci Murat, Cette solution a résolu mon problème. Ce que je veux vraiment Cela doit fonctionner de la même manière que PHP.
Ritesh Patadiya
27

Les expressions telles que «différence de jours» ne sont jamais aussi simples qu'elles le paraissent. Si vous avez les dates suivantes:

d1: 2011-10-15 23:59:00
d1: 2011-10-16 00:01:00

la différence de temps est de 2 minutes, la «différence de jours» doit-elle être 1 ou 0? Des problèmes similaires se posent pour toute expression de la différence en mois, en années ou autre étant donné que les années, les mois et les jours ont des durées et des heures différentes (par exemple, le jour où l'heure d'été commence est 1 heure plus court que d'habitude et deux heures plus court que le jour ça se termine).

Voici une fonction pour une différence de jours qui ignore l'heure, c'est-à-dire que pour les dates ci-dessus, elle renvoie 1.

/*
   Get the number of days between two dates - not inclusive.

   "between" does not include the start date, so days
   between Thursday and Friday is one, Thursday to Saturday
   is two, and so on. Between Friday and the following Friday is 7.

   e.g. getDaysBetweenDates( 22-Jul-2011, 29-jul-2011) => 7.

   If want inclusive dates (e.g. leave from 1/1/2011 to 30/1/2011),
   use date prior to start date (i.e. 31/12/2010 to 30/1/2011).

   Only calculates whole days.

   Assumes d0 <= d1
*/
function getDaysBetweenDates(d0, d1) {

  var msPerDay = 8.64e7;

  // Copy dates so don't mess them up
  var x0 = new Date(d0);
  var x1 = new Date(d1);

  // Set to noon - avoid DST errors
  x0.setHours(12,0,0);
  x1.setHours(12,0,0);

  // Round to remove daylight saving errors
  return Math.round( (x1 - x0) / msPerDay );
}

Cela peut être plus concis:

/*  Return number of days between d0 and d1.
**  Returns positive if d0 < d1, otherwise negative.
**
**  e.g. between 2000-02-28 and 2001-02-28 there are 366 days
**       between 2015-12-28 and 2015-12-29 there is 1 day
**       between 2015-12-28 23:59:59 and 2015-12-29 00:00:01 there is 1 day
**       between 2015-12-28 00:00:01 and 2015-12-28 23:59:59 there are 0 days
**        
**  @param {Date} d0  - start date
**  @param {Date} d1  - end date
**  @returns {number} - whole number of days between d0 and d1
**
*/
function daysDifference(d0, d1) {
  var diff = new Date(+d1).setHours(12) - new Date(+d0).setHours(12);
  return Math.round(diff/8.64e7);
}

// Simple formatter
function formatDate(date){
  return [date.getFullYear(),('0'+(date.getMonth()+1)).slice(-2),('0'+date.getDate()).slice(-2)].join('-');
}

// Examples
[[new Date(2000,1,28), new Date(2001,1,28)],  // Leap year
 [new Date(2001,1,28), new Date(2002,1,28)],  // Not leap year
 [new Date(2017,0,1),  new Date(2017,1,1)] 
].forEach(function(dates) {
  document.write('From ' + formatDate(dates[0]) + ' to ' + formatDate(dates[1]) +
                 ' is ' + daysDifference(dates[0],dates[1]) + ' days<br>');
});

RobG
la source
1
@ rudeovskizebear - testé dans IE, Firefox et Safari, fonctionne très bien. Il utilise ECMAScript de base que je m'attendrais à fonctionner dans n'importe quel navigateur, qu'est-ce qui ne fonctionne pas pour vous?
RobG
Je l'ai mis sur une page de test, et cela a bien fonctionné dans Chrome, mais j'ai continué à obtenir null dans IE9 et le dernier FF
mnsr
@ RafiB. — Je ne sais pas comment vous pensez que l'un est plus précis que l'autre, ils font essentiellement la même chose, c'est-à-dire calculent la différence en jours entiers en utilisant une valeur d'heure UTC. L'ambiguïté de la question n'a pas été élucidée. Si c'était le cas, cela pourrait conduire à une solution différente.
RobG
@RobG Veuillez modifier les exemples dans les commentaires d'une solution plus concise. Le mois devrait être '12' et non '22'
S.aad
1
@ IgorKudryashov - désolé, je ne comprends tout simplement pas. 2000 est une année bissextile, donc du 28 février 2000 au 28 février 2001 correspond à 366 jours. Dans une année non bissextile, c'est 365 jours. J'ai ajouté quelques exemples supplémentaires.
RobG
18
<html lang="en">
<head>
<script>
function getDateDiff(time1, time2) {
  var str1= time1.split('/');
  var str2= time2.split('/');

  //                yyyy   , mm       , dd
  var t1 = new Date(str1[2], str1[0]-1, str1[1]);
  var t2 = new Date(str2[2], str2[0]-1, str2[1]);

  var diffMS = t1 - t2;    
  console.log(diffMS + ' ms');

  var diffS = diffMS / 1000;    
  console.log(diffS + ' ');

  var diffM = diffS / 60;
  console.log(diffM + ' minutes');

  var diffH = diffM / 60;
  console.log(diffH + ' hours');

  var diffD = diffH / 24;
  console.log(diffD + ' days');
  alert(diffD);
}

//alert(getDateDiff('10/18/2013','10/14/2013'));
</script>
</head>
<body>
  <input type="button" 
       onclick="getDateDiff('10/18/2013','10/14/2013')" 
       value="clickHere()" />

</body>
</html>
Anadi Kumar
la source
Ça ne m'aide pas. Je ne peux pas étendre cela à des mois ou des années dans la même approche.
tomazahlin
9

utilisez Moment.js pour tous vos calculs de date-heure liés à JavaScript

La réponse à votre question est:

var a = moment([2007, 0, 29]);   
var b = moment([2007, 0, 28]);    
a.diff(b) // 86400000  

Les détails complets peuvent être trouvés ici

Basant Sahu
la source
4
Et profitez des 400 Ko supplémentaires pour une simple différence de date.
Romeo Mihalcea
@RomeoMihalcea Le moment actuel minifié.js 2.22.2 avec une locale est de 53 Ko, 17 Ko gzippé. Je comprends cependant votre inquiétude. C'est une énorme bibliothèque à utiliser pour une fonction simple, mais elle prend en charge tellement de bizarreries liées à la date / heure que cela en vaut souvent la peine.
HeikoS
8
function DateDiff(date1, date2) {
    date1.setHours(0);
    date1.setMinutes(0, 0, 0);
    date2.setHours(0);
    date2.setMinutes(0, 0, 0);
    var datediff = Math.abs(date1.getTime() - date2.getTime()); // difference 
    return parseInt(datediff / (24 * 60 * 60 * 1000), 10); //Convert values days and return value      
}
user2513608
la source
Merci pour les solutions :)
bhagirathi
La plupart des solutions que j'ai trouvées ne fonctionnent pas ou sont trop longues. Votre solution est la plus simple à ce jour et fonctionne exactement comme prévu! Cheers :)
Bruce
et si je veux connaître la différence avec plus d'une heure? dans la question post, il y a des heures et des secondes, que pour tous ces zéros?
2oppin le
8

Avec momentjs c'est simple:

moment("2016-04-08").fromNow();
Josh LaMar
la source
1
moment.js est génial! :)
Kami
Bonne réponse, mais probablement exagérée pour cette situation spécifique.
HappyDog
6
var d1=new Date(2011,0,1); // jan,1 2011
var d2=new Date(); // now

var diff=d2-d1,sign=diff<0?-1:1,milliseconds,seconds,minutes,hours,days;
diff/=sign; // or diff=Math.abs(diff);
diff=(diff-(milliseconds=diff%1000))/1000;
diff=(diff-(seconds=diff%60))/60;
diff=(diff-(minutes=diff%60))/60;
days=(diff-(hours=diff%24))/24;

console.info(sign===1?"Elapsed: ":"Remains: ",
             days+" days, ",
             hours+" hours, ",
             minutes+" minutes, ",
             seconds+" seconds, ",
             milliseconds+" milliseconds.");
Andrew D.
la source
4

Désolé mais le calcul de la milliseconde à plat n'est pas fiable Merci pour toutes les réponses, mais peu de fonctions que j'ai essayées échouent soit le 1. Une date proche de la date d'aujourd'hui 2. Une date en 1970 ou 3. Une date dans une année bissextile.

Approche qui a le mieux fonctionné pour moi et couvre tous les scénarios, par exemple, année bissextile, date proche en 1970, 29 février, etc.

var someday = new Date("8/1/1985");
var today = new Date();
var years = today.getFullYear() - someday.getFullYear();

// Reset someday to the current year.
someday.setFullYear(today.getFullYear());

// Depending on when that day falls for this year, subtract 1.
if (today < someday)
{
    years--;
}
document.write("Its been " + years + " full years.");
jaiveeru
la source
3

Si vous utilisez moment.js, il est assez simple de trouver une différence de date.

var now  = "04/09/2013 15:00:00";
var then = "04/09/2013 14:20:30";

moment.utc(moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss"))).format("HH:mm:ss")
James Hawkings
la source
3
function DateDiff(b, e)
{
    let
        endYear = e.getFullYear(),
        endMonth = e.getMonth(),
        years = endYear - b.getFullYear(),
        months = endMonth - b.getMonth(),
        days = e.getDate() - b.getDate();
    if (months < 0)
    {
        years--;
        months += 12;
    }
    if (days < 0)
    {
        months--;
        days += new Date(endYear, endMonth, 0).getDate();
    }
    return [years, months, days];
}

[years, months, days] = DateDiff(
    new Date("October 21, 1980"),
    new Date("July 11, 2017")); // 36 8 20
Alexander Chernosvitov
la source
3

Je pense que cela devrait le faire.

let today = new Date();
let form_date=new Date('2019-10-23')
let difference=form_date>today ? form_date-today : today-form_date
let diff_days=Math.floor(difference/(1000*3600*24))
Ebuka Joseph Akeru
la source
2

C'est ainsi que vous pouvez implémenter la différence entre les dates sans cadre.

function getDateDiff(dateOne, dateTwo) {
        if(dateOne.charAt(2)=='-' & dateTwo.charAt(2)=='-'){
            dateOne = new Date(formatDate(dateOne));
            dateTwo = new Date(formatDate(dateTwo));
        }
        else{
            dateOne = new Date(dateOne);
            dateTwo = new Date(dateTwo);            
        }
        let timeDiff = Math.abs(dateOne.getTime() - dateTwo.getTime());
        let diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
        let diffMonths = Math.ceil(diffDays/31);
        let diffYears = Math.ceil(diffMonths/12);

        let message = "Difference in Days: " + diffDays + " " +
                      "Difference in Months: " + diffMonths+ " " + 
                      "Difference in Years: " + diffYears;
        return message;
     }

    function formatDate(date) {
         return date.split('-').reverse().join('-');
    }

    console.log(getDateDiff("23-04-2017", "23-04-2018"));
Aravinda Meewalaarachchi
la source
1

function daysInMonth (month, year) {
    return new Date(year, month, 0).getDate();
}
function getduration(){

let A= document.getElementById("date1_id").value
let B= document.getElementById("date2_id").value

let C=Number(A.substring(3,5))
let D=Number(B.substring(3,5))
let dif=D-C
let arr=[];
let sum=0;
for (let i=0;i<dif+1;i++){
  sum+=Number(daysInMonth(i+C,2019))
}
let sum_alter=0;
for (let i=0;i<dif;i++){
  sum_alter+=Number(daysInMonth(i+C,2019))
}
let no_of_month=(Number(B.substring(3,5)) - Number(A.substring(3,5)))
let days=[];
if ((Number(B.substring(3,5)) - Number(A.substring(3,5)))>0||Number(B.substring(0,2)) - Number(A.substring(0,2))<0){
days=Number(B.substring(0,2)) - Number(A.substring(0,2)) + sum_alter
}

if ((Number(B.substring(3,5)) == Number(A.substring(3,5)))){
console.log(Number(B.substring(0,2)) - Number(A.substring(0,2)) + sum_alter)
}

time_1=[]; time_2=[]; let hour=[];
 time_1=document.getElementById("time1_id").value
 time_2=document.getElementById("time2_id").value
  if (time_1.substring(0,2)=="12"){
     time_1="00:00:00 PM"
  }
if (time_1.substring(9,11)==time_2.substring(9,11)){
hour=Math.abs(Number(time_2.substring(0,2)) - Number(time_1.substring(0,2)))
}
if (time_1.substring(9,11)!=time_2.substring(9,11)){
hour=Math.abs(Number(time_2.substring(0,2)) - Number(time_1.substring(0,2)))+12
}
let min=Math.abs(Number(time_1.substring(3,5))-Number(time_2.substring(3,5)))
document.getElementById("duration_id").value=days +" days "+ hour+"  hour " + min+"  min " 
}
<input type="text" id="date1_id" placeholder="28/05/2019">
<input type="text" id="date2_id" placeholder="29/06/2019">
<br><br>
<input type="text" id="time1_id" placeholder="08:01:00 AM">
<input type="text" id="time2_id" placeholder="00:00:00 PM">
<br><br>
<button class="text" onClick="getduration()">Submit </button>
<br><br>
<input type="text" id="duration_id" placeholder="days hour min">

Maximus Su
la source
Ce code donne des résultats précis sur le nombre de jours, d'heure et même de minutes
Maximus Su
J'espère que vous l'utilisez
Maximus Su
0

Ok, il y a plusieurs façons de le faire. Oui, vous pouvez utiliser un ancien JS. Essayez simplement:

let dt1 = new Date()
let dt2 = new Date()

Émulons le passage en utilisant Date.prototype.setMinutes et assurez-vous que nous sommes à portée.

dt1.setMinutes(7)
dt2.setMinutes(42)
console.log('Elapsed seconds:',(dt2-dt1)/1000)

Vous pouvez également utiliser une bibliothèque comme js-joda , où vous pouvez facilement faire des choses comme celle-ci (directement à partir de la documentation):

var dt1 = LocalDateTime.parse("2016-02-26T23:55:42.123");
var dt2 = dt1
  .plusYears(6)
  .plusMonths(12)
  .plusHours(2)
  .plusMinutes(42)
  .plusSeconds(12);

// obtain the duration between the two dates
dt1.until(dt2, ChronoUnit.YEARS); // 7
dt1.until(dt2, ChronoUnit.MONTHS); // 84
dt1.until(dt2, ChronoUnit.WEEKS); // 356
dt1.until(dt2, ChronoUnit.DAYS); // 2557
dt1.until(dt2, ChronoUnit.HOURS); // 61370
dt1.until(dt2, ChronoUnit.MINUTES); // 3682242
dt1.until(dt2, ChronoUnit.SECONDS); // 220934532

Il y a beaucoup plus de bibliothèques ofc, mais js-joda a un avantage supplémentaire d'être disponible également en Java, où il a été largement testé. Tous ces tests ont été migrés vers js-joda, il est également immuable.

mwojtera
la source
-1

cela devrait très bien fonctionner si vous avez juste besoin d'afficher le temps restant, car JavaScript utilise des images pour son heure, vous aurez votre heure de fin - The Time RN après cela, nous pouvons le diviser par 1000 car apparemment 1000 images = 1 seconde, après cela, vous pouvez utiliser les calculs de base du temps, mais il y a toujours un problème avec ce code, puisque le calcul est statique, il ne peut pas compenser le total de jours différent dans une année (360/365/366), le tas de SI après le calcul, il faut le rendre nul si le temps est inférieur à 0, j'espère que cela aide même si ce n'est pas exactement ce que vous demandez :)

var now = new Date();
var end = new Date("End Time");
var total = (end - now) ;
var totalD =  Math.abs(Math.floor(total/1000));

var years = Math.floor(totalD / (365*60*60*24));
var months = Math.floor((totalD - years*365*60*60*24) / (30*60*60*24));
var days = Math.floor((totalD - years*365*60*60*24 - months*30*60*60*24)/ (60*60*24));
var hours = Math.floor((totalD - years*365*60*60*24 - months*30*60*60*24 - days*60*60*24)/ (60*60));
var minutes = Math.floor((totalD - years*365*60*60*24 - months*30*60*60*24 - days*60*60*24 - hours*60*60)/ (60));
var seconds = Math.floor(totalD - years*365*60*60*24 - months*30*60*60*24 - days*60*60*24 - hours*60*60 - minutes*60);

var Y = years < 1 ? "" : years + " Years ";
var M = months < 1 ? "" : months + " Months ";
var D = days < 1 ? "" : days + " Days ";
var H = hours < 1 ? "" : hours + " Hours ";
var I = minutes < 1 ? "" : minutes + " Minutes ";
var S = seconds < 1 ? "" : seconds + " Seconds ";
var A = years == 0 && months == 0 && days == 0 && hours == 0 && minutes == 0 && seconds == 0 ? "Sending" : " Remaining";

document.getElementById('txt').innerHTML = Y + M + D + H + I + S + A;
KratzXD
la source