Я реализовал секундомер, который отлично работает, не учитывая, что праздничные и выходные дни не должны учитываться в общей продолжительности. Я искал какую-нибудь библиотеку с открытым исходным кодом, где я мог бы получить прошедшее время, пройдя момент начала, момент окончания и набор государственных праздников (выходные не учитываются). Единственная библиотека, которая упрощает мне жизнь, — это net.sf.jtemporal, но мне еще нужно расширить ее функциональность. Может ли кто-нибудь сказать мне, есть ли какая-нибудь полезная библиотека для получения желаемой функциональности?
Прошедшее время без учета выходных и праздничных дней на Яве
Ответы (5)
Как я уже упоминал, здесь, вероятно, лучший и самый простой подход - создать таблицу, содержащую информацию о каждом дне (количество рабочих дней с начала/выходного дня и т. д.; одна строка в день = 365 строк в год) а затем просто используйте функцию подсчета / с правильным выбором.
Сомневаюсь, что вы найдете что-то конкретное. Но достаточно легко создать собственную логику. Вот какой-то псевдокод...
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;
}
Вы тоже считаете только банковские часы? с 9:00 до 15:00? Или это 24 часа в сутки?
Вам следует взглянуть на Joda Time. Это гораздо лучший API даты/времени, чем тот, который включен в Java.
Я думаю, что это было бы правильным решением для того, что вы ищете. Он рассчитывает прошедшее время (учитывая, что в одном рабочем дне 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;
}