Получите минуты между двумя рабочими днями в 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 .

Другие вопросы по тегам