GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

Calcular periodo e horas entre datas

java
Tags: #<Tag:0x00007fb019df0608>

#1

Pessoal, preciso da ajuda de alguém com isso, pois não faço ideia de como fazer.
Recebo uma data inicial e um tempo de esforço, a partir daí preciso calcular a data final de acordo com o tempo informado e distribuir nos dias do período as horas utilizadas.
Obs: Tomando como base uma jornada 07:30 - 12:00 e 13:00 - 17:30 e intervalo 12:00 - 13:00, para esse cálculo.
Ex:
Data Inicial -> 30-03-2017
Tempo Esforço: 22h:15m

Período Tempo
30-03-2017 9h
31-03-2017 9h
03-04-2017 4h 15m
Estou tendo dificuldade com isso, alguém poderia me ajudar, fico muito grato.

Obrigado


#2

Cara data no java é um pouco chato de trabalhar. Mas saiu no Java8 uma nova api e ainda não testei. Mas da uma olhada pode ser que resolva seu problema.

Link para uma breve introdução.

http://4java.com.br/java-8-e-sua-nova-api-para-datas/


#3

1 - Divida o total de horas de esforço pelo número de horas diárias (somando-se a primeira e a segunda parte você tem o total de horas diárias).
2 - Verifique o resto da divisão, se ele for menor que o número de horas de um dia, considere um dia a mais no cálculo da data de término.
3 - Com o valor do resto da divisão, calcule o total de horas e minutos do último dia.

Exemplo:
Início 01/04/2017
Esforço: 23:30 horas
23:30 / 9 = 2 resto 5:30 => total de dias: 3
Primeiro período: 07:30 - 12:00: 4:30 horas
Assim sendo:
01/04/2017 - 9:00 horas
02/04/2017 - 9:00 horas
03/04/2017 - 5:30 horas


#4

Matheus, obrigado pela dica, mas como estou com o Java 7, não me ajuda muito no momento e também não faço ideia de como fazer.

Preciso de ajuda em desenvolver mesmo.


#5

Obrigado Luis Augusto pelas dicas, foi de grande valia.

Você poderia me enviar um exemplo de código, por favor.


#6

Não. Esta parte é tua responsabilidade. A estrutura lógica está pronta, basta implementar :smiley:
Sucesso!


#7

Ok! Só pedi como base de estudo, como sou iniciante e não tenho seu conhecimento, pensei que pudesse me ajudar com isso.

Mas mesmo assim, muito obrigado pelas dicas.


#8

Independente de ser iniciante ou não, você deve ser capaz de construir a tua forma de desenvolver.
Além do mais, a solução que apontei é muito simples, basicamente, divisão (operador /) e resto (operador %).
Para ir somando os dias à data inicial, utilize o Calendar

Calendar cal = Calendar.getInstance();

E utilize os métodos setTime(Date data) e add(Calendar.DAY_OF_MONTH, int days)

Como transformar a data inicial em Date?
Utilize a classe SimpleDateFormat

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");

Detalhe, o parâmetro dd/MM/yyyy corresponde ao formato em que a data inicial será inserida. Se for o padrão americano, utilize

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

Ou o padrão em que a String que representa a data inicial vier a ser informada. Para converter a String em Date, invoque o método parse(String str) (Este método lança uma ParseException que precisa ser tratada).

Dúvidas? Primeiro pesquise no google, tente encontrar exemplos do que precisa e, se não tiver sucesso, o fórum está aqui.


#9

Ok, obrigado. Vou tentar, se tiver dúvidas, volto aqui!


#10

Já que está iniciando recomendo fortemente atualizar a versão do Java .

Até porque ja já que teremos o Java 9 e como comentei. As maneiras tradicionais de trabalhar como datas como nosso amigo @Luis_Augusto_Santos mostrou é extramente desconfortável. Além de que você pode acabar utilizando métodos ou classes do Java 7 que serão descontinuados nas versões futuras.

E como mencionei anteriormente uma das grandes mudanças do Java 8 é essa nova maneira de trabalhar com datas ja que o sistema antigo é muito precário.


