Прошедшее время без учета выходных и праздничных дней на Яве

Я реализовал секундомер, который отлично работает, не учитывая, что праздничные и выходные дни не должны учитываться в общей продолжительности. Я искал какую-нибудь библиотеку с открытым исходным кодом, где я мог бы получить прошедшее время, пройдя момент начала, момент окончания и набор государственных праздников (выходные не учитываются). Единственная библиотека, которая упрощает мне жизнь, — это net.sf.jtemporal, но мне еще нужно расширить ее функциональность. Может ли кто-нибудь сказать мне, есть ли какая-нибудь полезная библиотека для получения желаемой функциональности?


person Community    schedule 18.09.2008    source источник


Ответы (5)


Как я уже упоминал, здесь, вероятно, лучший и самый простой подход - создать таблицу, содержащую информацию о каждом дне (количество рабочих дней с начала/выходного дня и т. д.; одна строка в день = 365 строк в год) а затем просто используйте функцию подсчета / с правильным выбором.

person Matej    schedule 18.09.2008
comment
Извините, я отредактировал свой вопрос, указав, что я использую язык Java. Большое спасибо. - person ; 18.09.2008

Сомневаюсь, что вы найдете что-то конкретное. Но достаточно легко создать собственную логику. Вот какой-то псевдокод...

private long CalculateTimeSpan(DateTime BeginDate, DateTime EndDate, ArrayList<DateTime> BankHollidays)
{
    long ticks = 0;
    while (BeginDate <= EndDate) // iterate until reaching end
    {
        if ((BeginDate is holliday?) || (BeginDate is Weekend?))
             skip;
        else
             ticks += (24*60*60*1000);

        BeginDate = BeginDate + 1 day; // add one day and iterate
    }

    return ticks;
}
person bastos.sergio    schedule 18.09.2008
comment
Я бы использовал HashSet, чтобы избежать повторения значений, но мне это кажется немного неэффективным, особенно потому, что если гранулярность равна секундам, вам нужно повторять 60x60x24 раза за каждый день. Любая другая более эффективная идея для этого случая. Спасибо - person ; 18.09.2008

Вы тоже считаете только банковские часы? с 9:00 до 15:00? Или это 24 часа в сутки?

person Nick Berardi    schedule 18.09.2008
comment
Это 24 часа в сутки. У меня есть истекший таймер, но я хочу вернуть эту продолжительность, вычитая продолжительность выходных и праздничных дней в пределах этого интервала. - person ; 18.09.2008

Вам следует взглянуть на Joda Time. Это гораздо лучший API даты/времени, чем тот, который включен в Java.

person Heath Borders    schedule 18.09.2008
comment
Спасибо, но я уже сделал это, и это лучше, чем на Java, но в любом случае я нашел net.sf.jtemporal более подходящий для моей цели. ИспользуяCompactPeriodStorage.periodIterator(период периода), вы можете получить CloseableIterator, который выполняет итерацию по всем периодам хранения, которые пересекают данный период. - person ; 18.09.2008

Я думаю, что это было бы правильным решением для того, что вы ищете. Он рассчитывает прошедшее время (учитывая, что в одном рабочем дне 24 часа) без учета государственных праздников и выходных в:

/**
 * Calculate elapsed time in milliseconds
 * 
 * @param startTime
 * @param endTime
 * @return elapsed time in milliseconds
 */

protected long calculateElapsedTimeAux(long startTime, long endTime) { 
    CustomizedGregorianCalendar calStartTime = new CustomizedGregorianCalendar(this.getTimeZone());
    CustomizedGregorianCalendar calEndTime = new CustomizedGregorianCalendar(this.getTimeZone());
    calStartTime.setTimeInMillis(startTime);
    calEndTime.setTimeInMillis(endTime);
    long ticks = 0;

    while (calStartTime.before(calEndTime)) { // iterate until reaching end 
        ticks = ticks + increaseElapsedTime(calStartTime, calEndTime);
    }

    return ticks;
}

private long increaseElapsedTime(CustomizedGregorianCalendar calStartTime, CustomizedGregorianCalendar calEndTime) {
    long interval;
    long ticks = 0;

    interval = HOURS_PER_DAY*MINUTES_PER_HOUR*SECONDS_PER_MIN*MILLISECONDS_PER_SEC; // Interval of one day

    if ( calEndTime.getTimeInMillis() - calStartTime.getTimeInMillis() < interval) {
        interval = calEndTime.getTimeInMillis() - calStartTime.getTimeInMillis();
    }

    ticks = increaseElapsedTimeAux(calStartTime, calEndTime, interval);
    calStartTime.setTimeInMillis(calStartTime.getTimeInMillis() + interval);

    return ticks;
}

protected long increaseElapsedTimeAux(CustomizedGregorianCalendar calStartTime, CustomizedGregorianCalendar calEndTime, long interval) {
    long ticks = 0;

    CustomizedGregorianCalendar calNextStartTime = new CustomizedGregorianCalendar(this.getTimeZone());
    calNextStartTime.setTimeInMillis(calStartTime.getTimeInMillis() + interval);

    if ( (calStartTime.isWorkingDay(_nonWorkingDays) && calNextStartTime.isWorkingDay(_nonWorkingDays)) ) { // calStartTime and calNextStartTime are working days
        ticks = interval;

    }
    else {
        if (calStartTime.isWorkingDay(_nonWorkingDays)) { // calStartTime is a working day and calNextStartTime is a non-working day
            ticks = (calStartTime.getNextDay().getTimeInMillis() - calStartTime.getTimeInMillis());
        }
        else {
            if (calNextStartTime.isWorkingDay(_nonWorkingDays)) { // calStartTime is a non-working day and calNextStartTime is a working day
                ticks = (calNextStartTime.getTimeInMillis() - calStartTime.getNextDay().getTimeInMillis());
            }
            else {} // calStartTime and calEndTime are non-working days
        }
    }

    return ticks;
}
person Community    schedule 26.09.2008