Problemas ao calcular Diferença de Horas em Date

8 respostas
G

Olá, tudo bem ?

sou nova na área e o GUJ foi o site mais indicado pra pesquisas e dúvidas…
realmente eu gostei muito e decidi criar uma conta pra minhas possíveis dúvidas, rs.
e ai vem uma.

Eu tenho que calcular a diferença de uma hora pra outra…
e tenho que exibir somente onde a diferença é maior que 05 min… é pra controle de ponto…

e olha como está minha classe…

Aqui é onde faço a comparação . e por se tratar de comparar Data com String . fiz dois métodos pra poder converter tudo pra HH:mm.
até ai estava tudo certinho …
mas agora que preciso fazer esse cálculo pra ter a diferença é que vem o problema…

private List<CompTimeSheetBiometrico> listComp = new ArrayList<CompTimeSheetBiometrico>();
   private List<TimeSheetBio> listaTimeSheet = new ArrayList<TimeSheetBio>();
   private List<Biometrico> listaBiometrico = new ArrayList<Biometrico>();

 public List comparaTimeSheetBiometrico(Date dataIni, Date dataFim) {
        listaTimeSheet = retornaConsultaTimeSheet(dataIni, dataFim);
        listaBiometrico = retornaConsultaBiometrico(dataIni, dataFim);

        for (Biometrico bt : listaBiometrico) {
            CompTimeSheetBiometrico comp = new CompTimeSheetBiometrico();

            for (TimeSheetBio ts : listaTimeSheet) {
                if (bt.getSigla().equals(ts.getSigla()) && bt.getData().equals(ts.getData())) {

                    comp.setSigla(bt.getSigla());
                    comp.setData(bt.getData());
                    comp.setN_apropriacao(ts.getN_apropriacao());
                    comp.setNome(ts.getNome());

                    if (ts.getFlag_destino().equals("entrada")) {
                        if (!converteData(ts.getHora()).equals(formataHora(bt.getMenor_horario()))) {
                            if (diferencaMenor(dataIni, dataFim) >= 5) {
                            comp.setEntradaTS(ts.getHora());
                            comp.setEntradaBio(bt.getMenor_horario());
                        }
                        }
                    } else if (ts.getFlag_destino().equals("saida")) {
                        if (!converteData(ts.getHora()).equals(formataHora(bt.getMaior_horario()))) {
                            if(diferencaMaior(dataIni, dataFim) >= 5)
                            comp.setSaidaTS(ts.getHora());
                            comp.setSaidaBio(bt.getMaior_horario());
                        }
                    }
                }
            }
            listComp.add(comp);

            if (comp.getEntradaTS() == null && comp.getEntradaBio() == null && comp.getSaidaTS() == null && comp.getSaidaBio() == null) {
                listComp.remove(comp);
            }
        }
        return listComp;
    }

private static String formataHora(Date hora) {
        SimpleDateFormat formatoData = new SimpleDateFormat("HH:mm");
        return formatoData.format(hora);
    }

    private String converteData(String dtData) {
        SimpleDateFormat formatBra;
        formatBra = new SimpleDateFormat("HH:mm");
        Date newData;
        try {
            newData = formatBra.parse(dtData.toString());
            return (formatBra.format(newData));
        } catch (Exception e) {
            return "Erro na conversão da data";
        }
    }

comecei a fazer o método…
e está assim … acredito que não esteja correto pois ele está gerando erro de NullPointer…
alguém pode apontar meu erro… ou me ajudar a criar um método mais fácil …

private int retornarDiferenca(Date data1, Date data2) {

        return (int) ((data1.getTime() - data2.getTime()) / (1000 * 60 * 60));
    }

private int diferencaMenor(Date dataIni, Date dataFim) {
        listaTimeSheet  = retornaConsultaTimeSheet(dataIni, dataFim);
        listaBiometrico = retornaConsultaBiometrico(dataIni, dataFim);
        Integer diferenca= 0;

     for (Biometrico bio : listaBiometrico) {
            for (TimeSheetBio ts : listaTimeSheet) {
        try {
            SimpleDateFormat df = new SimpleDateFormat("HH:mm");
            Date data1 = df.parse(ts.getHora());
            Date data2 = bio.getMenor_horario();
            diferenca = retornarDiferenca(data1, data2);
        } catch (java.text.ParseException parse) {
            parse.printStackTrace();
        }
            }
     }
        return diferenca;
    }

8 Respostas

drsmachado

Olá, benvinda.
Você mencionou um null pointer exception.
Mostre qual a linha que dispara essa exceção.
Outra coisa, seria mais fácil converter tudo para milissegundos, fazer os cáculos e, se preciso, fazer a conversão para Date.

Long timeIni = dataIni.getTime();//retorna a data atual em milissegundos
Long timeFim = dataFim.getTime();
Long diferencaReal = timeFim - timeIni;
Long diferencaTolerada = 1000*60*5; //1000 ms = 1 s, 60 s = 1m
if (diferencaReal > diferencaTolerada){
//faz o que precisa fazer aqui
}

Além disso, poderia substituir o Date por Calendar, que já possui vários métodos que facilitariam o cálculo.
Além disso, acredito que o jodaTime tenha algo mais fácil.

G

Olá, Obrigado.

isso o NullPointer aponta nesse método, na linha . .

