Como obtenho o número de dias entre duas datas no JavaScript?


403

Como obtenho o número de dias entre duas datas no JavaScript? Por exemplo, com duas datas nas caixas de entrada:

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

<script>
  alert(datediff("day", first, second)); // what goes here?
</script>

5
99% dos casos em que o usuário solicita "número de dias entre duas datas" o que ela não entende é que está tentando comparar maçãs com peras. O problema se torna tão simples se perguntado "Quantas datas há em um intervalo de datas?" Ou quantos quadrados eu tenho que cruzar no calendário. Isso deixa de fora os problemas de horário e horário de verão, etc. A confusão está implícita em nós por causa da estrutura de dados de data e hora que é pura bobagem. Não existe tal coisa como datetime há data e há tempo, dois objetos muito distintas, tanto na natureza e comportamento
Mihail Shishkov

Para uma função que divide a diferença em unidades (inteiras) de tempo, use a resposta em stackoverflow.com/a/53092438/3787376 .
Edward

Eu acho que essa pergunta deve ser excluída ou pelo menos marcada como "evitar", pois a maioria das respostas está incorreta ou depende de várias bibliotecas.
RobG 16/03/19

Respostas:


409

Aqui está uma implementação rápida e suja de datediff, como uma prova de conceito para resolver o problema, conforme apresentado na pergunta. Ele se baseia no fato de que você pode obter os milissegundos decorridos entre duas datas subtraindo-os, o que os coage em seu valor numérico primitivo (milissegundos desde o início de 1970).

// 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"/>

Você deve estar ciente de que as APIs de data "normais" (sem "UTC" no nome) operam no fuso horário local do navegador do usuário; portanto, em geral, você pode ter problemas se o usuário estiver em um fuso horário que você não faz. espere, e seu código terá que lidar com as transições do horário de verão. Você deve ler atentamente a documentação do objeto Date e seus métodos e, para algo mais complicado, considere usar uma biblioteca que ofereça APIs mais seguras e poderosas para manipulação de datas.

Além disso, para fins de ilustração, o snippet usa acesso nomeado ao windowobjeto por questões de brevidade, mas na produção você deve usar APIs padronizadas como getElementById ou, mais provavelmente, alguma estrutura da interface do usuário.


2
Eu acho que Math.trunc () é mais apropriado. Apenas no caso de alguém usa Data objetos mais precisos (ou seja, incluindo as horas, minutos e segundos)
Jin Wang

21
Como a resposta marcada como correta e com a votação mais alta (a partir de agora), vale a pena comentar que esta resposta não trata corretamente o horário de verão. Veja a resposta de Michael Liu.
osullic 21/09/16

O que parseDate faz exatamente?
Mohammad Kermani 27/11/16

2
@ osullic - esta resposta lida com o horário de verão com Math.round , no entanto, espera que sejam entregues apenas strings de data, não data e hora.
RobG

2
Lembre-se de que a data está no formato americano neste exemplo, ou seja, MM / DD / AAAA. Se você precisa da versão do Reino Unido, então você precisa mudar o parseDatemétodo a ser:return new Date(mdy[2], mdy[1], mdy[0]-1);
Viqas

207

No momento da redação deste documento, apenas uma das outras respostas manipula corretamente as transições de horário de verão. Aqui estão os resultados em um sistema localizado na Califórnia:

                                        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

Embora Math.roundretorne os resultados corretos, acho que é um pouco desajeitado. Em vez disso, explicando explicitamente as alterações no deslocamento UTC quando o horário de verão começa ou termina, podemos usar a aritmética exata:

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

Explicação

Os cálculos de data do JavaScript são complicados porque os Dateobjetos armazenam horários internamente no UTC, e não no horário local. Por exemplo, 3/10/2013 00:00 (horário padrão do Pacífico) (UTC-08: 00) é armazenado como 10/10/2013 8:00 (UTC) e 11/03/2013 12:00 (horário do Pacífico) ( UTC-07: 00) é armazenado como 11/3/2013 07:00 UTC. Neste dia, a hora local da meia-noite à meia-noite é de apenas 23 horas no UTC!

Embora um dia no horário local possa ter mais ou menos de 24 horas, um dia no UTC é sempre exatamente 24 horas. 1 O daysBetweenmétodo mostrado acima aproveita esse fato ligando primeiro treatAsUTCpara ajustar os horários locais à meia-noite UTC, antes de subtrair e dividir.

1. JavaScript ignora segundos bissextos.


