Jak uzyskać liczbę dni między dwiema datami w JavaScript?

403

Jak uzyskać liczbę dni między dwiema datami w JavaScript? Na przykład podane dwie daty w polach wejściowych:

<input id="first" value="1/1/2000"/>
<input id="second" value="1/1/2001"/>

<script>
  alert(datediff("day", first, second)); // what goes here?
</script>
Michael Haren
źródło
5
99% przypadków, w których użytkownik pyta o „liczbę dni między dwiema datami”, czego nie rozumie, to to, że próbuje porównać jabłka z gruszkami. Problem staje się tak prosty, gdy zapytamy: „Ile DAT jest w ZAKRESIE DATY?” Lub Ile kwadratów muszę przekroczyć w kalendarzu. Pozostawia to problemy z czasem i czasem letnim itp. Pomieszanie jest nam przypisane z powodu struktury danych datetime, która jest czystym nonsensem. Nie ma czegoś takiego jak data i godzina, jest data i czas, dwa bardzo różne obiekty zarówno pod względem natury, jak i zachowania
Mihail Shishkov
Aby uzyskać funkcję dzielącą różnicę na (całe) jednostki czasu, użyj odpowiedzi na stackoverflow.com/a/53092438/3787376 .
Edward
Uważam, że to pytanie powinno zostać usunięte lub przynajmniej oznaczone jako „unikaj”, ponieważ większość odpowiedzi jest albo nieprawidłowa, albo zależy od różnych bibliotek.
RobG

Odpowiedzi:

409

Oto szybkie i nieprzyzwoite wdrożenie datediff, będące dowodem koncepcji rozwiązania problemu przedstawionego w pytaniu. Opiera się na fakcie, że można uzyskać upływające milisekundy między dwiema datami, odejmując je, co wymusza ich pierwotną wartość liczbową (milisekundy od początku 1970 r.).

// new Date("dateString") is browser-dependent and discouraged, so we'll write
// a simple parse function for U.S. date format (which does no error checking)
function parseDate(str) {
    var mdy = str.split('/');
    return new Date(mdy[2], mdy[0]-1, mdy[1]);
}

function datediff(first, second) {
    // Take the difference between the dates and divide by milliseconds per day.
    // Round to nearest whole number to deal with DST.
    return Math.round((second-first)/(1000*60*60*24));
}

alert(datediff(parseDate(first.value), parseDate(second.value)));
<input id="first" value="1/1/2000"/>
<input id="second" value="1/1/2001"/>

Należy pamiętać, że „normalne” interfejsy API daty (bez nazwy „UTC” w nazwie) działają w lokalnej strefie czasowej przeglądarki użytkownika, więc ogólnie możesz mieć problemy, jeśli użytkownik znajduje się w strefie czasowej, której nie znasz spodziewaj się, a Twój kod będzie musiał radzić sobie z przejściami czasu letniego. Powinieneś uważnie przeczytać dokumentację dotyczącą obiektu Date i jego metod, a w przypadku bardziej skomplikowanych przypadków zdecydowanie rozważ użycie biblioteki, która oferuje bezpieczniejsze i wydajniejsze interfejsy API do manipulowania datami.

Również w celach ilustracyjnych fragment używa nazwanego dostępu do windowobiektu dla zwięzłości, ale w produkcji należy używać standardowych interfejsów API, takich jak getElementById lub, bardziej prawdopodobne, niektóre struktury interfejsu użytkownika.

Miles
źródło
2
Myślę, że Math.trunc () jest bardziej odpowiednie. Na wypadek, gdyby ktoś użył bardziej precyzyjnych obiektów typu Data (tj. Włączając godziny, minuty i sekundy)
Jin Wang
21
Jako odpowiedź oznaczoną jako poprawną i najlepiej głosowaną (na razie), warto skomentować, że ta odpowiedź nie obsługuje czasu letniego. Zamiast tego zobacz odpowiedź Michaela Liu.
osullic
Co dokładnie robi parseDate?
Mohammad Kermani
2
@ osullic - ta odpowiedź radzi sobie z czasem letnim za pomocą Math.round , jednak oczekuje się, że będą przekazywane tylko ciągi daty, a nie data i godzina.
RobG
2
Pamiętaj tylko, że w tym przykładzie data jest w formacie amerykańskim, tj. MM / DD / RRRR. Jeśli potrzebujesz wersji brytyjskiej, musisz zmienić parseDatemetodę na:return new Date(mdy[2], mdy[1], mdy[0]-1);
Viqas
207

