Get minutes between two working days in Java
Asked Answered
B

3

0

I am trying to calculate the minutes between two Joda DateTimes or Calendars in Java. Ofcourse this would be simple if I could use the Minutes.minutesBetween function, but I can only count the minutes between working days and 8:00 AM - 6:00 PM.

E.g.:

Startdate: 03-11-2015 16:00
Enddate: 03-11-2015 17:00

This would be simple, as it would be exactly 60 minutes. Because it's a workday and between the given work hours.

Now what I am trying to calculate is:

Startdate: 03-11-2015 17:00
Enddate: 03-12-2015 09:00

This should return 120 minutes even though there's a lot more minutes in between, because there's only two working hours between the two dates.

Sometimes there's also a weekend between two dates, those minutes should not be added either.

I have been trying tirelessly to implement this, but I have not found a solution.

Any ideas?

Thanks in advance.

EDIT: Thanks to Davis Broda's pseudocode I have found a solution:

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;
}
Braden answered 11/3, 2015 at 19:9 Comment(2)
I think you may need to write some code, or show what you have so far.Harvey
Sharing the things I came up with would really not make any sense. I haven't even come close to a solution. I have spent hours on googling about this and came up empty. If the solutions is obvious, I must be using the wrong keywords... Posting here is always a last resort for me (as you can see by the very few questions I ask).Braden
G
3

a pseudocode solution might look something like the below.

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
Gadgeteer answered 11/3, 2015 at 19:17 Comment(5)
Thanks a lot, this might get me somewhere. Have not thought about it this way. shameBraden
Yes sir, that got me there in 20 minutes. Thank you for your help and sorry for wasting your time.Braden
@Braden No need to apologize. You're not the only one to struggle with this issue. I've seen several other people run into the same wall. This sort of thing is basically what stackoverflow is for.Gadgeteer
The pseudocode does not take weekends in account, but I have found a solution never the less. I will edit my question with the solution. Thank you for your help.Braden
@Braden Weekdays would be little more than another iteration of this code, with onSameWorkWeek replacing onSameWorkDay? and similar replacements.I figured that if you got the days working you wouldn't have too much trouble with the weeks, so it wasn't worth making the answer more complicated by inserting week-handling code..Gadgeteer
S
1

I think people on lookout for a solution of this problem will find this repo useful: https://github.com/ansshuman/silversurfer

Specifically this java code file: https://github.com/ansshuman/silversurfer/blob/main/src/com/github/ansshuman/timesurfer/TimeSurfer.java

Its method 'public Long calculateWorkingTimeInMillis(Date start, Date end)' calculates working time between two dates. Time and Space complexity both are O(1) for the program. Uses the old Date and calendar api but works properly though

Spandex answered 6/2, 2022 at 20:4 Comment(1)
This is a great solution - thank youMeill
R
0

In the latest Java version as date it is easier to do with LocalDateTime.

Rhodes answered 22/12, 2022 at 13:43 Comment(2)
Thanks for the contribution, What you say is very true and helpful. We don’t value link-only answers much on Stack Overflow, so you may want to explain a little about how LocalDateTime helps find the result (with or without code, it’s no requirement).Whall
LocalDateTime is actually the wrong class to use here. That class lacks the context of a time zone. So calculating elapsed time between moments is impossible as your calculation will fail to account for anomalies such Daylight Saving Time (DST).Ninette

© 2022 - 2025 — McMap. All rights reserved.