Calcular horas dentro de um List

13 respostas
mateus.cordeiro

Senhores, Bom dia!
Estou com uma duvida e preciso de algumas dicas!
Eu tenho um sistema hoje que o controle de pontos(hora de entrada, almoco, retorno e saida), que tem como objetivo calcular as horas de trabalho!

Carrego esse dados do banco em um List para apresentar em um DataModel no JSF(dataTable).

Preciso calcular as horas trabalhadas = (almoco - entrada) + (saida - retornoAlmoco) e apresentar em uma outra coluna do dataTable.
Como faço isso? Por onde estudar?

Obrigado

13 Respostas

ManoJava

Bom dia!

A alguns dias um usuario teve uma duvida parecida e postei algumas soluções que aplico no meu dia-a-dia para resolução de horas trabalhadas, veja no link.

Att.

fbl.lucas

Você poderia criar um método getTotalTrabalhado dentro do objeto Hora e acessa-lo no jsp/xhtml

public Integer getTotalTrabalhado(){ return (this.almoco - this.entrada) + (this.saida - this.retornoAlmoco); }

mateus.cordeiro

Ok! Mas como eu faço p percorrer cada linha e apresenta-la no dataTable?
Uso um for?

T

Veja se isso te ajuda.

Obs.: tem método com nome meio feio. Mas acho que pode te ajudar.

public class CalculoHoras {

	private static final SimpleDateFormat FORMAT = new SimpleDateFormat("HH:mm:ss");

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			Calendar dtEntrada = Calendar.getInstance();
			Calendar dtSaidaAlmoco = Calendar.getInstance();
			Calendar dtEntradaPosAlmoco = Calendar.getInstance();
			Calendar dtSaida = Calendar.getInstance();
			Scanner scanner = new Scanner(System.in);

			System.out.println("As horas devem ser informadas no formato HH:mm:ss");

			System.out.println("Hora de chegada: ");
			dtEntrada.setTime(FORMAT.parse(scanner.next()));

			System.out.println("Hora de saída para o almoço: ");
			dtSaidaAlmoco.setTime(FORMAT.parse(scanner.next()));

			System.out.println("Hora volta do almoço: ");
			dtEntradaPosAlmoco.setTime(FORMAT.parse(scanner.next()));

			System.out.println("Data saída: ");
			dtSaida.setTime(FORMAT.parse(scanner.next()));

			long difMilli = dtSaidaAlmoco.getTimeInMillis() - dtEntrada.getTimeInMillis();

			Hora hr = getDif(difMilli);

			difMilli = dtSaida.getTimeInMillis() - dtEntradaPosAlmoco.getTimeInMillis();
			Hora hr1 = getDif(difMilli);

			Calendar calendar = hr.t(hr1);

			System.out.println(FORMAT.format(calendar.getTime()));

		} catch (ParseException e) {
			e.printStackTrace();
		}

	}

	private static Hora getDif(long difMilli) {
		int timeInSeconds = (int) difMilli / 1000;
		int hours, minutes, seconds;
		hours = timeInSeconds / 3600;
		timeInSeconds = timeInSeconds - (hours * 3600);
		minutes = timeInSeconds / 60;
		timeInSeconds = timeInSeconds - (minutes * 60);
		seconds = timeInSeconds;

		Hora hora = new Hora(hours, minutes, seconds);
		return hora;
	}

}

class Hora {

	int hour;
	int minute;
	int second;

	public Hora(int hours, int minutes, int seconds) {
		this.hour = hours;
		this.minute = minutes;
		this.second = seconds;
	}

	public Calendar t(Hora hora) {

		Calendar c = Calendar.getInstance();
		c.set(Calendar.HOUR_OF_DAY, hour);
		c.set(Calendar.MINUTE, minute);
		c.set(Calendar.SECOND, second);

		c.add(Calendar.HOUR_OF_DAY, hora.hour);
		c.add(Calendar.MINUTE, hora.minute);
		c.add(Calendar.SECOND, hora.second);
		return c;
	}

}
fbl.lucas

mateus.cordeiro:
Ok! Mas como eu faço p percorrer cada linha e apresenta-la no dataTable?
Uso um for?

Então você não sabe utilizar o dataTable, caso esteja utilizando o do próprio JSF veja o código abaixo, caso esteja utilizando Richfaces segue o link com o demo Demo Richfaces

<h:dataTable id="books" value="#{BookStore.items}" var="store"> <h:column> <f:facet name="header"> <h:outputText value="Titulo Coluna"/> </f:facet> <h:outputText value="#{store.name}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Titulo Coluna"/> </f:facet> <h:outputText value="#{store.subject}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Titulo Coluna"/> </f:facet> <h:outputText value="#{store.price}"/> </h:column> </h:dataTable>

fbl.lucas

http://www.guj.com.br/java/16342-datatable-do-jsf—como-usar

mateus.cordeiro
Vamos lá! TMA - Cara muito obrigado pela apoio... ajudou muito sua CLASSE. Porem, Ficou assim:
public class CalculoHoras {  
      
