Получите минуты между двумя рабочими днями в Java
Я пытаюсь вычислить минуты между двумя Joda DateTimes или Календари в Java. Конечно, это было бы просто, если бы я мог использовать функцию Minutes.minutesBetween, но я могу рассчитывать только минуты между рабочими днями и 8:00 - 18:00.
Например:
Дата начала: 03-11-2015 16:00
Конечная дата: 03-11-2015 17:00
Это было бы просто, поскольку это было бы точно 60 минут. Потому что это рабочий день и между заданными рабочими часами.
Теперь я пытаюсь вычислить:
Дата начала: 03-11-2015 17:00
Конечная дата: 03-12-2015 09:00
Это должно вернуть 120 минут, хотя между ними намного больше минут, потому что между двумя датами есть только два рабочих часа.
Иногда между двумя датами также есть выходные, эти минуты также не должны добавляться.
Я неустанно пытался реализовать это, но я не нашел решения.
Есть идеи?
Заранее спасибо.
РЕДАКТИРОВАТЬ: Благодаря псевдокоду Дэвиса Броды я нашел решение:
private static int BEGINWORKHOUR = 8;
private static int ENDWORKHOUR = 16;
public int getWorkedMinutes(){
Calendar start = (Calendar) this.startTime.clone();
Calendar end = (Calendar) this.endTime.clone();
if(start.get(Calendar.HOUR_OF_DAY) < BEGINWORKHOUR){
start.set(Calendar.HOUR_OF_DAY, BEGINWORKHOUR);
start.set(Calendar.MINUTE, 0);
}
if(end.get(Calendar.HOUR_OF_DAY) >= ENDWORKHOUR){
end.set(Calendar.HOUR_OF_DAY, ENDWORKHOUR);
end.set(Calendar.MINUTE, 0);
}
int workedMins = 0;
while(!sameDay(start, end)){
workedMins += workedMinsDay(start);
start.add(Calendar.DAY_OF_MONTH, 1);
start.set(Calendar.HOUR_OF_DAY, BEGINWORKHOUR);
start.set(Calendar.MINUTE, 0);
}
workedMins += (end.get(Calendar.MINUTE) - start.get(Calendar.MINUTE)) + ((end.get(Calendar.HOUR_OF_DAY) - start.get(Calendar.HOUR_OF_DAY))*60);
return workedMins;
}
private int workedMinsDay(Calendar start){
if((start.get(Calendar.DAY_OF_WEEK) == 1) || (start.get(Calendar.DAY_OF_WEEK) == 6)) return 0;
else return (60 - start.get(Calendar.MINUTE)) + ((ENDWORKHOUR - start.get(Calendar.HOUR_OF_DAY) - 1)*60);
}
private boolean sameDay(Calendar start, Calendar end){
if(start.get(Calendar.YEAR) == end.get(Calendar.YEAR) && start.get(Calendar.MONTH) == end.get(Calendar.MONTH) &&
start.get(Calendar.DAY_OF_MONTH) == end.get(Calendar.DAY_OF_MONTH)) return true;
else return false;
}
3 ответа
Решение псевдокода может выглядеть примерно так:
onSameWorkDay?
if yes
simple date comparison
if no
days = find number of whole work days between the two dates
dayToMin = days * 8 * 60
minDay1 = find minutes between specified start time and end of day1
minDay2 = find minutes between start of final day and specified end time
totalTime = dayToMin + minDay1 + minDay2
Я думаю, что люди, которые ищут решение этой проблемы, найдут этот репозиторий полезным: https://github.com/ansshuman/silversurfer .
В частности, этот файл кода Java: https://github.com/ansshuman/silversurfer/blob/main/src/com/github/ansshuman/timesurfer/TimeSurfer.java
Его метод «public Long calculateWorkingTimeInMillis(дата начала, дата окончания)» вычисляет рабочее время между двумя датами. Сложность времени и пространства составляет O(1) для программы. Использует старый API даты и календаря, но работает правильно
В последней версии Java в качестве даты проще сделать LocalDateTime .