W chwili pisania tego tekstu tylko jedna z pozostałych odpowiedzi poprawnie obsługuje przejścia DST (czas letni). Oto wyniki dla systemu zlokalizowanego w Kalifornii:

                                        1/1/2013- 3/10/2013- 11/3/2013-
User       Formula                      2/1/2013  3/11/2013  11/4/2013  Result
---------  ---------------------------  --------  ---------  ---------  ---------
Miles                   (d2 - d1) / N   31        0.9583333  1.0416666  Incorrect
some         Math.floor((d2 - d1) / N)  31        0          1          Incorrect
fuentesjr    Math.round((d2 - d1) / N)  31        1          1          Correct
toloco     Math.ceiling((d2 - d1) / N)  31        1          2          Incorrect

N = 86400000

Chociaż Math.roundzwraca poprawne wyniki, myślę, że jest trochę niezgrabny. Zamiast tego, jawnie rozliczając zmiany przesunięcia UTC, gdy DST zaczyna się lub kończy, możemy użyć dokładnej arytmetyki:

function treatAsUTC(date) {
    var result = new Date(date);
    result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
    return result;
}

function daysBetween(startDate, endDate) {
    var millisecondsPerDay = 24 * 60 * 60 * 1000;
    return (treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay;
}

alert(daysBetween($('#first').val(), $('#second').val()));

Wyjaśnienie

Obliczanie daty w JavaScript jest trudne, ponieważ Dateobiekty przechowują czasy wewnętrznie w UTC, a nie w czasie lokalnym. Na przykład 03.10.2013 12:00 czasu pacyficznego (UTC-08: 00) jest zapisywany jako 3/10/2013 8:00 UTC, a 03.11.2013 12:00 czasu pacyficznego ( UTC-07: 00) jest przechowywany jako 3/11/2013 7:00 AM UTC. Tego dnia od północy do północy czasu lokalnego jest tylko 23 godziny w UTC!

Chociaż dzień w czasie lokalnym może trwać mniej więcej 24 godziny, dzień w UTC jest zawsze dokładnie 24 godziny. 1 ThedaysBetween sposób przedstawiony powyżej wykorzystuje ten fakt przez pierwsze powołanie treatAsUTCdo regulacji zarówno razy lokalne do północy UTC, zanim odejmowanie i dzielenie.

1. JavaScript ignoruje sekundy przestępne.

Michael Liu
źródło
2
Nie ma potrzeby korzystania z UTC, wystarczy ustawić lokalne godziny na północ (lub taką samą wartość dla obu dat). Dzień ułamkowy wprowadzony za pomocą czasu letniego wynosi najwyżej tylko ± 0,04 (aw niektórych miejscach mniej), więc uzupełnia Math.round . ;-) Wykorzystywanie konstruktora daty do analizowania ciągów nie jest dobrym pomysłem. Jeśli naprawdę chcesz użyć wartości UTC, Date.UTC(...)najpierw przeanalizuj ciągi znaków .
RobG
2
@RobG: Jak powiedziałem w mojej odpowiedzi: „Mimo że Math.round zwraca poprawne wyniki, myślę, że jest nieco niezręczny. Zamiast tego, jawnie uwzględniając zmiany przesunięcia UTC, gdy DST zaczyna się lub kończy, możemy użyć dokładnej arytmetyki”.
Michael Liu
W rzeczywistości czasy, które przedstawiłeś jako „niepoprawne”, są technicznie poprawne. Nie zmieniasz DateTimes na UTC ... po prostu zmieniasz czas każdego DateTime, aby uzyskać sztuczną liczbę całkowitą. Zaokrąglanie nie jest „niezgrabne” ... jest to dokładnie poprawne podejście, ponieważ i tak to robisz w głowie: zaokrąglasz część czasu (godziny, minuty, sekundy) i po prostu próbujesz uzyskać całość numer dnia
JDB wciąż pamięta Monikę
116

Najłatwiejszy sposób na uzyskanie różnicy między dwiema datami:

var diff =  Math.floor(( Date.parse(str2) - Date.parse(str1) ) / 86400000); 

