I'm trying to calculate how many minutes are between two dates while excluding periods of time that are arbitrarily defined and occur weekly. I also need to be able to calculate the reverse, where given a time, calculate X number of minutes forward excluding those time periods.
For example, I may have two periods [Fri 5:31pm - Sat 2:26pm] and [Tuesday 3:37am - Thursday 1:14am] that I don't want to count when figuring out the minutes between two dates and when calculating forward.
I currently have code that does this for only one gap, though it's not super efficient and is becoming a strain on my system. I also need to accommodate multiple defined gaps which I currently do not do.
My code which does this for one gap looks like this (hideStart
and hideEnter
are the start and end DateTime for the gap, absoluteLowValue
is the starting time from which I am calculating the distance or time between):
public int absoluteDistance(DateTime high){
long totalMinutes = new Duration(absoluteLowValue,high).getStandardMinutes();
if (!gapHider.isHidingGaps())
return (int)totalMinutes;
int minutesPerWeek = 10080;
long minutesPerHide = new Duration(hideStart, hideEnd).getStandardMinutes();
long numFullWeeks = totalMinutes/minutesPerWeek;
long remainder = totalMinutes%minutesPerWeek;
totalMinutes -= numFullWeeks*minutesPerHide;
DateTime latestEnd = high;
if (latestEnd.getDayOfWeek() == hideEnd.getDayOfWeek() && latestEnd.getSecondOfDay() < hideEnd.getSecondOfDay()){
latestEnd = latestEnd.minusWeeks(1);
}
while (latestEnd.getDayOfWeek() != hideEnd.getDayOfWeek())
latestEnd = latestEnd.minusDays(1);
latestEnd = latestEnd.withTime(hideEnd.getHourOfDay(),
hideEnd.getMinuteOfHour(),
hideEnd.getSecondOfMinute(),
hideEnd.getMillisOfSecond());
DateTime latestStart = high;
if (latestStart.getDayOfWeek() == hideStart.getDayOfWeek() && latestStart.getSecondOfDay() < hideStart.getSecondOfDay()){
latestStart = latestStart.minusWeeks(1);
}
while (latestStart.getDayOfWeek() != hideStart.getDayOfWeek())
latestStart = latestStart.minusDays(1);
latestStart = latestStart.withTime(hideStart.getHourOfDay(),
hideStart.getMinuteOfHour(),
hideStart.getSecondOfMinute(),
hideStart.getMillisOfSecond());
long timeToNearestEnd = new Duration(latestEnd, high).getStandardMinutes();
long timeToNearestStart = new Duration(latestStart, high).getStandardMinutes();
if (timeToNearestEnd < remainder){
totalMinutes -= minutesPerHide;
}else if (timeToNearestStart < remainder){
totalMinutes -= new Duration(latestStart, high).getStandardMinutes();
}
return (int)totalMinutes;
}
public DateTime timeSinceAbsLow(int index){
if (absoluteLowValue != null){
if (!gapHider.isHidingGaps())
return absoluteLowValue.plusMinutes(index);
DateTime date = absoluteLowValue;
long minutesPerWeek = 10080;
long minutesPerHide = new Duration(hideStart, hideEnd).getStandardMinutes();
int difference = (int)(minutesPerWeek - minutesPerHide);
int count = 0;
while (index - count >= difference){
date = date.plusWeeks(1);
count += difference;
}
int remaining = index - count;
DateTime nextStart = date;
while (nextStart.getDayOfWeek() != hideStart.getDayOfWeek())
nextStart = nextStart.plusDays(1);
nextStart = nextStart.withTime(hideStart.getHourOfDay(),
hideStart.getMinuteOfHour(),
hideStart.getSecondOfMinute(),
hideStart.getMillisOfSecond());
long timeDiff = new Duration(date, nextStart).getStandardMinutes();
if (timeDiff < remaining){
date = nextStart.plusMinutes((int)minutesPerHide);
count+= timeDiff;
remaining = index - count;
}
date = date.plusMinutes(remaining);
return date;
}
return new DateTime();
}
Is there a better or easier way of doing this process? I imagine that if I add in the amount of logic to loop through a list of "gaps" that it will just slow it down even more. I'm open to not using Jodatime, I just happen to be using that currently. Any help appreciated!