Como faço para obter a diferença entre duas datas em JavaScript?

111

Estou criando um aplicativo que permite definir eventos com um intervalo de tempo. Desejo preencher automaticamente a data de término quando o usuário seleciona ou altera a data de início. Não consigo descobrir, no entanto, como obter a diferença entre os dois tempos e, em seguida, como criar uma nova data de término usando essa diferença.

bdukes
fonte

Respostas:

73

Em JavaScript, as datas podem ser transformadas no número de milissegundos desde a epoc chamando o getTime()método ou apenas usando a data em uma expressão numérica.

Portanto, para obter a diferença, basta subtrair as duas datas.

Para criar uma nova data com base na diferença, basta passar o número de milissegundos no construtor.

var oldBegin = ...
var oldEnd = ...
var newBegin = ...

var newEnd = new Date(newBegin + oldEnd - oldBegin);

Isso deve funcionar

EDIT : Bug corrigido apontado por @bdukes

EDITAR :

Para obter uma explicação do comportamento, oldBegin, oldEnd, e newBeginsão Dateexemplos. Chamar operadores +e -irá acionar a conversão automática de Javascript e chamará automaticamente o valueOf()método de protótipo desses objetos. Acontece que o valueOf()método é implementado no Dateobjeto como uma chamada para getTime().

Então, basicamente: date.getTime() === date.valueOf() === (0 + date) === (+date)

Vincent Robert
fonte
Qual é o formato necessário para .getTime () funcionar ... Por exemplo - new Date ('22 -12-2012 00:00 '). GetTime () não funcionará ... Alguma ideia?
Jimmyt1988
1
Para análise de data em JS, sugiro que você dê uma olhada nesta pergunta: stackoverflow.com/questions/1576753/…
Vincent Robert
8
OldBegin, oldEnd e NewBegin deveriam ser Dateobjetos? É difícil dizer que tipo de objeto eles deveriam ser, uma vez que a declaração da variável foi omitida aqui.
Anderson Green
Além disso, há uma função que você pode usar para adicionar ou subtrair datas em JavaScript: stackoverflow.com/a/1214753/975097
Anderson Green
Tenha cuidado ao adicionar números e dias. Veja minha resposta abaixo para explicação
Dan
24

JavaScript suporta perfeitamente a diferença de data fora da caixa

var msMinute = 60*1000, 
    msDay = 60*60*24*1000,
    a = new Date(2012, 2, 12, 23, 59, 59),
    b = new Date("2013 march 12");


console.log(Math.floor((b - a) / msDay) + ' full days between');
console.log(Math.floor(((b - a) % msDay) / msMinute) + ' full minutes between');

Agora, algumas armadilhas. Experimente isto:

console.log(a - 10);
console.log(a + 10);

Portanto, se você corre o risco de adicionar um número e uma data, converta a data para numberdiretamente.

console.log(a.getTime() - 10);
console.log(a.getTime() + 10);

Meu primeiro exemplo demonstra o poder do objeto Date, mas na verdade parece ser uma bomba-relógio

Dan
fonte
Dan, achei seu exemplo o mais fácil de entender e seguir. Obrigado.
Melanie
5
As "armadilhas" são, na verdade, padrões baseados na especificação da linguagem. O operador de subtração -força os argumentos para número, portanto, a Data retorna seu valor de tempo. O +operador está sobrecarregado, então pode fazer adição, coerção para número ou concatenação. Visto que as datas obrigam a String neste caso, +faz a concatenação. A confusão não é culpa do objeto Date, mas da sobrecarga dos operadores.
RobG
9

Veja JsFiddle DEMO

    var date1 = new Date();    
    var date2 = new Date("2025/07/30 21:59:00");
    //Customise date2 for your required future time

    showDiff();

function showDiff(date1, date2){

    var diff = (date2 - date1)/1000;
    diff = Math.abs(Math.floor(diff));

    var days = Math.floor(diff/(24*60*60));
    var leftSec = diff - days * 24*60*60;

    var hrs = Math.floor(leftSec/(60*60));
    var leftSec = leftSec - hrs * 60*60;

    var min = Math.floor(leftSec/(60));
    var leftSec = leftSec - min * 60;

    document.getElementById("showTime").innerHTML = "You have " + days + " days " + hrs + " hours " + min + " minutes and " + leftSec + " seconds before death.";

setTimeout(showDiff,1000);
}

para o seu código HTML:

<div id="showTime"></div>
tika
fonte
4

Se você não se preocupa com o componente de tempo, você pode usar .getDate()e .setDate()apenas para definir a parte da data.

Portanto, para definir a data de término para 2 semanas após a data de início, faça algo assim:

function GetEndDate(startDate)
{
    var endDate = new Date(startDate.getTime());
    endDate.setDate(endDate.getDate()+14);
    return endDate;
}

Para retornar a diferença (em dias) entre duas datas, faça o seguinte:

function GetDateDiff(startDate, endDate)
{
    return endDate.getDate() - startDate.getDate();
}