Otrzymujesz różnicę dni (lub NaN, jeśli nie można przeanalizować jednego lub obu). Data analizy dała wynik w milisekundach. Aby uzyskać go w ciągu dnia, należy go podzielić przez 24 * 60 * 60 * 1000

Jeśli chcesz podzielić go na dni, godziny, minuty, sekundy i milisekundy:

function dateDiff( str1, str2 ) {
    var diff = Date.parse( str2 ) - Date.parse( str1 ); 
    return isNaN( diff ) ? NaN : {
        diff : diff,
        ms : Math.floor( diff            % 1000 ),
        s  : Math.floor( diff /     1000 %   60 ),
        m  : Math.floor( diff /    60000 %   60 ),
        h  : Math.floor( diff /  3600000 %   24 ),
        d  : Math.floor( diff / 86400000        )
    };
}

Oto moja refaktoryzowana wersja Jamesa:

function mydiff(date1,date2,interval) {
    var second=1000, minute=second*60, hour=minute*60, day=hour*24, week=day*7;
    date1 = new Date(date1);
    date2 = new Date(date2);
    var timediff = date2 - date1;
    if (isNaN(timediff)) return NaN;
    switch (interval) {
        case "years": return date2.getFullYear() - date1.getFullYear();
        case "months": return (
            ( date2.getFullYear() * 12 + date2.getMonth() )
            -
            ( date1.getFullYear() * 12 + date1.getMonth() )
        );
        case "weeks"  : return Math.floor(timediff / week);
        case "days"   : return Math.floor(timediff / day); 
        case "hours"  : return Math.floor(timediff / hour); 
        case "minutes": return Math.floor(timediff / minute);
        case "seconds": return Math.floor(timediff / second);
        default: return undefined;
    }
}
trochę
źródło
2
Zła odpowiedź. Math.floor () straci cię dzień, gdy zegary idą do przodu w czasie letnim. Math.round () poda prawidłową odpowiedź w większości sytuacji, ale w innych odpowiedziach są też lepsze opcje.
Phil B,
101