private int diferencaMenor(Date dataIni, Date dataFim) {  
        listaTimeSheet  = retornaConsultaTimeSheet(dataIni, dataFim);  
        listaBiometrico = retornaConsultaBiometrico(dataIni, dataFim);  
        Integer diferenca= 0;  
  
     for (Biometrico bio : listaBiometrico) {  
            for (TimeSheetBio ts : listaTimeSheet) {  
        try {  
            SimpleDateFormat df = new SimpleDateFormat("HH:mm");  
            Date data1 = df.parse(ts.getHora());  // o NullPointer aponta aqui .
            Date data2 = bio.getMenor_horario();  
            diferenca = retornarDiferenca(data1, data2);  
        } catch (java.text.ParseException parse) {  
            parse.printStackTrace();  
        }  
            }  
     }  
        return diferenca;  
    }

vou tentar fazer essa conversão pra milissegundos e dar uma pesquisada sobre Calendar… nunca trabalhei com ele…

Obrigado pela ajuda .

drsmachado

Pela linha que está apontada, provável que algum elemento da listaTimeSheet esteja nulo.
O correto seria valdiar, verificando se ts != null, por exemplo.

Sim, a conversão é uma forma “arcaica” de resolver isso, mais simples.

Calendar está no pacote java.util e é uma interface, a principal implementação é GregorianCalendar

fernandopaiva

uma dica q recebi a muiiito tempo sobre trabalhar com Datas e q uso até hoje, inclusive fazendo o que vc precisa para meus calculos de data.

Use a API JodaTime, aqui: http://joda-time.sourceforge.net/

t+ e boa sorte.

ManoJava

Bom dia!

Segue o link para classe Calendar, e tambem da uma pesquisada aqui no Guj pois tem vários tópicos abordando esse assunto de cálculo de horas,
com várias dúvidas pertinentes.

http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html

Att.

G

Muito Obrigado pelas dicas !

vou testar todas aqui… e com essa ajuda espero que de certo !!

Valeu mesmo .

G

Pessoas estava tentando fazer assim ..

private long retornarDiferenca() {
        Calendar cal = new GregorianCalendar();
        long diferencaReal;
        long timeIni, timeFim;

        timeIni = cal.getTimeInMillis();
        timeFim = cal.getTimeInMillis();
        diferencaReal = timeFim - timeIni;

        return diferencaReal;
    }

e ai adicionava esse método direto na comparação

if (ts.getFlag_destino().equals(&quot;entrada&quot;)) {
                        if (!converteData(ts.getHora()).equals(formataHora(bt.getMenor_horario()))) {
                            if (retornarDiferenca() &gt; diferencaTolerada) {
                                comp.setEntradaTS(ts.getHora());
                                comp.setEntradaBio(bt.getMenor_horario());
                            }
                        }
                    } else if (ts.getFlag_destino().equals(&quot;saida&quot;)) {
                        if (!converteData(ts.getHora()).equals(formataHora(bt.getMaior_horario()))) {
                            if (retornarDiferenca() &gt; diferencaTolerada) {
                                comp.setSaidaTS(ts.getHora());
                                comp.setSaidaBio(bt.getMaior_horario());
                            }
                        }
                    }
                }

tentei mas gerou em branco minha lista..
=/ .

é melhor deixar do jeito que estava??
Sou nova aqui nessa empresa..
ai pedi pra add a API Joda Time mas não deixaram...
disseram que não posso alterar nada =( .

na verdade eles preferem que eu tente arrumar daquele jeito que eu mandei no primeiro post sabe...
mas não faz sentido.. o NullPointer da na última linha da lista.. dei um print e vem tudo certo.. ai quando chega no último campo..
ele vem null.

G

drsmachado:
Pela linha que está apontada, provável que algum elemento da listaTimeSheet esteja nulo.
O correto seria valdiar, verificando se ts != null, por exemplo.

Sim, a conversão é uma forma “arcaica” de resolver isso, mais simples.

Calendar está no pacote java.util e é uma interface, a principal implementação é GregorianCalendar

Olha o método que criei pra essa conversão …

public int diferencaMin(Date dataIni, Date dataFim) throws ParseException {
        listaTimeSheet = retornaConsultaTimeSheet(dataIni, dataFim);
        listComp = comparaTimeSheetBiometrico(dataIni, dataFim);
        int diferenca = 0;
        long diferencaMin = 0;
        Long timeIni, timeFim;

        for (CompTimeSheetBiometrico comp : listComp) {
            for (TimeSheetBio ts : listaTimeSheet) {

                if (ts.getFlag_destino().equals("entrada")) {

                    SimpleDateFormat df = new SimpleDateFormat("HH:mm");
                    timeIni = df.parse(comp.getEntradaTS()).getTime();
                    timeFim = comp.getEntradaBio().getTime();
                    diferencaMin = (timeFim - timeIni);
                    diferenca = (int) diferencaMin;
                } else if (ts.getFlag_destino().equals("saida")) {
                    SimpleDateFormat df = new SimpleDateFormat("HH:mm");
                    if (comp.getSaidaTS() != null) {
                    timeIni = df.parse(comp.getSaidaTS()).getTime();
                    timeFim = comp.getSaidaBio().getTime();
                    diferencaMin = (timeFim - timeIni);
                    diferenca = (int) diferencaMin;
                    }
                }
        }
        }
        return diferenca;
    }

só que agora preciso comparar esse resultado a >= 5 …

só que não sei onde…
tentei dentro do meu método principal mas não deu certo …
ele está comparando errado …

ai tentei fazer dentro desse método aqui mesmo . .
só que da o seguinte erro.

Erro ao gerar o relatorio. java.util.ConcurrentModificationException

Alguém tem alguma dica do melhor modo pra se comparar isso ?

Criado 22 de fevereiro de 2012
Ultima resposta 23 de fev. de 2012
Respostas 8
Participantes 4