Calcular periodo e horas entre datas

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

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/

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

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.

Obrigado Luis Augusto pelas dicas, foi de grande valia.

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

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

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.

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.

1 curtida

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

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.

Ok Matheus.

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.

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.

Obrigado Lucas pela resposta!

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

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?

Verdade Luis!

E como seto o timezone? Seria assim?

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

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

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

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]

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?