Polecam korzystanie z biblioteki moment.js ( http://momentjs.com/docs/#/displaying/difference/ ). Prawidłowo radzi sobie z czasem letnim i ogólnie jest świetny do pracy.

Przykład:

var start = moment("2013-11-03");
var end = moment("2013-11-04");
end.diff(start, "days")
1
Stephenbez
źródło
10
Jako ostrzeżenie, choć momentjs jest świetny, jest to dość duża zależność
Jason Axelson
Tak naprawdę powinno być, end.diff(start,"days")chociaż napisany kod będzie działał, ponieważ data początkowa jest późniejsza niż data końcowa!
gordon613
40

Pójdę do przodu i wezmę to małe narzędzie, w którym znajdziesz dla niego funkcje. Oto krótki przykład:

        <script type="text/javascript" src="date.js"></script>
        <script type="text/javascript">
            var minutes = 1000*60;
            var hours = minutes*60;
            var days = hours*24;

            var foo_date1 = getDateFromFormat("02/10/2009", "M/d/y");
            var foo_date2 = getDateFromFormat("02/12/2009", "M/d/y");

            var diff_date = Math.round((foo_date2 - foo_date1)/days);
            alert("Diff date is: " + diff_date );
        </script>
fuentesjr
źródło
28
const startDate = '2017-11-08';
const endDate   = '2017-10-01';
const timeDiff  = (new Date(startDate)) - (new Date(endDate));
const days      = timeDiff / (1000 * 60 * 60 * 24)
  1. Ustaw datę początkową
  2. Ustaw datę zakończenia
  3. Oblicz różnicę
  4. Konwertuj milisekundy na dni

Aktualizacja: Wiem, że nie jest to częścią twoich pytań, ale ogólnie nie zalecałbym wykonywania żadnych obliczeń ani manipulacji datą w waniliowym JavaScript, a raczej do tego używaj biblioteki typu date-fns lub moment.js z powodu wielu przypadków krawędzi.

marcobiedermann
źródło
5
Doceniam takie odpowiedzi: krótkie, proste i nie są wymagane losowe zależności! Twoje zdrowie.
daCoda
2
Czy to tylko ja timeDiffpowróciłem przecząco? Nie powinno timeDiffbyć (new Date(endDate)) - (new Date(startDate));?
Feyisayo Sonubi
@ feyisayo-sonubi zależy od tego, w jakiej kolejności przekazujesz datę rozpoczęcia i zakończenia. W tym przykładzie(new Date('2017-11-08')) - (new Date('2017-10-01')) // 3283200000
marcobiedermann
const timeDiff = +(new Date(start)) - +(new Date(end));
Ben Racicot
Świetny. Chociaż wolęreturn (Date.UTC(yr2, mo2-1, dy2) - Date.UTC(yr1, mo1-1, dy1)) / 86400000;
dcromley
13

Korzystanie z Moment.js

var future = moment('05/02/2015');
var start = moment('04/23/2015');
var d = future.diff(start, 'days'); // 9
console.log(d);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment-with-locales.min.js"></script>

Michael K.
źródło
moment.js jest naprawdę przydatny w takich rzeczach, jak różnice w YTD, var now = moment(), yearStart = moment().startOf('year'); var ytdDays = now.diff(yearStart, 'days'); // this can be years, months, weeks, days, hours, minutes, and seconds console.log(ytdDays); więcej tutaj: momentjs.com
Sharif
10

Wartości daty w JS są wartościami daty i godziny.

Zatem bezpośrednie obliczenia daty są niespójne:

(2013-11-05 00:00:00) - (2013-11-04 10:10:10) < 1 day

na przykład musimy przekonwertować drugą datę:

(2013-11-05 00:00:00) - (2013-11-04 00:00:00) = 1 day

metoda może obciąć młyny w obu datach:

var date1 = new Date('2013/11/04 00:00:00');
var date2 = new Date('2013/11/04 10:10:10'); //less than 1
var start = Math.floor(date1.getTime() / (3600 * 24 * 1000)); //days as integer from..
var end = Math.floor(date2.getTime() / (3600 * 24 * 1000)); //days as integer from..
var daysDiff = end - start; // exact dates
console.log(daysDiff);

date2 = new Date('2013/11/05 00:00:00'); //1

var start = Math.floor(date1.getTime() / (3600 * 24 * 1000)); //days as integer from..
var end = Math.floor(date2.getTime() / (3600 * 24 * 1000)); //days as integer from..
var daysDiff = end - start; // exact dates
console.log(daysDiff);

Norris
źródło
9

Lepiej pozbyć się DST, Math.ceil, Math.floor itp., Używając czasów UTC:

var firstDate = Date.UTC(2015,01,2);
var secondDate = Date.UTC(2015,04,22);
var diff = Math.abs((firstDate.valueOf() 
    - secondDate.valueOf())/(24*60*60*1000));

Ten przykład daje różnicę 109 dni. 24*60*60*1000jest jeden dzień w milisekundach.

Timo Kähkönen
źródło
9

Aby obliczyć dni między 2 podanymi datami, możesz użyć następującego kodu. Daty, których tu używam, to 01 stycznia 2016 i 31 grudnia 2016

var day_start = new Date("Jan 01 2016");
var day_end = new Date("Dec 31 2016");
var total_days = (day_end - day_start) / (1000 * 60 * 60 * 24);
document.getElementById("demo").innerHTML = Math.round(total_days);
<h3>DAYS BETWEEN GIVEN DATES</h3>
<p id="demo"></p>

NooNa MarJa
źródło
9

Można obliczyć różnicę dni pełnego dowodu między dwiema datami spoczywającymi w różnych strefach czasowych przy użyciu następującego wzoru:

var start = new Date('10/3/2015');
var end = new Date('11/2/2015');
var days = (end - start) / 1000 / 60 / 60 / 24;
console.log(days);
// actually its 30 ; but due to daylight savings will show 31.0xxx
// which you need to offset as below
days = days - (end.getTimezoneOffset() - start.getTimezoneOffset()) / (60 * 24);
console.log(days);

riv
źródło
To jest najbardziej poprawna odpowiedź, należy wziąć pod uwagę czas letni! Dzięki
Gisway,
6

Znalazłem to pytanie, gdy chcę wykonać obliczenia na dwóch datach, ale data ma wartość godzin i minut, zmodyfikowałem odpowiedź @ michael-liu, aby dopasować ją do moich wymagań, i przeszła mój test.

różne dni 2012-12-31 23:00 i 2013-01-01 01:00powinna wynosić 1. (2 godziny) diff dni 2012-12-31 01:00i 2013-01-01 23:00powinna wynosić 1. (46 godzin)

function treatAsUTC(date) {
    var result = new Date(date);
    result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
    return result;
}

var millisecondsPerDay = 24 * 60 * 60 * 1000;
function diffDays(startDate, endDate) {
    return Math.floor(treatAsUTC(endDate) / millisecondsPerDay) - Math.floor(treatAsUTC(startDate) / millisecondsPerDay);
}
guilin 桂林
źródło
6
var start= $("#firstDate").datepicker("getDate");
var end= $("#SecondDate").datepicker("getDate");
var days = (end- start) / (1000 * 60 * 60 * 24);
 alert(Math.round(days));

przykład jsfiddle :)

