给定节假日安排,怎么自动算出调休规则?

1148 字
6 分钟
给定节假日安排,怎么自动算出调休规则?

AstraSchedule 里我做了一个很有意思的功能,通过公开的节假日安排数据能够自动推算出当年或往年的调休关系,具体是哪一天工作日补的哪一天休息日,也能反查休息日是从哪个工作日调过来的。

TLDR 算法流程#

按时间顺序,一一配对。

为每个 detail 建立映射

对组内调休日排序

按顺序配对

对组内补班日排序

添加到最终映射表

输入年份

从公开数据获取全年工作日与节假日数据

遍历节假日,筛选出调休日

按相同 detail 对调休日进行分组

按相同 detail 对工作日进行分组

返回映射表

为每个 detail 建立映射

对组内调休日排序

按顺序配对

对组内补班日排序

添加到最终映射表

输入年份

从公开数据获取全年工作日与节假日数据

遍历节假日,筛选出调休日

按相同 detail 对调休日进行分组

按相同 detail 对工作日进行分组

返回映射表

算法其实不难,甚至说特别简单。后面主要讲讲这个算法是怎么寻思出来的。

怎么想出来的#

其实也不是很难想,我们平时也会说调休哪一天调的哪一天。尽管更多人更在乎哪天上班哪天下班,但对于学校和学生来说还要关心到底要上哪天的课。这是对于学校来说每年必不可少的脑力劳动。但既然每年都能发出通知来,那说明调休很大可能有一个一一对应的关系。

其实光从 “调休” 这个词来说,他是一个动宾短语,“调” 作为动词有 “调剂” 的意思

新华字典 调(tiáo)

调剂:以临万货,以~盈虚。

“调休”的本质是重新调配时间资源——当公共假期”盈”(多了休息日)时,就从周末”虚”处(借出休息日)来补,最终实现工作日与休息日的 总量平衡

到这其实就能直接想出上述的算法了。但是如果你语文跟我一样稀烂,其实上面是我现查的,那也可以从另一个角度来思考:化学和数学。

初中化学就教了 化合价 的概念。初中化学教材告诉我们,原子为了形成一个相对稳定结构,会与其他原子相结合。怎么结合呢?以离子为例,电子发生了 “转移” 。类比到调休上,是 节假日 发生了 转移 。所以我们也可以试着给某一天加上一个 “价态”。

比如我们分析一下 2026 年的元旦假期安排:把本该是工作日的休息日标记成 +1 价,把本该是休息日的工作日标记成 -1 价。原本就是休息日或者工作日没变的标记成 0 价。

日期星期状态价态
2026-01-01元旦,本来就休息0
2026-01-02休息,但本该是工作日+1
2026-01-03周六,本来就休息0
2026-01-04工作,但本该是休息日-1

Amazing!有趣的是,我们发现这样标记恰好和化合价一样,满足 代数和为 0 的性质。也就是说,同一假期分组内,各日期的价态代数和为 0。而且这个算法的结构也比化合价更简单,化合价还有 +2 价 -3 价这样的,但这个算法只有 -1 0 +1 三种价态。

然后到了初中数学发挥的部分:已知

a+b=0a + b = 0

那么 a 与 b 互为相反数

Wikipedia 相反数(加法逆元)

实数中,数 aa 的相反数 a−a ,称为其加法逆元

显然,aabb 任一为 00,最终 a+ba+b 都不可能为 00。所以 aabb 必然一个是 1-1 一个是 +1+1。那么,由上文的结论可得,每个假期分组的日期价态代数和为 0 可以表述成下面这样:

(a1+b1)+(a2+b2)++(an+bn)=0(a_1 + b_1)+(a_2+b_2)+\cdots+(a_n+b_n)=0

那么对于每一组 (an+bn)(a_n+b_n) 就恰好对应一天休息日和一天工作日。这说明,调休节假日和调休工作日就是可以一一对应起来的

最后就是怎么对应的问题,这个就是经验而言,注意到,一般把最早的调休节假日和最早的调休工作日对调。也就是说,大部分情况下是按日期顺序来调休的。

那就很简单了:按假日分组,然后按时间顺序排好调休工作日和调休节假日,基于上文的结论,直接一一配对即可。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

给定节假日安排,怎么自动算出调休规则?
https://khbit.cn/posts/valance-cal/
作者
KuoHu
发布于
2026-07-26
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
KuoHu
INFP 5w4 sp/sx 549 IEI RLUAI
公告
这里没有公告。
分类
标签
最新动态
站点统计
文章
11
分类
4
标签
11
总字数
43,415
运行时长
0
最后活动
0 天前
站点信息
构建平台
Cloudflare Pages
博客版本
Firefly v6.15.10
文章许可
CC BY-NC-SA 4.0