2017-04-21 73 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 
} 
相關問題