        private static final SimpleDateFormat FORMAT = new SimpleDateFormat("HH:mm:ss");  
      
        public Time calcular(Time ent, Time alm, Time ret, Time sai) {  
                //Converte java.sql.Time em Calendar
                Calendar entrada = Calendar.getInstance();
                entrada.setTime(ent);
                
                Calendar almoco = Calendar.getInstance();
                entrada.setTime(alm);
                
                Calendar retorno = Calendar.getInstance();  
                entrada.setTime(ret);
                
                Calendar saida = Calendar.getInstance();  
                entrada.setTime(sai);
       
      
                long difMilli = almoco.getTimeInMillis() - entrada.getTimeInMillis();  
      
                Hora hr = getDif(difMilli);  
      
                difMilli = saida.getTimeInMillis() - retorno.getTimeInMillis();  
                Hora hr1 = getDif(difMilli);  
      
                Calendar calendar = hr.t(hr1);  
                            
                //Converte Calendar em java.sql.Time
                Time horasCalculadas = (Time) calendar.getTime();
                return horasCalculadas;
     
        }  
      
        private static Hora getDif(long difMilli) {  
            int timeInSeconds = (int) difMilli / 1000;  
            int hours, minutes, seconds;  
            hours = timeInSeconds / 3600;  
            timeInSeconds = timeInSeconds - (hours * 3600);  
            minutes = timeInSeconds / 60;  
            timeInSeconds = timeInSeconds - (minutes * 60);  
            seconds = timeInSeconds;  
      
            Hora hora = new Hora(hours, minutes, seconds);  
            return hora;  
        }  
      
    }  
    class Hora {  
      
        int hour;  
        int minute;  
        int second;  
      
        public Hora(int hours, int minutes, int seconds) {  
            this.hour = hours;  
            this.minute = minutes;  
            this.second = seconds;  
        }  
      
        public Calendar t(Hora hora) {  
      
            Calendar c = Calendar.getInstance();  
            c.set(Calendar.HOUR_OF_DAY, hour);  
            c.set(Calendar.MINUTE, minute);  
            c.set(Calendar.SECOND, second);  
      
            c.add(Calendar.HOUR_OF_DAY, hora.hour);  
            c.add(Calendar.MINUTE, hora.minute);  
            c.add(Calendar.SECOND, hora.second);  
            return c;  
        }  
      
    }
Eu chamo ele nesse outro metodo que carrega o List:
public List<Horas> carrega(String Iduser){ 
         int idusuario = Integer.parseInt(Iduser);
         List<Horas> hora = new ArrayList<Horas>();
         CalculoHoras ch = new CalculoHoras();//isso que está certo? 
         try{                  
         String sql = " SELECT tb.*, "
                    + " bh.justificativa AS justificativa "
                    + " FROM tabcontrole AS tb LEFT JOIN bancohoras AS bh ON tb.idbanco = bh.idbanco"
                    + " WHERE cod_func = ? "
                    + " ORDER BY data_cont ";
         
         PreparedStatement ps = conexao.getConn().prepareStatement(sql);
         ps.setInt(1, idusuario);
         ResultSet rs = ps.executeQuery();
             
             while (rs.next()){
                Horas hr = new Horas();
                
                
                Time entra = rs.getTime("entrada");
                Time almo = rs.getTime("almoco");
                Time volt = rs.getTime("volta");
                Time said = rs.getTime("saida");
                
                hr.setData(rs.getDate("data_cont"));
                hr.setEntrada(entra);
                hr.setAlmoco(almo);
                hr.setRetorno(volt);
                hr.setSaida(said);
                hr.setAdicional(rs.getTime("adicional"));
                hr.setJustificativa(rs.getString("justificativa"));
                hr.setObs(rs.getString("obs"));
              
                hr.setHrTrabalhadas(ch.calcular(entra, almo, volt,said));//Chamo o metodo que faz os calculos, passando os parametros.
                
                hora.add(hr);
             }
             
         }catch(SQLException e){
             e.printStackTrace();
         }finally{
             conexao.fecharConexao();
         }
         return hora;
     }
O erro que aparece é o seguinte: java.lang.NoClassDefFoundError: util/CalculoHoras
mateus.cordeiro

LUCAS!
Isso do dataTable eu consigo, só não sei se minha logica está correta!

Fiz o que vc falou e criei o dentro da classe Horas um Time hrTrabalhadas! para receber os valores calculados!

fbl.lucas

mateus.cordeiro:
LUCAS!
Isso do dataTable eu consigo, só não sei se minha logica está correta!

Fiz o que vc falou e criei o dentro da classe Horas um Time hrTrabalhadas! para receber os valores calculados!


Então você ja consegue exibir um valor, mas este valor não esta correto?

mateus.cordeiro

cara, ele dá esse erro:
java.lang.NoClassDefFoundError: util/CalculoHoras

javax.faces.el.EvaluationException: java.lang.NoClassDefFoundError: util/CalculoHoras

at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)

at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)

at javax.faces.component.UICommand.broadcast(UICommand.java:315)

at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)

at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)

at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)

at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)

at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)

