2017-04-21 69 views
0

我偶然发现过几次这个问题,并且有一些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

根据您的使用情况,预先计算并查找它(我们实际上是在一家公司中为一年剩余的日子做了这些工作 - 我们使用的是Lotus Notes,并且考虑在飞行中做这件事实在太痛苦) –

+0

为什么要预先计算并缓存一些可以在固定时间内完成的事情? –

+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 
    } 

我认为本周周一(对于乔达默认)开始。

我也认为在周六和下周五之间有5个工作日,而在周一和下周五之间只有4个工作日。

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 
} 
相关问题