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.
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.
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
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.
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.
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
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.
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
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.