Aravindh Gopi
źródło
6

Myślę, że rozwiązania nie są poprawne 100% Chciałbym użyć sufitu zamiast podłogi , okrągły zadziała, ale to nie jest właściwa operacja.

function dateDiff(str1, str2){
    var diff = Date.parse(str2) - Date.parse(str1); 
    return isNaN(diff) ? NaN : {
        diff: diff,
        ms: Math.ceil(diff % 1000),
        s: Math.ceil(diff / 1000 % 60),
        m: Math.ceil(diff / 60000 % 60),
        h: Math.ceil(diff / 3600000 % 24),
        d: Math.ceil(diff / 86400000)
    };
}
Tolo Palmer
źródło
4
Dni mogą trwać dłużej niż 24 godziny, a minuty mogą trwać dłużej niż 60 sekund. Użycie Math.ceil () w tych przypadkach przeliczyłoby się.
Rich Dougherty,
5

Co powiesz na użycie formatDate z widżetu DatePicker? Można go użyć do konwersji dat w formacie znacznika czasu (w milisekundach od 01.01.1970), a następnie wykonać proste odejmowanie.

kgiannakakis
źródło
5

function timeDifference(date1, date2) {
  var oneDay = 24 * 60 * 60; // hours*minutes*seconds
  var oneHour = 60 * 60; // minutes*seconds
  var oneMinute = 60; // 60 seconds
  var firstDate = date1.getTime(); // convert to milliseconds
  var secondDate = date2.getTime(); // convert to milliseconds
  var seconds = Math.round(Math.abs(firstDate - secondDate) / 1000); //calculate the diffrence in seconds
  // the difference object
  var difference = {
    "days": 0,
    "hours": 0,
    "minutes": 0,
    "seconds": 0,
  }
  //calculate all the days and substract it from the total
  while (seconds >= oneDay) {
    difference.days++;
    seconds -= oneDay;
  }
  //calculate all the remaining hours then substract it from the total
  while (seconds >= oneHour) {
    difference.hours++;
    seconds -= oneHour;
  }
  //calculate all the remaining minutes then substract it from the total 
  while (seconds >= oneMinute) {
    difference.minutes++;
    seconds -= oneMinute;
  }
  //the remaining seconds :
  difference.seconds = seconds;
  //return the difference object
  return difference;
}
console.log(timeDifference(new Date(2017,0,1,0,0,0),new Date()));

Noreddine Belhadj Cheikh
źródło
1
Czy mogę prosić o dodanie dodatkowego kontekstu wokół odpowiedzi? Odpowiedzi zawierające tylko kod są trudne do zrozumienia. Pomoże zarówno pytającemu, jak i przyszłym czytelnikom, czy możesz dodać więcej informacji w swoim poście.
RBT
chciałem edytować, ale otrzymywałem błędy, mogłem przesłać edycję :(.
Noreddine Belhadj Cheikh
2
@ N.Belhadj możesz zastąpić wszystkie te pętle while prostymi operacjami div i mod (%)
Mihail Shishkov
4

To może nie być najbardziej eleganckie rozwiązanie, ale wydaje mi się, że odpowiada na to pytanie za pomocą stosunkowo prostego fragmentu kodu. Nie możesz użyć czegoś takiego:

function dayDiff(startdate, enddate) {
  var dayCount = 0;

  while(enddate >= startdate) {
    dayCount++;
    startdate.setDate(startdate.getDate() + 1);
  }

return dayCount; 
}

Zakłada się, że przekazujesz obiekty daty jako parametry.

Popmatic
źródło
4

Jeśli masz dwa uniksowe znaczniki czasu, możesz użyć tej funkcji (nieco bardziej szczegółowej ze względu na przejrzystość):

// Calculate number of days between two unix timestamps
// ------------------------------------------------------------
var daysBetween = function(timeStampA, timeStampB) {
    var oneDay = 24 * 60 * 60 * 1000; // hours * minutes * seconds * milliseconds
    var firstDate = new Date(timeStampA * 1000);
    var secondDate = new Date(timeStampB * 1000);
    var diffDays = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay)));
    return diffDays;
};

