[RESOLVIDO] Alguém já usou o Jollyday para calcular duas datas sem contar os feriados

Ola pessoal,

Estou tentando usar o Jollyday para calcular duas datas e estrair delas o periodo de horas, mas teria que eliminar as horas que são de dias de feriados.

Hoje eu uso o Joda-Time para calcular a quantidade de horas de duas datas, com o código abaixo

Date dataInicio = new Date();
System.out.println(new Period(new DateTime(dataInicio), new DateTime()).toStandardHours().getHours());

Agora eu quero usar o código do Jollyday abaixo, para integrar com o Joda-Time.

HolidayManager m = HolidayManager.getInstance(HolidayCalendar.BRAZIL);

Set<Holiday> holidays = m.getHolidays(2011, "br", "s");

Alguém tem idéia de como resolver isso?

Site do Jollyday
http://jollyday.sourceforge.net/usage.html

Site do Joda-Time
http://joda-time.sourceforge.net/key_period.html

Obrigado…

O teu problema é interessante hehe…

Eu acabei de fazer um sistema de ficha ponto então precisei ir a fundo nos Time…
Usei o JodaTime, Calendar…

Pelo que entendi vc tem intervalo de datas com horas, qr diminuir uma por outra…
Acho que a solução é vc percorrer o periodo de datas com For…
E dentro do for vc verifica se é feriado… se não for feriado vc diminui aquele periodo ali dentro do for…

:wink:

ps.: o for analisa data por data. subtraindo apenas quando nao for feriado

Com esse código abaixo eu consigo pegar todas as datas dos feriados existentes no ano de 2011

       HolidayManager m = HolidayManager.getInstance(HolidayCalendar.BRAZIL);

        Set<Holiday> holidays = m.getHolidays(2011, "br", "s");

        //Mostra  todos os feriados do ano de 2011
        for (Holiday h : holidays){
            System.out.println(h.getDate());
        }

Eu fiz assim:

public static int verificaDiasUteis(Date dataInicio) {

        long numeroDiasExecutados = (long) (new Date().getTime() - dataInicio.getTime()) / 86400000L;

        int totalHorasNesseDia = 0;

        Calendar cal = Calendar.getInstance();
        cal.setTime(dataInicio);

        for (int i = 1; i < numeroDiasExecutados; i++) {

            //Verifica se é diferente de final de semana
            if (cal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY && cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {

                //Lista todos os feriados do ano de 2011, pelo jollyday
                HolidayManager m = HolidayManager.getInstance(HolidayCalendar.BRAZIL);

                Set<Holiday> holidays = m.getHolidays(2011, "br", "s");

                boolean feriado = false;

                //Verifica se o dia atual é um dia de feriado
                for (Holiday h : holidays){
                    if (h.getDate().equals(new DateTime(cal.getInstance().getTime()))) {
                        feriado = true;
                        break;
                    }
                }

                //Verifica se é diferente de feriado para poder considerar um dia util e adicionar a quantidade de horas nesse dia
                if (!feriado) {

                    //Seta o horario final dessa data, para poder calcular o horário
                    Calendar calFinal = Calendar.getInstance();
                    calFinal.set(cal.YEAR, cal.MONTH, cal.DAY_OF_YEAR, 18, 00, 00);

                    totalHorasNesseDia += new Period(new DateTime(cal.getInstance().getTime()), new DateTime(calFinal.getInstance().getTime())).toStandardHours().getHours();
                }
            }

            //Acrescenta mais um dia na data para poder verificar se é dia util
            cal.add(Calendar.DATE, 1);
        }

        return totalHorasNesseDia;
    }

Se tiver alguma outra idéia de como resolver, me avisem.

Obs: No meu caso o horário limite para cada dia é ás 18:00:00, por isso eu faço assim:

//Seta o horario final dessa data, para poder calcular o horário
                    Calendar calFinal = Calendar.getInstance();
                    calFinal.set(cal.YEAR, cal.MONTH, cal.DAY_OF_YEAR, 18, 00, 00);

Abs.

Não funcionou essa lógica?

não precisa usar esse Jollyday pra saber se é feriado ou nao

No meu caso, eu tenho um cadastro de feriados…
ai consulto se a data é feriado… mas deve ter algo pronto para isso ja

Ae pessoal, sempre coloquem a resposta da solução, pois, pode ser você amanhã querendo pesquisar uma solução para o problema.

Resolvi o problema da seguinte forma abaixo:

import de.jollyday.Holiday;
import de.jollyday.HolidayCalendar;
import de.jollyday.HolidayManager;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Set;
import org.joda.time.DateTime;
import org.joda.time.Period;

public class Teste {

    public static void main(String[] args) {

        try {
            //Data de inicio para teste
            Calendar cal = Calendar.getInstance();
            cal.set(2011, 8, 1, 16, 0, 0);

            System.out.println("Quantidade de horas trabalhadas ["+quantidadeHorasTrabalhadas(cal.getTime())+"]");

        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    /*
     ---------------Calcula a quantidade de horas trabalhadas com base na data de inicio----------------
     * Obs: - Horário de trabalho definido dás 09:00:00 ás 18:00:00
     *      - Não contabiliza as horas dos finais de semana (Sabado e Domingo) e nem dos feriados de São Paulo
     *      - Horário limite de almoço 14:00:00
     */
    public static int quantidadeHorasTrabalhadas(Date dataInicio) throws ParseException {

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

        //Pega a quantidade de dias que passaram, com base na data inicio e fim
        long numeroDiasExecutados = (long) (new Date().getTime() - sdf.parse(new DateTime(dataInicio).getYear()+"-"+new DateTime(dataInicio).getMonthOfYear()+"-"+new DateTime(dataInicio).getDayOfMonth()).getTime()) / 86400000L;

        int totalHorasTrabalhadas = 0;

        Calendar cal = Calendar.getInstance();
        cal.setTime(dataInicio);

        //Se a difenreça de data for igual a 0, é porque a data é a mesma da atual
        if (numeroDiasExecutados == 0) {
            return new Period(new DateTime(cal.getTime()), new DateTime()).toStandardHours().getHours();

        //Caso contrário, será adicionado +1, para poder contabilizar a data atual
        } else {
            numeroDiasExecutados+=1;
        }

        //Lista todos os dias, para poder fazer o calculo
        for (int i = 1; i <= numeroDiasExecutados; i++) {

            //Verifica se é diferente de final de semana
            if (cal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY && cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {

                //Lista todos os feriados do brasil e em são paulo usando a api jollyday
                HolidayManager m = HolidayManager.getInstance(HolidayCalendar.BRAZIL);

                //Seta o ano conforme a data verificada, para poder listar os feriados
                Set<Holiday> holidays = m.getHolidays(new DateTime(cal.getTime()).getYear(), "br", "s");

                boolean feriado = false;

                //Verifica se o dia atual é um dia de feriado
                for (Holiday h : holidays){
                    
                    Date dataFeriado = sdf.parse(new DateTime(h.getDate().toDateTimeAtCurrentTime()).getYear()+"-"+new DateTime(h.getDate().toDateTimeAtCurrentTime()).getMonthOfYear()+"-"+new DateTime(h.getDate().toDateTimeAtCurrentTime()).getDayOfMonth());
                    Date dataAtual = sdf.parse(new DateTime(cal.getTime()).getYear()+"-"+new DateTime(cal.getTime()).getMonthOfYear()+"-"+new DateTime(cal.getTime()).getDayOfMonth());

                    if (dataFeriado.compareTo(dataAtual) == 0) {
                        feriado = true;
                        break;
                    }
                }

                //Verifica se é diferente de feriado para poder considerar um dia util e adicionar a quantidade de horas nesse dia
                if (!feriado) {

                    //Verifica se é o último dia
                    if (i == numeroDiasExecutados) {
                        //Seta o horario inicial dessa data, para poder calcular o horário
                        Calendar calInicial = Calendar.getInstance();
                        calInicial.set(new DateTime(cal.getTime()).getYear(), new DateTime(cal.getTime()).getMonthOfYear() - 1, new DateTime(cal.getTime()).getDayOfMonth(), 9, 0, 0);

                        totalHorasTrabalhadas += new Period(new DateTime(calInicial.getTime()), new DateTime()).toStandardHours().getHours();

                        //Verifica se ocorreu um almoço nesse dia, para poder retirar uma hora
                        if (new DateTime().getHourOfDay() > 14) {
                            totalHorasTrabalhadas -= 1;
                        }

                    //Verifica se é o primeiro dia
                    } else if(i == 1) {

                        //Seta o horario final dessa data, para poder calcular o horário
                        Calendar calFinal = Calendar.getInstance();
                        calFinal.set(new DateTime(cal.getTime()).getYear(), new DateTime(cal.getTime()).getMonthOfYear() - 1, new DateTime(cal.getTime()).getDayOfMonth(), 18, 0, 0);

                        totalHorasTrabalhadas += new Period(new DateTime(cal.getTime()), new DateTime(calFinal.getTime())).toStandardHours().getHours();

                        //Verifica se ocorreu um almoço nesse dia, para poder retirar uma hora
                        if (new DateTime(cal.getTime()).getHourOfDay() < 14) {
                            totalHorasTrabalhadas -= 1;
                        }

                    //Outros dias, 8 horas padrao retirando a hora de almoço
                    } else {
                        totalHorasTrabalhadas += 8;
                    }

                //É um feriado
                } else if (feriado){
                    System.out.println("----------Data de feriado----------");
                    System.out.println(cal.getTime());
                    System.out.println("-----------------------------------");
                }
            }

            //Acrescenta mais um dia na data para poder verificar se é dia util
            cal.add(Calendar.DATE, 1);
        }

        return totalHorasTrabalhadas;
    }
}

Fiz varios testes e está ok, caso alguém precise de algo parecido, poderá utilizar em um futuro próximo.

Obs: O código pode ser adaptado e customizado, isso fica a critério de cada um.

Abs.