2
Não há necessidade de usar o UTC, basta definir o horário local para meia-noite (ou o mesmo valor para as duas datas). O dia fracionário introduzido pelo horário de verão é de apenas ± 0,04 no máximo (e em alguns lugares menos), portanto, termina com Math.round . ;-) Confiar no construtor Date para analisar seqüências de caracteres não é uma boa ideia. Se você realmente deseja usar valores UTC, analise as strings usando Date.UTC(...)em primeiro lugar.
RobG 17/02

2
@RobG: Como afirmei na minha resposta: "Embora o Math.round retorne os resultados corretos, acho que é um pouco desajeitado. Em vez disso, explicando explicitamente as alterações no deslocamento do UTC quando o horário de verão começa ou termina, podemos usar a aritmética exata".
Michael Liu

Na verdade, os horários que você representou como "incorretos" estão, tecnicamente, corretos. Você não está alterando o DateTimes para UTC ... está apenas alterando o horário de cada DateTime para obter um número inteiro artificial. O arredondamento não é "desajeitado" ... é exatamente a abordagem correta aqui, porque é isso que você está fazendo em sua cabeça de qualquer maneira: você está arredondando a parte do tempo (horas, minutos, segundos) e apenas tentando obter um valor inteiro número do dia.
JDB ainda se lembra de Monica

116

A maneira mais fácil de obter a diferença entre duas datas:

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

Você obtém os dias de diferença (ou NaN se um ou ambos não puderam ser analisados). A data da análise deu o resultado em milissegundos e, para obtê-lo por dia, você deve dividi-lo por 24 * 60 * 60 * 1000

Se você deseja dividir por dias, horas, minutos, segundos e milissegundos:

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

Aqui está minha versão refatorada da versão de James:

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

2
Resposta ruim. Math.floor () perderá você um dia quando os relógios avançarem no horário de verão. Math.round () dará a resposta certa na maioria das situações, mas também existem opções melhores em outras respostas.
Phil B

101

Eu recomendo usar a biblioteca moment.js ( http://momentjs.com/docs/#/displaying/difference/ ). Ele lida corretamente com o horário de verão e, em geral, é ótimo trabalhar com ele.

Exemplo:

var start = moment("2013-11-03");
var end = moment("2013-11-04");
end.diff(start, "days")
1

10
Assim como uma advertência, enquanto momentjs é grande, é uma grande dependência bastante
Jason Axelson

Realmente deve ser, end.diff(start,"days")embora o código escrito funcione porque a data de início é posterior à data de término!
gordon613

40

Eu iria em frente e pegaria esse pequeno utilitário e nele você encontrará funções para isso. Aqui está um pequeno exemplo:

        <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>

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. Definir data de início
  2. Definir data final
  3. Calcular diferença
  4. Converter milissegundos em dias

Atualização: Eu sei que isso não faz parte de suas perguntas, mas, em geral, eu não recomendaria fazer nenhum cálculo ou manipulação de data no JavaScript vanilla e preferir usar uma biblioteca como date-fns ou moment.js devido a muitos casos extremos .


5
Aprecio respostas como estas: curtas, simples e sem dependências aleatórias necessárias! Felicidades.
daCoda 24/01/19

2
Sou eu quem timeDiffretornou no negativo? Não deveria timeDiffser (new Date(endDate)) - (new Date(startDate));?
Feyisayo Sonubi 04/08/19

@ feyisayo-sonubi depende de qual ordem você passa na data de início e de término. Neste exemplo(new Date('2017-11-08')) - (new Date('2017-10-01')) // 3283200000
marcobiedermann 4/08/19

const timeDiff = +(new Date(start)) - +(new Date(end));
Ben Racicot

Ótimo. Embora eu prefirareturn (Date.UTC(yr2, mo2-1, dy2) - Date.UTC(yr1, mo1-1, dy1)) / 86400000;
dcromley

13

Usando 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>


moment.js é realmente útil para coisas como diferenças acumuladas no acumulado do ano, 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); aqui: momentjs.com
Sharif

11

Os valores de data em JS são valores de data e hora.

Portanto, cálculos de datas diretas são inconsistentes:

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

por exemplo, precisamos converter a segunda data:

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

o método pode truncar os moinhos nas duas datas:

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


9

Melhor se livrar do horário de verão, Math.ceil, Math.floor etc. usando os horários 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));

Este exemplo dá diferença 109 dias. 24*60*60*1000é um dia em milissegundos.


9

Para calcular os dias entre 2 datas, você pode usar o código a seguir. As datas que eu uso aqui são 01 de janeiro de 2016 e 31 de dezembro de 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>


9

É possível calcular uma diferença de dias completos de prova entre duas datas em diferentes ZTs usando a seguinte fórmula:

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


Esta é a resposta mais correta, você deve levar em consideração o horário de verão! Obrigado
Gisway

6

