我之前偶然发现了这个问题并且有一些SO答案,但它们非常慢,例如
def businessDaysBetween(startDate: DateTime, endDate: DateTime): Seq[DateTime] = {
1 to daysBetween(startDate, endDate) map {
startDate.withFieldAdded(DurationFieldType.days(), _)
} diff holidays filter {
_.getDayOfWeek() match {
case DateTimeConstants.SUNDAY | DateTimeConstants.SATURDAY => false
case _ => true
}
}
}
def daysBetween(startDate: DateTime, endDate: DateTime) =
Days.daysBetween(startDate.toDateMidnight(), endDate.toDateMidnight()).getDays()
我的问题不仅是如何计算两个日期之间的工作日数,还有最快的解决方案。请注意,我只需要知道工作日的数量,而不是实际的日期。
答案 0 :(得分:1)
在我看来,这是一个稍微更具可读性的版本,具有相同的O(C)
复杂度:
def getPreviousWorkDay(d: DateTime): DateTime = {
d.withDayOfWeek(Math.min(d.getDayOfWeek, DateTimeConstants.FRIDAY)).withTimeAtStartOfDay()
}
def businessDaysBetween(startDate: DateTime, endDate: DateTime): Int = {
val workDayStart = getPreviousWorkDay(startDate)
val workDayEnd = getPreviousWorkDay(endDate)
val daysBetween = Days.daysBetween(workDayStart, workDayEnd).getDays
val weekendDaysBetween = daysBetween / 7 * 2
val additionalWeekend = if(workDayStart.getDayOfWeek > workDayEnd.getDayOfWeek) 2 else 0
daysBetween - weekendDaysBetween - additionalWeekend
}
我认为星期一是星期一开始的(Joda的默认值)。
我还认为在星期六和下周五之间有5个工作日,而在星期一和下周五之间只有4个工作日。
答案 1 :(得分:0)
这是我认为最快的解决方案,只需要考虑startDate
所代表的一周中哪一天。复杂性为O(C)
:
def businessDaysBetween(startDate: DateTime, endDate: DateTime): Int = {
val numDays = daysBetween(startDate, endDate)
val numHolidays: Int = startDate.getDayOfWeek match {
case DateTimeConstants.MONDAY => (numDays / 7)*2 + (if (numDays % 7 > 4) min(numDays % 7 - 4, 2) else 0)
case DateTimeConstants.TUESDAY => (numDays / 7)*2 + (if (numDays % 7 > 3) min(numDays % 7 - 3, 2) else 0)
case DateTimeConstants.WEDNESDAY => (numDays / 7)*2 + (if (numDays % 7 > 2) min(numDays % 7 - 2, 2) else 0)
case DateTimeConstants.THURSDAY => (numDays / 7)*2 + (if (numDays % 7 > 1) min(numDays % 7 - 1, 2) else 0)
case DateTimeConstants.FRIDAY => (numDays / 7)*2 + (if (numDays % 7 > 0) min(numDays % 7, 2) else 0)
case DateTimeConstants.SATURDAY => 1 + (numDays / 7)*2 + (if (numDays % 7 > 0) 1 else 0)
case DateTimeConstants.SUNDAY => 1 + (numDays / 7)*2 + (if (numDays % 7 > 5) 1 else 0)
}
numDays - numHolidays
}