Przykład:

daysBetween(1096580303, 1308713220); // 2455
Wallace Sidhrée
źródło
4

Zachowaj ostrożność podczas używania milisekund .

Metoda date.getTime () zwraca milisekundy, a wykonywanie operacji matematycznych z milisekundami wymaga uwzględnienia

  • Czas letni (DST)
  • sprawdzanie, czy obie daty mają ten sam czas (godziny, minuty, sekundy, milisekundy)
  • upewnij się, jakie zachowanie różnic dni jest wymagane: 19 września 2016 r. - 29 września 2016 r. = różnica 1 lub 2 dni?

Przykład z powyższego komentarza jest najlepszym rozwiązaniem, jakie do tej pory znalazłem https://stackoverflow.com/a/11252167/2091095 . Ale użyj +1 do jego wyniku, jeśli chcesz liczyć wszystkie zaangażowane dni.

function treatAsUTC(date) {
    var result = new Date(date);
    result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
    return result;
}

function daysBetween(startDate, endDate) {
    var millisecondsPerDay = 24 * 60 * 60 * 1000;
    return (treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay;
}

var diff = daysBetween($('#first').val(), $('#second').val()) + 1;
Dalibor Matura
źródło
4

Date.prototype.days = function(to) {
  return Math.abs(Math.floor(to.getTime() / (3600 * 24 * 1000)) - Math.floor(this.getTime() / (3600 * 24 * 1000)))
}


console.log(new Date('2014/05/20').days(new Date('2014/05/23'))); // 3 days

console.log(new Date('2014/05/23').days(new Date('2014/05/20'))); // 3 days

Abdennour TOUMI
źródło
3

Miałem ten sam problem w Angular. Robię kopię, bo inaczej zastąpi pierwszą randkę. Obie daty muszą mieć czas 00:00:00 (oczywiście)

 /*
* Deze functie gebruiken we om het aantal dagen te bereken van een booking.
* */
$scope.berekenDagen = function ()
{
    $scope.booking.aantalDagen=0;

    /*De loper is gelijk aan de startdag van je reservatie.
     * De copy is nodig anders overschijft angular de booking.van.
     * */
    var loper = angular.copy($scope.booking.van);

    /*Zolang de reservatie beschikbaar is, doorloop de weekdagen van je start tot einddatum.*/
    while (loper < $scope.booking.tot) {
        /*Tel een dag op bij je loper.*/
        loper.setDate(loper.getDate() + 1);
        $scope.booking.aantalDagen++;
    }

    /*Start datum telt natuurlijk ook mee*/
    $scope.booking.aantalDagen++;
    $scope.infomsg +=" aantal dagen: "+$scope.booking.aantalDagen;
};
użytkownik3806549
źródło
3

Użyłem poniższego kodu, aby wypróbować funkcjonalność daty opublikowania wiadomości. Obliczam minutę, godzinę, dzień lub rok na podstawie daty i bieżącej daty.

var startDate= new Date("Mon Jan 01 2007 11:00:00");
var endDate  =new Date("Tue Jan 02 2007 12:50:00");
var timeStart = startDate.getTime();
var timeEnd = endDate.getTime();
var yearStart = startDate.getFullYear();
var yearEnd   = endDate.getFullYear();
if(yearStart == yearEnd)
 {
  var hourDiff = timeEnd - timeStart; 
  var secDiff = hourDiff / 1000;
  var minDiff = hourDiff / 60 / 1000; 
  var hDiff = hourDiff / 3600 / 1000; 
  var myObj = {};
  myObj.hours = Math.floor(hDiff);
  myObj.minutes = minDiff  
  if(myObj.hours >= 24)
   {
    console.log(Math.floor(myObj.hours/24) + "day(s) ago")
   } 
 else if(myObj.hours>0)
  {
   console.log(myObj.hours +"hour(s) ago")
  }
 else
  {
   console.log(Math.abs(myObj.minutes) +"minute(s) ago")
  }
}
else
{
var yearDiff = yearEnd - yearStart;
console.log( yearDiff +" year(s) ago");
}
Ramees Rahath
źródło
Proszę wyjaśnić swój kod, a problem został rozwiązany, samo wklejenie kodu jest uważane za złą odpowiedź.
Marco Scabbiolo,
2
Chociaż ten kod może odpowiedzieć na pytanie, zapewnienie dodatkowego kontekstu dotyczącego tego, jak i / lub dlaczego rozwiązuje problem, poprawiłoby długoterminową wartość odpowiedzi.
Michael Parker,
Dziękuję @ MarcoScabbiolo, @ Michael Parker za komentarze. Ponieważ jestem nowy w Stackoverflow w zakresie odpowiadania, nie byłem świadomy tego, jak należy zapewnić rozwiązanie
Ramees Rahath,
3

jeśli chcesz mieć DateArray z datami, spróbuj tego:

<script>
        function getDates(startDate, stopDate) {
        var dateArray = new Array();
        var currentDate = moment(startDate);
        dateArray.push( moment(currentDate).format('L'));

        var stopDate = moment(stopDate);
        while (dateArray[dateArray.length -1] != stopDate._i) {
            dateArray.push( moment(currentDate).format('L'));
            currentDate = moment(currentDate).add(1, 'days');
        }
        return dateArray;
      }
</script>

DebugSnippet

Ricardo Fercher
źródło
3

Prostym sposobem obliczania dni między dwiema datami jest usunięcie obu ich składników czasu, tj. Ustawienie godzin, minut, sekund i milisekund na 0, a następnie odjęcie czasu i nurkowanie go z milisekundami o wartości jednego dnia.

var firstDate= new Date(firstDate.setHours(0,0,0,0));
var secondDate= new Date(secondDate.setHours(0,0,0,0));
var timeDiff = firstDate.getTime() - secondDate.getTime();
var diffDays =timeDiff / (1000 * 3600 * 24);
Sriman Pathy
źródło
Problem w tym rozwiązaniu polega na tym, że zakładasz, że firstDate i secondDate są datami, więc nie ma potrzeby zmiany ich ponownie na datę, a jeśli nie są to daty *, które nie są), otrzymasz błąd w setHours. aby to naprawić, musisz przenieść setHours pozanew Date
AaA
2
function formatDate(seconds, dictionary) {
    var foo = new Date;
    var unixtime_ms = foo.getTime();
    var unixtime = parseInt(unixtime_ms / 1000);
    var diff = unixtime - seconds;
    var display_date;
    if (diff <= 0) {
        display_date = dictionary.now;
    } else if (diff < 60) {
        if (diff == 1) {
            display_date = diff + ' ' + dictionary.second;
        } else {
            display_date = diff + ' ' + dictionary.seconds;
        }
    } else if (diff < 3540) {
        diff = Math.round(diff / 60);
        if (diff == 1) {
            display_date = diff + ' ' + dictionary.minute;
        } else {
            display_date = diff + ' ' + dictionary.minutes;
        }
    } else if (diff < 82800) {
        diff = Math.round(diff / 3600);
        if (diff == 1) {
            display_date = diff + ' ' + dictionary.hour;
        } else {
            display_date = diff + ' ' + dictionary.hours;
        }
    } else {
        diff = Math.round(diff / 86400);
        if (diff == 1) {
            display_date = diff + ' ' + dictionary.day;
        } else {
            display_date = diff + ' ' + dictionary.days;
        }
    }
    return display_date;
}
zloctb
źródło
2