at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)

at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)

at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)

at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)

at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)

at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91


mateus.cordeiro

Eu criei uma nova classe com o nome Calculo.
É a mesma que CalculoHoras, apenas criei o arquivo como nova classe pelo NetBeans. Pq a outra eu havia copiado de um outro projeto.

Agora o erro é para converter o Calendar em java.sql.Time

Calendar calendar = hr.t(hr1); //Converte Calendar em java.sql.Time java.sql.Time hc = new java.sql.Time(calendar.getTime());

Agora dá um erro de conversão!
java.lang.ClassCastException: java.util.Calendar cannot be cast to java.sql.Time

Caused by: java.lang.ClassCastException: java.util.Date cannot be cast to java.sql.Date

at util.Calculo.calcular(Calculo.java:48)

at dao.HorasDAO.carrega(HorasDAO.java:61)

Exatamente onde faz a conversão!

Ta dificil… alguma dica, o que está errado?

fbl.lucas
Calendar calendar = hr.t(hr1);  
//Converte Calendar em java.sql.Time
java.sql.Time hc = new java.sql.Time(calendar.getTime());
Este código nem era para compilar, o construtor de Time não recebe um Date. Eu faria o seguinte, altera este seu método Hora.t() (sugestão, renomeie este método para um nome que sugira o que ele realmente faz, ex: getSQLTime(), as boas práticas agradecem) para que o método retorne um java.sql.Time
class Hora {  
      
        int hour;  
        int minute;  
        int second;  
      
        public Hora(int hours, int minutes, int seconds) {  
            this.hour = hours;  
            this.minute = minutes;  
            this.second = seconds;  
        }  
      
        public java.sql.Time getSQLTime(Hora hora) {   
            return new java.sql.Time(hour, minute, second);  
        }  
      
    }
Agora se você precisa do calendar em algum lugar, é só criar outro método ao invés de substituir.
mateus.cordeiro

Lucas! Obrigado pela ajuda!
Consegui resolver utilizando essa classe, que faz as contas com java.sql.Time:

package util;

import java.sql.Time;

public class Calculo{
    
    public Time calcular (Time entrada, Time almoco, Time volta, Time saida) {
            
            Time manha = calcula(entrada, almoco);
            Time tarde = calcula(volta, saida);
            Time total = soma(manha,tarde);
            
            return total;
                
    }

    public static Time calcula(Time entrada, Time almoco) {
        String hora1 = entrada.toString();
        String hora2 = almoco.toString();

        String horas = "00";
        String minutos = "00";
        String segundos = "00";

        int sub = 0;
        int subHoras = 0;
        int subMinutos = 0;

        int segundos1 = (Integer.parseInt(hora1.substring(0, 2)) * 3600)
                + (Integer.parseInt(hora1.substring(3, 5)) * 60)
                + Integer.parseInt(hora1.substring(6, 8));
        int segundos2 = (Integer.parseInt(hora2.substring(0, 2)) * 3600)
                + (Integer.parseInt(hora2.substring(3, 5)) * 60)
                + Integer.parseInt(hora2.substring(6, 8));

        if (segundos1 > segundos2) {
            sub = segundos1 - segundos2;
        } else if (segundos2 > segundos1) {
            sub = segundos2 - segundos1;
        } else {
            sub = 0;
        }

        if (sub >= 3600) {
            subHoras = (sub - (sub % 3600)) / 3600;
            sub = sub - (subHoras * 3600);
            if (subHoras < 10) {
                horas = "0" + Integer.toString(subHoras);
            } else {
                horas = Integer.toString(subHoras);
            }
        }

        if (sub >= 60) {
            subMinutos = (sub - (sub % 60)) / 60;
            sub = sub - (subMinutos * 60);
            if (subMinutos < 10) {
                minutos = "0" + Integer.toString(subMinutos);
            } else {
                minutos = Integer.toString(subMinutos);
            }
        }

        if (sub < 10) {
            segundos = "0" + Integer.toString(sub);
        } else {
            segundos = Integer.toString(sub);
        }

        //System.out.println("HH:MM:SS : " + horas + ":" + minutos + ":" + segundos);
        int horaFinal = Integer.parseInt(horas);
        int minFinal = Integer.parseInt(minutos);
        int segFinal = Integer.parseInt(segundos);

        Time resultado = new Time(horaFinal, minFinal, segFinal);

        return resultado;
    }

    public static Time soma(Time entra, Time saida) {
        Time resultado = null;

        int somaH = entra.getHours() + saida.getHours();
        int somaM = entra.getMinutes() + saida.getMinutes();
        int somaS = entra.getSeconds() + saida.getSeconds();

        if (somaM >= 60) {
            somaH = somaH + 1;
            somaM = somaM - 60;            
        }
        if (somaS >= 60) {
            somaM = somaM + 1;
            somaS = somaS - 60;            
        }

        resultado = new Time(somaH, somaM, somaS);

        return resultado;
    }

}

Obrigado!

Criado 22 de dezembro de 2011
Ultima resposta 26 de dez. de 2011
Respostas 13
Participantes 4