为什么日历上明明有365天,合同里却只说"7个工作日内交付"?
这个看似简单的问题,背后藏着SaaS产品的一个经典设计陷阱。开发者Great Uttar最近开源了一个工作日计算工具,代码不过几十行,却精准戳中了无数业务系统的痛点。
![]()
从"能跑就行"到"能商用才行"
JavaScript原生的日期减法确实简单。两个日期对象相减,除以一天的毫秒数,四舍五入——日历天数到手。
但业务场景从不买账。物流系统要算配送时效,HR系统要算带薪假期,财务系统要算账期利息。这些场景共享一个潜规则:周六周日不算数。
Great Uttar的解决方案很直接:遍历日期区间,用getDay()方法过滤。返回0是周日,6是周六,其余1-5计入工作日。
代码逻辑朴素到近乎笨拙——while循环逐日推进,条件判断累加计数。没有算法优化,没有数学捷径,就是硬算。
但这恰恰是产品思维的关键转折。当业务规则复杂且多变时,可读性和可维护性往往比计算效率更重要。
一个财务系统的账期模块,每年可能因政策调整修改节假日规则三次。这时候,维护者更需要一眼看懂的逻辑,而不是节省几毫秒的黑魔法。
节假日:那个被低估的变量
周末只是起点。真正的复杂度来自公共假期——不同国家、不同地区、甚至不同行业的假期列表千差万别。
Great Uttar的第二版函数引入了一个Set结构存储假期字符串。每次循环时,将当前日期转为ISO格式(YYYY-MM-DD),检查是否命中假期集合。
这个设计暴露了一个产品决策:假期数据谁来维护?
硬编码在代码里?每年更新都要发版。交给用户配置?界面复杂度飙升。对接第三方假期API?又引入外部依赖风险。
Great Uttar的选择是参数化——函数接收holidays数组,默认空值。把决策权交给调用方,工具本身保持中立。
这是小型开源项目的典型生存策略。不做全功能平台,只做可组合的积木。假期数据源可以是手动维护的JSON,可以是政府开放接口,可以是企业内部的OA系统——工具不预设,也不限制。
边界情况:产品鲁棒性的试金石
代码里藏着一个容易忽略的细节:日期顺序校验。
if (end < start) { return 0; }
三行防御性代码,拦截了时间倒流的可能性。用户误操作、数据导入错误、时区转换异常——无数真实世界的脏数据被挡在这里。
另一个微妙之处是日期包含策略。当前实现包含起止日期,周一至周五返回5天。但某些业务场景需要"次日开始计算",这时候需要手动调整起始日期。
Great Uttar没有封装这个变体,而是让调用者自行处理。文档里一句话带过,代码保持简洁。
这种取舍值得玩味。是做成配置项满足所有场景,还是保持核心简单、边缘场景让用户自己扩展?
从提交历史看,Great Uttar明显倾向后者。工具上线后没有膨胀成日期计算全家桶,而是专注做好一件事:给定两个日期和一组假期,返回工作日数量。
为什么这个工具值得关注
技术层面,它没有任何创新。遍历日期是O(n)复杂度,n为区间天数。一年区间最多365次循环,现代JavaScript引擎的微秒级开销可以忽略。
产品层面,它解决了一个被低估的共性需求。npm上搜索"business days",排名靠前的包要么依赖庞大(moment-business-days),要么API设计陈旧(date-fns的addBusinessDays只支持加法)。
Great Uttar的在线计算器(greatuptools.com/business-days-calculator)走了一条更轻量的路:零安装、即时可用、代码可复制。
这个模式正在成为一种趋势。开发者不再追求库的完整性,而是提供"可运行的文档"——一段能直接塞进项目的代码,加上一个验证逻辑的在线沙盒。
对于25-40岁的技术从业者,这种交付方式切中了两个痛点:一是避免依赖地狱,二是减少决策成本。不需要评估库的维护状态、许可证风险、体积开销,需要时复制代码,用完即走。
给你的实用建议
如果你正在处理类似的日期计算需求,可以直接复用这段逻辑,但建议做三处加固:
第一,时区处理。当前代码依赖JavaScript Date的本地时区行为,跨时区场景需要明确指定UTC或特定时区。
第二,假期缓存。如果假期列表来自API,考虑在应用层做缓存,避免每次计算都重复请求。
第三,性能兜底。虽然O(n)可接受,但极端场景(如计算跨越数十年的区间)需要设置上限或改用数学公式优化。
最后,检查你的现有系统。有多少地方还在用日历天数冒充工作日?合同条款、服务等级协议、自动化通知——这些环节的日期计算逻辑,可能正悄悄积累着业务风险。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.