2024年节假日判断:从硬编码到动态策略的JS实战演进
每逢节假日临近,无论是开发请假审批系统、智能排班工具,还是设计营销活动的自动开关,一个绕不开的核心需求就是:如何让代码准确地“知道”今天是不是休息日?这个问题看似简单,背后却涉及法定节假日、周末以及令人头疼的调休安排。直接调用API固然方便,但面对需要离线运行、对数据主权有要求,或者需要极高定制化灵活性的场景,一套自主可控的日期判断逻辑就显得尤为重要。今天,我们就深入探讨如何用JavaScript构建一个不仅准确、而且健壮、易于维护的节假日判断方案,并分享我在多个实战项目中踩坑后总结出的最佳实践。
1. 核心逻辑拆解:超越简单的数组比对
最直观的思路,确实是准备两个数组:一个存放所有放假的日期(包括周末和法定假日),另一个存放需要上班的周末(即调休日)。判断时,检查目标日期是否在放假数组中,或者是否为周末,同时还要确保它不在调休上班的数组中。这个逻辑本身是清晰的,但原始的实现方式存在几个可以优化的关键点。
1.1 日期格式的“陷阱”与标准化处理
原始代码中,数组里的日期字符串格式是 "2024-4-4" 而非 "2024-04-04",原因是 Date 对象的 getMonth() 和 getDate() 方法返回的是未补零的数字。这种强依赖格式的做法非常脆弱。
// 脆弱的格式依赖
const curDate = new Date();
const formattedDate = `${curDate.getFullYear()}-${curDate.getMonth()+1}-${curDate.getDate()}`;
// 输出可能是 "2024-4-3",与数组中的 "2024-04-03" 无法匹配
更好的做法是,无论数组中的格式如何,在比对时都使用一个统一的、标准化的日期键。我推荐使用 ISO 8601 格式的日期部分(YYYY-MM-DD) 作为键值,因为它既标准又易于排序和比较。
function toDateKey(date) {
const year = date.getFullYear();
// getMonth()返回0-11,需要+1,然后通过padStart补零
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
// 使用示例
const today = new Date();
const todayKey = toDateKey(today); // 例如 "2024-04-03"
这样,我们的节假日数组和调休数组也应当使用这种标准化格式。这不仅解决了匹配问题,还让数据本身更清晰。
1.2 数据结构优化:从数组到集合(Set)
原始代码使用数组,并通过 indexOf 或 includes 方法检查包含关系。对于小型、静态的数据集,这没问题。但考虑到可读性和性能(尤其是当需要频繁判断时),使用 ES6 的 Set 是更优的选择。Set 提供了接近 O(1) 时间复杂度的 has 方法,用于检查成员是否存在。
// 使用 Set 存储节假日和调休日
const holidaySet = new Set([
'2024-04-04', // 清明节
'2024-04-05',
'2024-04-06',
'2024-05-01', // 劳动节
// ... 其他节假日
]);
const workdayWeekendSet = new Set([
'2024-04-07', // 清明调休上班
'2024-04-28', // 劳动节调休上班
// ... 其他调休上班日
]);
// 判断逻辑变得非常简洁高效
function isHoliday(date) {
const dateKey = toDateKey(date);
const isWeekend = date.getDay() === 0 || date.

&spm=1001.2101.3001.5002&articleId=153715545&d=1&t=3&u=5a53e1ed4bd34a8eaa71b926b8640f2d)
673

被折叠的 条评论
为什么被折叠?



