Como calcular o número de dias entre duas datas

Olá, amigos,

É a primeira vez que venho postar uma mensagem neste forum, então, quero enviar meu abraço a todos que participam do GUJ Forum, tenho lido as mensagens e aprendido muito com vocês.

Sou iniciante, tenho muitas dificuldades, e agora estou com um problema que não sei resolver. No meu aplicativo tenho duas JTextField, a T1 e a T2, onde digito datas, no formato dd/mm/yyyy, exemplo, 15/10/2005.

Sempre a data digitada na T2 é posterior(maior) que a data digitada na T1.

Depois eu clico em um JButton B1, e usando a interface ActionListener, e o método actionPerformed(), eu desejo calcular o número de dias entre as duas datas, dentro desse evento. Esse valor então deve aparecer em uma uma outra JTextField T3. Só isso.

Eu fiz o aplicativo, mais não sei fazer a rotina que captura as duas datas em T1 e T2, calcula os dias entre as duas datas e coloca esse valor na T3.

Eu já entendi que preciso usar

import java.util.Date;

e utilizar o método data.getTime(), parece que é por aí, mas não sei fazer isto. Tento ler no Tutorial sobre a API, mas não entendo. Deve ser uma rotina de 3 ou 4 linhas , mas não sei fazer. Se alguém puder me ajudar eu agradeço muito.

Abraço a todos,
Luca

Melhor esquecer o inferno todo da java.util.Calendar e usar a JODA Time direto :wink:

http://joda-time.sourceforge.net/index.html

1 curtida

cara…pergunta muuito frequente…
http://www.javafree.org/javabb/viewtopic.jbb?t=10031
http://www.javafree.org/javabb/viewtopic.jbb?t=4683&page=0&h=trabalhando%20com%20datas#26030

como vc é novo no forum é melhor te avisar antes… da sempre uma procurada básica no google, neste ou em outros fóruns… antes que alguem te responda com grocerias.

coloque este codigo dentro do evento gerado pelo botão:

SimpleDateFormat sdf = new SimpleDateFormat(“dd/MM/yyyy”);
Calendar data1 = Calendar.getInstance();
Calendar data2 = Calendar.getInstance();
try {
data1.setTime(sdf.parse(jTextField1.getText()));
data2.setTime(sdf.parse(jTextField2.getText()));
} catch (java.text.ParseException e ) {}
int dias = data2.get(Calendar.DAY_OF_YEAR) -
data1.get(Calendar.DAY_OF_YEAR);
jTextField3.setText(String.valueOf(dias));

lembre de importar:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

e detalhe: o codigo acima funciona apenas para ambas as datas no mesmo ano.
se vc for usar datas de anos diferentes o codigo cresce mais um pouquinho.

3 curtidas

Ao Demys,

Seu código rodou legal, cara! Perfeito. Por isso eu tinha detalhado no meu pedido os componentes que eu estava usando, mas achava difícil, envolvia tratamento de exceção, mas você fez a coisa perfeita, e eu quero agradecer muito sua colaboração.

Tem um problema apenas, é que na realidade, eu vou usar datas de anos diferentes sim, e você tinha alertado que só funcionaria para datas do mesmo ano. Se você puder alterar para poder pegar quaisquer anos, eu seria muito grato, meu conhecimento de Java ainda não dá pra sacar o que acontece ali, não posso eu mesmo mudar. Agradeço demais sua ajuda.

Um grande abraço pra você,
Luca

2 curtidas

Ao deniswsrosa,

Muito obrigado por sua ajuda, eu entrei nos links e tem muita coisa legal neles sim, e obrigado também por me avisar de que a galera pega no pé, tô atento cara, mas sou de paz, e o que desejo é fazer amigos. Muito obrigado.

Luca

1 curtida

Para saber a diferença de dias entre duas datas, transforme-as para milissegundos, obtenha a diferença, some 1 hora (devido a problemas de horário de verão etc.) e divida por 86400000.

import java.util.*;
import java.text.*;

class DiffDias {
    public static void main(String[] args) throws ParseException {
        // Dando um exemplo: quantos dias se passam desde 07/09/1822 até 05/06/2006?
        DateFormat df = new SimpleDateFormat ("dd/MM/yyyy");
        df.setLenient(false);
        Date d1 = df.parse ("07/09/1822");
        System.out.println (d1);
        Date d2 = df.parse ("05/06/2006");
        System.out.println (d2);
        long dt = (d2.getTime() - d1.getTime()) + 3600000; // 1 hora para compensar horário de verão
        System.out.println (dt / 86400000L); // passaram-se 67111 dias
    }
}
1 curtida

Ao Thingol,