Encontrei essa pergunta quando quero calcular algumas duas datas, mas a data tem horas e minutos, modifiquei a resposta de @ michael-liu para atender às minhas necessidades e ela passou no teste.

dias de diferença 2012-12-31 23:00e 2013-01-01 01:00deve ser igual a 1. (2 horas) dias de diferença 2012-12-31 01:00e 2013-01-01 23:00deve ser igual a 1. (46 horas)

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

6
var start= $("#firstDate").datepicker("getDate");
var end= $("#SecondDate").datepicker("getDate");
var days = (end- start) / (1000 * 60 * 60 * 24);
 alert(Math.round(days));

exemplo jsfiddle :)


6

Eu acho que as soluções não estão corretas 100% Eu usaria o teto em vez do piso , a rodada funcionará, mas não é a operação correta.

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

4
Os dias podem ter mais de 24 horas e os minutos podem ter mais de 60 segundos. O uso de Math.ceil () seria uma contagem excessiva nesses casos.
Rich Dougherty

5

Que tal usar o formatDate do widget DatePicker? Você pode usá-lo para converter as datas no formato de carimbo de data / hora (milissegundos desde 01/01/1970) e depois fazer uma subtração simples.


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


11
Posso solicitar que você adicione um pouco mais de contexto à sua resposta. As respostas somente de código são difíceis de entender. Isso ajudará tanto os leitores quanto os futuros leitores, se você puder adicionar mais informações em sua postagem.
RBT 22/01

Eu queria editar, mas estava recebendo erros, eu poderia enviar a edição :(.
Noreddine Belhadj Cheikh

2
@ N.Belhadj você pode substituir todos os loops while com div simples e (%) operações mod
Mihail Shishkov

4

Esta pode não ser a solução mais elegante, mas parece responder à pergunta com um pouco de código relativamente simples, eu acho. Você não pode usar algo assim:

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

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

return dayCount; 
}

Isso pressupõe que você esteja passando objetos de data como parâmetros.


4

Se você tiver dois registros de data e hora unix, poderá usar esta função (tornada um pouco mais detalhada por uma questão de clareza):

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

Exemplo:

daysBetween(1096580303, 1308713220); // 2455

4

Tenha cuidado ao usar milissegundos .

O date.getTime () retorna milissegundos e a operação matemática com milissegundos exige a inclusão

  • Horário de Verão (DST)
  • verificando se as duas datas têm o mesmo horário (horas, minutos, segundos, milissegundos)
  • certifique-se de que comportamento de dias é necessário: 19 de setembro de 2016 a 29 de setembro de 2016 = diferença de 1 ou 2 dias?

O exemplo do comentário acima é a melhor solução que encontrei até agora https://stackoverflow.com/a/11252167/2091095 . Mas use +1 no resultado se desejar contar todos os dias envolvidos.

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;

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


3

Eu tive o mesmo problema no Angular. Eu faço a cópia, porque mais ele substituirá o primeiro encontro. Ambas as datas devem ter tempo 00:00:00 (obviamente)

 /*
* 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;
};

3

Usei o código abaixo para experimentar a funcionalidade da data de postagem de uma publicação.Eu calculo o minuto ou a hora ou o dia ou o ano com base na data de postagem e na data atual.

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

Por favor, explique seu código e você resolveu o problema, apenas colar código é considerado uma resposta ruim.
Marco Scabbiolo

2
Embora esse código possa responder à pergunta, fornecer um contexto adicional a respeito de como e / ou por que ele resolve o problema melhoraria o valor a longo prazo da resposta.
22616 Michael ParkerJul

Graças @ MarcoScabbiolo, @ Michael Parker para o comments.Since Eu sou novo para Stackoverflow em termos de eletrônica, eu não estava ciente de como a solução deve ser proivided
Ramees Rahath

3

se você quiser ter um DateArray com datas, tente o seguinte:

<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


3

A maneira simples de calcular os dias entre duas datas é remover o componente de tempo, ou seja, definir horas, minutos, segundos e milissegundos para 0 e subtrair o tempo e mergulhá-lo com milissegundos no valor de um dia.

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

O problema da sua solução é que você está assumindo firstDate e secondDate como datas em que não há necessidade de alterá-las para data novamente e, se não forem data * que não são), ocorrerá um erro em setHours. para corrigir isso, você precisa mover setHours denew 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;
}

2

Simples, fácil e sofisticado. Essa função será chamada a cada 1 segundo para atualizar o tempo.

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

1

Uma solução melhor

Ignorando parte do tempo

retornará 0 se as duas datas forem iguais.

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">


1

Uma contribuição, para data anterior a 01-01-2009 e após 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);
  })();
}

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

0

Você pode usar o UnderscoreJS para formatar e calcular a diferença.

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>

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.