Por fim, vamos modificar a primeira função para que possa tomar o valor retornado por 2nd como parâmetro:

function GetEndDate(startDate, days)
{
    var endDate = new Date(startDate.getTime());
    endDate.setDate(endDate.getDate() + days);
    return endDate;
}
Joel Coehoorn
fonte
31
GetDateDiff()quebrará as barreiras do mês. Por exemplo, 2011/04/26 e 2011/05/01 retornarão -25, mas o deslocamento deve ser de 5 dias.
nfm
var ds = nova data (2014, 0, 31, 0, 0, 0, 0); var de = nova data (2014, 2, 31, 0, 0, 0, 0); GetDateDiff (ds, de) return 0
Noor
3

Obrigado @ Vincent Robert , acabei usando seu exemplo básico, embora seja na verdade newBegin + oldEnd - oldBegin. Esta é a solução final simplificada:

    // don't update end date if there's already an end date but not an old start date
    if (!oldEnd || oldBegin) {
        var selectedDateSpan = 1800000; // 30 minutes
        if (oldEnd) {
            selectedDateSpan = oldEnd - oldBegin;
        }

       newEnd = new Date(newBegin.getTime() + selectedDateSpan));
    }
bdukes
fonte
1
É um bom ponto explicar por que você às vezes está usando getTimee às vezes não
Dan
2

Dependendo de suas necessidades, esta função irá calcular a diferença entre os 2 dias e retornar um resultado em dias decimais.

// This one returns a signed decimal. The sign indicates past or future.

this.getDateDiff = function(date1, date2) {
    return (date1.getTime() - date2.getTime()) / (1000 * 60 * 60 * 24);
}

// This one always returns a positive decimal. (Suggested by Koen below)