Prosty łatwy i wyrafinowany. Ta funkcja będzie wywoływana co 1 sekundę w celu aktualizacji czasu.

const year = (new Date().getFullYear());
const bdayDate = new Date("04,11,2019").getTime();  //mmddyyyy

// countdown
let timer = setInterval(function() {

// get today's date
const today = new Date().getTime();

// get the difference
const diff = bdayDate - today;

// math
let days = Math.floor(diff / (1000 * 60 * 60 * 24));
let hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((diff % (1000 * 60)) / 1000);

}, 1000);
OhhhThatVarun
źródło
1

Lepsze rozwiązanie

Ignorowanie części czasu

zwróci 0, jeśli obie daty są takie same.

function dayDiff(firstDate, secondDate) {
  firstDate = new Date(firstDate);
  secondDate = new Date(secondDate);
  if (!isNaN(firstDate) && !isNaN(secondDate)) {
    firstDate.setHours(0, 0, 0, 0); //ignore time part
    secondDate.setHours(0, 0, 0, 0); //ignore time part
    var dayDiff = secondDate - firstDate;
    dayDiff = dayDiff / 86400000; // divide by milisec in one day
    console.log(dayDiff);
  } else {
    console.log("Enter valid date.");
  }
}

$(document).ready(function() {
  $('input[type=datetime]').datepicker({
    dateFormat: "mm/dd/yy",
    changeMonth: true,
    changeYear: true
  });
  $("#button").click(function() {
    dayDiff($('#first').val(), $('#second').val());
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<input type="datetime" id="first" value="12/28/2016" />
<input type="datetime" id="second" value="12/28/2017" />
<input type="button" id="button" value="Calculate">

Sumit Joshi
źródło
1

Wkład za datę przed 1970-01-01 i po 2038-01-19

function DateDiff(aDate1, aDate2) {
  let dDay = 0;
  this.isBissexto = (aYear) => {
    return (aYear % 4 == 0 && aYear % 100 != 0) || (aYear % 400 == 0);
  };
  this.getDayOfYear = (aDate) => {
    let count = 0;
    for (let m = 0; m < aDate.getUTCMonth(); m++) {
      count += m == 1 ? this.isBissexto(aDate.getUTCFullYear()) ? 29 : 28 : /(3|5|8|10)/.test(m) ? 30 : 31;
    }
    count += aDate.getUTCDate();
    return count;
  };
  this.toDays = () => {
    return dDay;
  };
  (() => {
    let startDate = aDate1.getTime() <= aDate2.getTime() ? new Date(aDate1.toISOString()) : new Date(aDate2.toISOString());
    let endDate = aDate1.getTime() <= aDate2.getTime() ? new Date(aDate2.toISOString()) : new Date(aDate1.toISOString());
    while (startDate.getUTCFullYear() != endDate.getUTCFullYear()) {
      dDay += (this.isBissexto(startDate.getFullYear())? 366 : 365) - this.getDayOfYear(startDate) + 1;
      startDate = new Date(startDate.getUTCFullYear()+1, 0, 1);
    }
    dDay += this.getDayOfYear(endDate) - this.getDayOfYear(startDate);
  })();
}
Adelson Silva Couto
źródło
0
   function validateDate() {
        // get dates from input fields
        var startDate = $("#startDate").val();
        var endDate = $("#endDate").val();
        var sdate = startDate.split("-");
        var edate = endDate.split("-");
        var diffd = (edate[2] - sdate[2]) + 1;
        var leap = [ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
        var nonleap = [ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
        if (sdate[0] > edate[0]) {
            alert("Please enter End Date Year greater than Start Date Year");
            document.getElementById("endDate").value = "";
            diffd = "";
        } else if (sdate[1] > edate[1]) {
            alert("Please enter End Date month greater than Start Date month");
            document.getElementById("endDate").value = "";
            diffd = "";
        } else if (sdate[2] > edate[2]) {
            alert("Please enter End Date greater than Start Date");
            document.getElementById("endDate").value = "";
            diffd = "";
        } else {
            if (sdate[0] / 4 == 0) {
                while (sdate[1] < edate[1]) {
                    diffd = diffd + leap[sdate[1]++];
                }
            } else {
                while (sdate[1] < edate[1]) {
                    diffd = diffd + nonleap[sdate[1]++];
                }
            }
            document.getElementById("numberOfDays").value = diffd;
        }
    }
Parmanand Shete
źródło
0

Możesz użyć UnderscoreJS do formatowania i obliczania różnicy.

Demo https://jsfiddle.net/sumitridhal/8sv94msp/

 var startDate = moment("2016-08-29T23:35:01");
var endDate = moment("2016-08-30T23:35:01");  
  

console.log(startDate);
console.log(endDate);

var resultHours = endDate.diff(startDate, 'hours', true);

document.body.innerHTML = "";
document.body.appendChild(document.createTextNode(resultHours));
body { white-space: pre; font-family: monospace; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"></script>

Sumit Ridhal
źródło