工作里有个需求,看着只有一行字,做起来却能把人磨掉一层皮:判断某天是不是工作日。我遇到过很多系统,考勤、OA审批流、计费、排产、物流时效、营销活动,最后都会长出一个“工作日/节假日判断”的模块。需求方开口往往是“这不就是判断周一到周五吗,很简单的”,真动手才发现,法定节假日、调休补班、企业自定义工作日、跨年日历、不同时区的业务日期,每一个点都能让实现方案推倒重来。
这篇文章我会从需求分析讲到技术设计,再讲到代码实现和运维坑位。适不适合你参考?只要你的系统需要跟“某天是否上班/放假”打交道,比如HR考勤、ERP排产、WMS预约收货、会议系统预约会议室,那这套思路基本都能套用。我会把最容易踩坑的地方标出来,也会给可以直接抄作业的表结构和计算逻辑。
1. 为什么“判断某天是否工作日”没那么简单
1.1 一个看似简单却坑过很多人的需求
先举一个最常见的例子。运营提了个需求:系统要在下单成功页展示“预计发货日”,遇到周末和法定节假日就顺延到下一个工作日。开发一听,简单,用LocalDate.getDayOfWeek()判断周一到周五就完事了。结果上线没两周,清明节前的周六被当成工作日,客服电话被打爆。
为什么?因为那年的清明节放假安排里,周六是调休补班日,员工正常上班,快递也正常揽收。反过来,还有周六周日里的法定节假日会放假,普通周五也可能被调休成休息日。所以“工作日 = 周一至周五”这个公式在业务系统里根本不成立。
这类问题在考勤系统里爆发得更明显。一个员工的出勤日,要同时受几套日历约束:国家法定节假日放假安排、公司额外福利假(比如年会日)、部门自定义的休息日(比如机房运维部门轮班)、甚至员工个人的班次模板。如果代码里只写一句“周末不算工时”,那调休补班的周六加班费就全算错了。
1.2 “工作日”的口径从来没有统一过
我在做中后台系统时,拿这个问题问过不同业务方,得到的答案至少有三种。第一种是自然周口径,就是周一到周五上班,周六周日休息,不带任何节假日概念,适合做纯数据统计标签。第二种是法定节假日口径,按照每年公布的放假安排执行,上班日包括调休补班的周末,休息日包括被调休的普通工作日,考勤、审批流大多走这个口径。第三种是企业自定义口径,比如客服团队实行排班制、生产线按班次运转,法定节假日在他们那里可能只是一部分规则,还要叠加设备的检修日、库存盘点日、系统停机日。
哪怕同一个系统内,不同模块的口径都可能冲突。考勤模块里周六补班算工作日,因为员工要来上班;但审批流里“顺延到下一个工作日”如果不识别补班日,系统会把审批自动延到周一,可实际上周六大家都在办公室。需求分析阶段如果没把“你这里的‘工作日’到底指什么”问清楚,后面技术方案做得再漂亮也是白搭。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 需求分析:先定口径,再谈技术
2.1 开工前必须问清楚的问题清单
我第一次接这类需求时也吃过亏,上来就设计表结构,结果业务方补充了一句“要能配置明年的排班”,整个方案的一半都白做了。现在我把这类需求当成一个小项目来做,先按清单过一遍,再进入技术设计。
第一个问题,判定结果用在什么场景。是只判断某一天是否工作日,还是需要计算从某天起往后N个工作日是哪天,或者需要判断一段时间内有多少个工作日?这三种场景对应接口复杂度和缓存策略完全不同。如果只是节假日文案展示,后端返回日期类型就够了;如果是审批SLA计算,那还得支持“跳过节假日和下班时段”的连续工时算法。
第二个问题,覆盖哪些日期范围。只查当前日期附近,还是要支持历史查询和远期查询?考勤补卡会追溯到上个月,生产排产可能会排到一年后。远期查询意味着节假日数据必须提前初始化,不能依赖人工当天的维护。
第三个问题,是否需要区分区域。在中国内地、中国香港、东南亚不同地区,节假日安排完全不一样。即便同样在国内,部分民族地区还有地方性假日。如果系统面向多个地域,日期表里必须预留区域字段,并且对外接口要传区域参数。
第四个问题,是否允许业务方自行覆盖。比较常见的场景是公司宣布某天额外放假,或者某些特殊岗位在法定节假日正常排班但事后调休。如果业务方有这个需求,系统的优先级模型就得支持“集团日历 < 公司日历 < 部门日历”。
2.2 节假日数据到底从哪来
这是整个技术方案的命脉。节假日数据有一个特点:规律的部分非常规律,不规律的部分年年变。2023年的中秋和国庆连在一起休了8天,2024年的春节调休又是另一种排列,靠算法推算根本推不出来,只能依赖权威发布的数据。
业界的做法基本有三类。第一类,人工维护一张年度日历表,每年年底由运维或行政把下一年度的放假安排录入系统。优点是非常可控,绝无接口抖动风险;缺点是纯手工操作,容易漏录错录,而且一错就影响全局。第二类,调用第三方节假日API,优点是省事,第一次接入一两个小时就能跑通;缺点是你无法控制上游数据质量,接口偶尔超时、限流甚至关停,节假日数据属于低频高敏感数据,一旦在发布当天挂了,客服压力会瞬间拉满。第三类,买商业数据源或者爬公告,适合中大型企业,有专人维护数据供应链。
我个人踩过的坑是,轻信第三方接口,没有加本地缓存校验,元旦假期前一天第三方接口返回了500,整个页面的“是否节假日”都判断失败了。后来我养成了一个习惯:所有第三方节假日数据只作为初始数据源,同步后必须落库,再在库里做二次校对,线上查询永远优先读本地表。所谓的可靠性,本质上是数据冗余度和兜底策略的可靠性,而不是赌某一个数据源永远健康。
2.3 明确输入输出和性能预期
需求分析阶段还有必要把接口的输入输出定清楚。输入不能只传一个`2