this.getDateDiff = function(date1, date2) {
    return Math.abs((date1.getTime() - date2.getTime()) / (1000 * 60 * 60 * 24));
}
aranha brilhante
fonte
1
Faça uma Math.abs()chamada e você sempre obterá uma casa decimal positiva.
Koen.
1
Boa sugestão, Koen. Isso dá às pessoas 2 opções: apenas a diferença de data verdadeira como você sugeriu, ou um datediff com o sinal indicando se a diferença está no passado ou no futuro. :)
sparkyspider
Observe que em JavaScript você também pode adicionar / subtrair um número em milissegundos date.getTime()para obter o tempo no futuro / passado. `var nextMinute = new Date (someDate.getTime () + 60 * 1000);
Dan
Este é um erro de digitação? "entre os 2 dias". Provavelmente entre 2 datas.
tomazahlin de
2

Se estiver usando o moment.js, existe uma solução mais simples, que lhe dará a diferença em dias em uma única linha de código.

moment(endDate).diff(moment(beginDate), 'days');

Detalhes adicionais podem ser encontrados na página moment.js

Saúde Miguel

Miguel Guardo
fonte
1
function compare()
{
  var end_actual_time    = $('#date3').val();

  start_actual_time = new Date();
  end_actual_time = new Date(end_actual_time);

  var diff = end_actual_time-start_actual_time;

  var diffSeconds = diff/1000;
  var HH = Math.floor(diffSeconds/3600);
  var MM = Math.floor(diffSeconds%3600)/60;

  var formatted = ((HH < 10)?("0" + HH):HH) + ":" + ((MM < 10)?("0" + MM):MM)
  getTime(diffSeconds);
}
function getTime(seconds) {
  var days = Math.floor(leftover / 86400);

  //how many seconds are left
  leftover = leftover - (days * 86400);

  //how many full hours fits in the amount of leftover seconds
  var hours = Math.floor(leftover / 3600);

  //how many seconds are left
  leftover = leftover - (hours * 3600);

  //how many minutes fits in the amount of leftover seconds
  var minutes = leftover / 60;

  //how many seconds are left
  //leftover = leftover - (minutes * 60);
  alert(days + ':' + hours + ':' + minutes);
}
Dheerendra
fonte
1

código estendido de modificação alternativa.

http://jsfiddle.net/vvGPQ/48/

showDiff();

function showDiff(){
var date1 = new Date("2013/01/18 06:59:00");   
var date2 = new Date();
//Customise date2 for your required future time

var diff = (date2 - date1)/1000;
var diff = Math.abs(Math.floor(diff));

var years = Math.floor(diff/(365*24*60*60));
var leftSec = diff - years * 365*24*60*60;

var month = Math.floor(leftSec/((365/12)*24*60*60));
var leftSec = leftSec - month * (365/12)*24*60*60;    

var days = Math.floor(leftSec/(24*60*60));
var leftSec = leftSec - days * 24*60*60;

var hrs = Math.floor(leftSec/(60*60));
var leftSec = leftSec - hrs * 60*60;

var min = Math.floor(leftSec/(60));
var leftSec = leftSec - min * 60;




document.getElementById("showTime").innerHTML = "You have " + years + " years "+ month + " month " + days + " days " + hrs + " hours " + min + " minutes and " + leftSec + " seconds the life time has passed.";

setTimeout(showDiff,1000);
}
NovaYear
fonte
Por favor, acrescente mais esclarecimentos à sua resposta e use um inglês melhor.
Processo de Fundo Monica
Esta solução está errada porque você usa 365 dias, negligenciando os anos bissextos.
Sergey Goliney
0
function checkdate() {
    var indate = new Date()
    indate.setDate(dat)
    indate.setMonth(mon - 1)
    indate.setFullYear(year)

    var one_day = 1000 * 60 * 60 * 24
    var diff = Math.ceil((indate.getTime() - now.getTime()) / (one_day))
    var str = diff + " days are remaining.."
    document.getElementById('print').innerHTML = str.fontcolor('blue')
}
hiren gamit
fonte
0
<html>
<head>
<script>
function dayDiff()
{
     var start = document.getElementById("datepicker").value;
     var end= document.getElementById("date_picker").value;
     var oneDay = 24*60*60*1000; 
     var firstDate = new Date(start);
     var secondDate = new Date(end);    
     var diffDays = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay)));
    document.getElementById("leave").value =diffDays ;
 }
</script>
</head>
<body>
<input type="text" name="datepicker"value=""/>
<input type="text" name="date_picker" onclick="function dayDiff()" value=""/>
<input type="text" name="leave" value=""/>
</body>
</html>
Sukanya Suku
fonte
0

este código preenche a duração dos anos de estudo quando você insere a data de início e de término (qualificar data acurada) do estudo e verifica se a duração é inferior a um ano se sim o alerta que uma mensagem leva em mente há três elementos de entrada o primeiro txtFromQualifDatee segundo txtQualifDatee terceirotxtStudyYears

vai mostrar o resultado do número de anos com fração

function getStudyYears()
    {
        if(document.getElementById('txtFromQualifDate').value != '' && document.getElementById('txtQualifDate').value != '')
        {
            var d1 = document.getElementById('txtFromQualifDate').value;

            var d2 = document.getElementById('txtQualifDate').value;

            var one_day=1000*60*60*24;

            var x = d1.split("/");
            var y = d2.split("/");

            var date1=new Date(x[2],(x[1]-1),x[0]);

            var date2=new Date(y[2],(y[1]-1),y[0])

            var dDays = (date2.getTime()-date1.getTime())/one_day;

            if(dDays < 365)
            {
                alert("the date between start study and graduate must not be less than a year !");

                document.getElementById('txtQualifDate').value = "";
                document.getElementById('txtStudyYears').value = "";

                return ;
            }

            var dMonths = Math.ceil(dDays / 30);

            var dYears = Math.floor(dMonths /12) + "." + dMonths % 12;

            document.getElementById('txtStudyYears').value = dYears;
        }
    }
Shareef
fonte
1
Nunca, jamais, analise strings de data para encontrar o ano porque a aparência da string (especialmente separadores) difere entre os navegadores. Use getFullYearque foi projetado para isso. ------- Veja a biblioteca datejs em googlecode, que possivelmente suporta a maioria dos casos esquivos
Dan,
obrigado pelo conselho @Dan, mas funcionou e testou para mim em um projeto governamental real (navegadores diferentes), é essa prática de programação fraca? :)
shareef
0

Se você usar objetos Date e depois usar o getTime() função para ambas as datas, ela fornecerá seus respectivos tempos desde 1º de janeiro de 1970 em um valor numérico. Você pode obter a diferença entre esses números.

Se isso não ajudar você, verifique a documentação completa: http://www.w3schools.com/jsref/jsref_obj_date.asp

Aaron
fonte
Oh, sim, não percebi, as respostas abaixo desta têm no máximo meio ano.
Koen.
0

O código abaixo retornará os dias restantes de hoje para a data futura.

Dependências: jQuery e MomentJs.

var getDaysLeft = function (date) {
  var today = new Date();
  var daysLeftInMilliSec = Math.abs(new Date(moment(today).format('YYYY-MM-DD')) - new Date(date));
  var daysLeft = daysLeftInMilliSec / (1000 * 60 * 60 * 24);   
  return daysLeft;
};

getDaysLeft('YYYY-MM-DD');
Vin S
fonte
0
var getDaysLeft = function (date1, date2) {
   var daysDiffInMilliSec = Math.abs(new Date(date1) - new Date(date2));
   var daysLeft = daysDiffInMilliSec / (1000 * 60 * 60 * 24);   
   return daysLeft;
};
var date1='2018-05-18';
var date2='2018-05-25';
var dateDiff = getDaysLeft(date1, date2);
console.log(dateDiff);
Vin S
fonte
0

ISSO É O QUE EU FIZ NO MEU SISTEMA.

var startTime=("08:00:00").split(":");
var endTime=("16:00:00").split(":");
var HoursInMinutes=((parseInt(endTime[0])*60)+parseInt(endTime[1]))-((parseInt(startTime[0])*60)+parseInt(startTime[1]));
console.log(HoursInMinutes/60);
Sean Cortez
fonte