Scala中修改单参数周末判断函数以支持双日期并计算工作日差
没问题,我来帮你搞定这个Scala日期计算的需求!你已经有了判断单天是否为周末的jourouvree函数,现在只需要基于它扩展出计算两个日期之间工作日差值的逻辑就行,下面是具体的实现步骤和代码:
解决方案思路
核心思路是保留你现有的单天判断函数,在此基础上遍历两个日期区间内的每一天,筛选出非周六周日的工作日并统计数量。同时我们会处理日期顺序颠倒的情况,避免出现异常结果。
第一步:确认并保留原jourouvree函数
假设你的原函数是基于Java 8的LocalDate实现的(Scala中可以直接使用Java的日期API),大致如下:
import java.time.LocalDate import java.time.DayOfWeek // 原函数:判断单个日期是否为工作日(非周六、周日) def jourouvree(date: LocalDate): Boolean = { val day = date.getDayOfWeek day != DayOfWeek.SATURDAY && day != DayOfWeek.SUNDAY }
第二步:实现双日期的工作日差值计算
我们写一个新函数calculateWorkdayDifference,接收起始和结束日期,内部调用jourouvree完成筛选统计:
def calculateWorkdayDifference(startDate: LocalDate, finishDate: LocalDate): Long = { // 先处理日期顺序,确保起始日期不晚于结束日期 val (start, finish) = if (startDate.isAfter(finishDate)) (finishDate, startDate) else (startDate, finishDate) // 生成日期序列,过滤工作日并计数 Iterator.iterate(start)(_.plusDays(1)) .takeWhile(!_.isAfter(finish)) // 包含结束日期在内 .count(jourouvree) }
代码细节解释
- 日期顺序处理:如果用户传入的起始日期比结束日期晚,自动交换两者,保证计算逻辑统一。
- 日期序列生成:用
Iterator.iterate生成从起始日开始,每天递增1的日期流,避免一次性加载大量日期到内存。 - 计数逻辑:通过
count(jourouvree)直接统计符合工作日条件的天数。
第三步:测试验证示例
你可以用以下测试用例验证函数的正确性:
// 测试1:周一到周五,共5个工作日 val start1 = LocalDate.of(2024, 5, 13) // 周一 val finish1 = LocalDate.of(2024, 5, 17) // 周五 println(calculateWorkdayDifference(start1, finish1)) // 输出:5 // 测试2:包含周末的区间,周三到下周一,共4个工作日 val start2 = LocalDate.of(2024, 5, 15) // 周三 val finish2 = LocalDate.of(2024, 5, 20) // 周一 println(calculateWorkdayDifference(start2, finish2)) // 输出:4 // 测试3:日期顺序颠倒的情况 val start3 = LocalDate.of(2024, 5, 17) // 周五 val finish3 = LocalDate.of(2024, 5, 13) // 周一 println(calculateWorkdayDifference(start3, finish3)) // 输出:5
可选:大跨度日期的优化方案
如果你的日期区间跨度很大(比如几年),遍历每一天的效率会偏低,这时候可以用数学计算的方式优化:
def calculateWorkdayDifferenceOptimized(startDate: LocalDate, finishDate: LocalDate): Long = { val (start, finish) = if (startDate.isAfter(finishDate)) (finishDate, startDate) else (startDate, finishDate) val totalDays = java.time.temporal.ChronoUnit.DAYS.between(start, finish) + 1 val fullWeeks = totalDays / 7 val remainingDays = totalDays % 7 // 计算剩余零散天数中的周末数量 var weekendCount = 0 var currentDayOfWeek = start.getDayOfWeek.getValue // 1=周一,7=周日 for (_ <- 0 until remainingDays.toInt) { if (currentDayOfWeek == 6 || currentDayOfWeek == 7) weekendCount += 1 currentDayOfWeek = if (currentDayOfWeek == 7) 1 else currentDayOfWeek + 1 } // 总天数减去所有周末天数 totalDays - (fullWeeks * 2 + weekendCount) }
这种方式通过计算完整周数的周末数量,加上剩余天数中的周末数量,直接得出工作日总数,效率会比遍历高很多。
内容的提问来源于stack exchange,提问作者vero
相关产品推荐
相关产品推荐