Quero agradecer a você thingol, seu código esclareu muitas coisas para mim, mas no meu aplicativo eu uso swing, duas JTextField ( T1 e T2) e uso um JButton (B1) que ao ser clicado deve conter esse código que permite capurar as datas nas duas T1 e T2, calcular o número de dias entre elas , e colocar em uma outra JTextField (T3) o resultado.

Eu preciso de um código dentro do evento disparado pelo JButton, eu estou tentando esse abaixo, veja:

public void actionPerformed(ActionEvent e)
         {
            
            if (e.getSource() == B1 )
              {
                 SimpleDateFormat df = new SimpleDateFormat ("dd/MM/yyyy");
                                                  
                  try 
                  { 
                     Date d1 = df.parse (T1.getText());
                     Date d2 = df.parse (T2.getText());
                  } 

                  catch (java.text.ParseException evt ) {}

                  long dt = (d2.getTime() - d1.getTime()) + 3600000;      
                  long dias = (dt / 86400000L);  
                 
                  T3.setText(String.valueOf(dias)); 

             }

Mas está dando erro, não está reconhecendo d1 e d2. Se alguém souber o que pode estar ocorrendo, e me ajudar, agradeço muito.
Luca

Tudo que você declara dentro das chaves “nasce” dentro delas e “morre” fora delas - isso é o tal do “escopo”.

No seu caso, d1 e d2 não são visíveis dentro da expressão dt = … porque “já morreram”.

Para resolver isso, declare d1 e d2 fora do “try”.

Ao Thingol,

Não entendi bem sua última instrução acima, amigo. Se eu tenho que usar uma Try - catch por causa do tratamento da Exception, como posso tirar as declarações Date d1 e Date d2 de dentro das chaves? Como fazer isto? Ficou confuso para mim, amigo. Significa não usar a try-catch ?

Você certamente deve estar certo, mas não estou entendendo, desculpe.
Abraços,
Luca

É assim:

Date d1 = null; 
Date d2 = null; 
try { 
       d1 = df.parse (T1.getText());
       d2 = df.parse (T2.getText());
} catch (java.text.ParseException evt ) {}
 long dt = (d2.getTime() - d1.getTime()) + 3600000;      
 long dias = (dt / 86400000L);  

declara d1 e d2 fora do try para que ele possa ser enxergado fora do try,
se ele for declarado dentro do try, so pode ser usado dentro do try.
É o tal do escopo de variaveis

1 curtida

[quote=cv]Melhor esquecer o inferno todo da java.util.Calendar e usar a JODA Time direto :wink:

Teve a manha do link…não conhecia… boa :idea:

Eu criei uma classe com metodos estaticos que calcula diferenca entre datas independendo do ano… So que a resposta será em dias o nome do metodo é getDaysOfInterval


package cpc;

import java.util.Calendar;

public class Data {

    public static String getFormattedData(int dia, int mes, int ano) {
        String strDia = null;
        String strMes = null;
        if (dia < 10) {
            strDia = "0" + dia;
        } else {
            strDia = Integer.toString(dia);
        }
        if (mes < 10) {
            strMes = "0" + mes;
        } else {
            strMes = Integer.toString(mes);
        }
        return strDia + "/" + strMes + "/" + Integer.toString(ano);
    }

    public static String getTodayDate() {
        Calendar dataAtual = Calendar.getInstance();

        Integer ano = dataAtual.get(Calendar.YEAR);
        Integer mes = dataAtual.get(Calendar.MONTH);
        Integer dia = dataAtual.get(Calendar.DAY_OF_MONTH);
        mes += 1;

        return getFormattedData(dia, mes, ano);
    }

    public static int getDaysOfInterval(String dataInit, String dataFinish) {
        int[] data1 = new int[3];
        int[] data2 = new int[3];
        int dias = 0;

        //Desmembra dia, mes e ano das datas;
        data1[0] = Integer.parseInt(dataInit.substring(0, 2)); //dia;
        data1[1] = Integer.parseInt(dataInit.substring(3, 5)); //mes;
        data1[2] = Integer.parseInt(dataInit.substring(6, 10)); //ano;

        data2[0] = Integer.parseInt(dataFinish.substring(0, 2)); //dia;
        data2[1] = Integer.parseInt(dataFinish.substring(3, 5)); //mes;
        data2[2] = Integer.parseInt(dataFinish.substring(6, 10)); //ano;

        int m1 = getDaysMonth(data1[1], data1[2]);
        int m2 = getDaysMonth(data2[1], data2[2]);

        if (data2[2] == data1[2]) { // Calculo para o mesmo ano;
            if (data1[1] == data2[1]) {
                dias = data2[0] - data1[0];
            } else {
                int diasMes1 = (m1 - data1[0]) + 1; 	// numero de dias do primeiro mes (do dia x até o dia 30);
                int diasMes2 = m2 - (m2 - data2[0]);	// numero de dias do ultimo mes (do dia 1 até o dia x);
                int interMeses = (data2[1] - data1[1]);	// quantidade de meses entre o primeiro e o ultimo mes;

                if (interMeses == 0) {
                    dias = diasMes1 + diasMes2;
                } else {
                    for (int i = 1; i < interMeses; i++) {
                        dias += getDaysMonth(data1[1] + i, data1[2]);
                    }
                    dias += (diasMes1 + diasMes2);
                }
            }
        } else {//Calculo para anos diferentes
            int mesesAno1 = 12 - data1[1];	    	//Numero de Meses ate o fim do ano (O Mes1 não está incluído);
            int diasMes1 = m1 - data1[0];		//Numero de dias do Mes1(inicial);
            for (int i = 0; i < mesesAno1; i++) {
                dias += getDaysMonth(data1[1] + i, data1[2]);
            }
            dias += diasMes1;

            int diasMes2 = m2 - (m2 - data2[0]);	    //Numero de dias do ultimo mes do periodo;
            int mesesAno2 = data2[1] - 1;	            //Numero de meses do mes 1 ate o mes x do novo ano;
            for (int i = 0; i < mesesAno2; i++) {
                dias += getDaysMonth(data2[1], data2[2]);
            }
            dias += diasMes2;

            if (data2[2] - data1[2] > 1) {
                dias += 365 * (data2[2] - data1[2] - 1);    // quantidade de anos entre o primeiro e o ultimo ano;
            }
        }
        return dias;
    }

    public static boolean yearIsBisext(int year) {
        //Ano Bisexto (Regras do Calendário Gregoriano):
        // 1 - Todo ano divisível por 4 é bissexto
        // 2 - Todo ano divisível por 100 não é bissexto
        // 3 - Mas se o ano for também divisível por 400 é bissexto
        // FONTE: http://blog.webcalc.com.br/2006/04/29/o-que-e-ano-bissexto/
        boolean retorno;
        if (year % 4 == 0) {
            if (year % 100 == 0) {
                if (year % 400 == 0) {
                    retorno = true;
                } else {
                    retorno = false;
                }
            } else {
                retorno = true;
            }
        } else {
            retorno = false;
        }
        return retorno;
    }

    public static int getDaysMonth(int month, int year) {
        //O ano valor do ano será usado para verificar se o ano é bisexto
        int[] mes = new int[12];

        mes[0] = 31;

        if (yearIsBisext(year)) {
            mes[1] = 29;
        } else {
            mes[1] = 28;
        }

        mes[2] = 31;

        mes[3] = 30;

        mes[4] = 31;

        mes[5] = 30;

        mes[6] = 31;

        mes[7] = 31;

        mes[8] = 30;

        mes[9] = 31;

        mes[10] = 30;

        mes[11] = 31;

        return mes[month - 1];
    }
}

Caro Cláudo.

Tentei aplicar a sua classe mas ela está dando uma resposta incoerente.

Tentei com o seguinte dado:

Data.getDaysOfInterval(“01/02/2000”, “02/02/2001”);

O certo seria 368 dias e esse método está retornado 362 dias.

Por favor, verifique este valor.

Abraços.

O valor correto é 367 dias porque 2000 é bissexto. De onde você tirou 368?

import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;

class Intervalo {
    private static DateFormat df = new SimpleDateFormat ("dd/MM/yyyy");
    /** Calcula o número de dias entre duas datas. */
    public static long calcular (String inicio, String fim) throws ParseException {
        Date dtInicial = df.parse (inicio);
        Date dtFinal = df.parse (fim);
        return 
             (dtFinal.getTime() - dtInicial.getTime() + 3600000L) / 86400000L;
    }
    public static void main(String[] args) throws Exception {
        long dias = Intervalo.calcular ("01/02/2000", "02/02/2001");
        System.out.println (dias);
    }
}

Aos que pularam a sugestão do cv e estão implementando o resto das sugestões no tópico, um aviso:

Por favor parem de ser masoquistas e tenham dó dos seus usuários e do cliente que vai ter que pagar mais alguns milhares de reais para fazer a manutenção do sistema.

O problema de cálculo de datas já foi solucionado pelo Joda Time. Qualquer outra tentativa de fazer a mesma coisa é perda de tempo.

Meu caro, obrigado. Vc está correto!

Valeu mesmo.

Muito bom! usei o código e funcionou beleza!