#11

Ok Matheus.


#12

Pessoal, o que estou fazendo de errado, os meus cálculos dos períodos estão corretos, a soma deu 9.0 para os dois períodos, mas para o tempo de esforço que deveria dar 20.25, está dando 23.25.

	String tempoEsforco = "20:15:00";
    
    String horaInicioManha = "07:30:00";
	String horaFimManha = "12:00:00";
    
	String horaInicioTarde = "13:00:00";
	String horaFimTarde = "17:30:00";
	
	SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
	
	//Período da manhã
	Date hm1 = sdf.parse(horaInicioManha);
    Date hm2 = sdf.parse(horaFimManha);
    double diffInMillis1 =   (hm2.getTime() - hm1.getTime())/ (double) (1000*60*60); //4.5
    int horasManha = (int) (diffInMillis1);
    int minutosManha = (int) ((diffInMillis1-horasManha) * 60);
    //System.out.println(horasManha+ " : " +minutosManha);
    
    //Período da tarde
    Date ht1 = sdf.parse(horaInicioTarde);
    Date ht2 = sdf.parse(horaFimTarde);
    double diffInMillis2 =   (ht2.getTime() - ht1.getTime())/ (double) (1000*60*60); //4.5
    int horasTarde = (int) (diffInMillis2);
    int minutosTarde = (int) ((diffInMillis2-horasTarde) * 60);
    //System.out.println(horasTarde+ " : " +minutosTarde);
    
   	    	    
    //Total dos dois períodos
    double somaDiffInMillis =   diffInMillis1 + diffInMillis2; //9.0
    int horasTotal = (int) (somaDiffInMillis);
    int minutosTotal = (int) ((somaDiffInMillis-horasTotal) * 60);
    //System.out.println(horasTotal+ " : " +minutosTotal);
    
    //Tempo esforço
  	Date tempoEsf = sdf.parse(tempoEsforco);
  	double diffInMillisTempoEsforco =   (tempoEsf.getTime()) / (double) (1000*60*60);
    //Aqui deveria dar 20.25 e está dando 23.25

Desde já agradeço a ajuda.


#14

Agora vou responder certo

double diffInMillisTempoEsforco = (tempoEsf.getTime() - 10800000) / (double) (1000*60*60);

Essa foi a solução que eu encontrei pois vi que se você criar uma variável que recebe “00:00:00” ela retorna no getTime 10800000. Não sei o por que disso, sou iniciante em programação então espero que alguém explique um pouco melhor o que realmente acontece.


#15

Obrigado Lucas pela resposta!

Pois é, também não imagino porque isso acontece, já tentei de diversas maneiras corrigir, mas sem êxito.


#16

Este valor, em ms, corresponde a 3 horas. +3 é o fuso onde a maior porção do território brasileiro se encontra.
Fuso horário. Faz sentido para vocês?


#17

Verdade Luis!

E como seto o timezone? Seria assim?

DateFormat df = DateFormat.getTimeInstance(DateFormat.MEDIUM);
df.setTimeZone(TimeZone.getTimeZone("UTC"));

#18

Você até pode fazer

df.setTimeZone(TimeZone.getTimeZone("UTC"));

Mas, não esqueça que os objetos de Date são construídos com base na data e hora 01/01/1970 00:00:00, ou seja, se você define o timezone, vai acabar trabalhando com a data 31/12/1969 e a hora será 21:00:00


#19

Tá, e como você faria, pode dar uma dica?


#20

A melhor opção, sem dúvidas, é a nova API de datas e horas do java (a partir do java 8).
Só não entendi uma coisa: você já não tem o esforço, por quê calcular o mesmo novamente?[quote=“Marcos_rhs, post:1, topic:345884”]
Recebo uma data inicial e um tempo de esforço
[/quote]


#21

Estou apenas transformando o esforço em decimal. Para fazer aquela divisão que você comentou, pegar o esforço e dividir pelo total de horas do período e depois pegar o resto.

Existe uma maneira mais simples?