std::chrono无法自动跳过周末和节假日,必须手动实现工作日计数逻辑:逐天遍历,用weekday判断周一至周五,并排除预存的法定节假日。

用 std::chrono 加手动跳过周末不行,它不处理节假日
标准库的 std::chrono 只能算总天数,std::chrono::duration_cast<:chrono::days></:chrono::days> 得到的是自然日差,完全不管周一到周五。你传入 2024-04-01(周一)和 2024-04-07(周日),它返回 6,但工作日其实是 5。更别说法定节假日了——C++ 标准库压根没内置日历规则。
必须自己实现工作日计数逻辑
核心思路是:从起始日期开始逐天推进,对每一天调用 weekday 判断是否为周一至周五,再排除已知节假日。关键点在于:
-
std::chrono::year_month_day可以把时间点转成年月日,配合std::chrono::weekday获取星期几(wd.c_encoding()返回 0=Sunday, 1=Monday…6=Saturday) - 别用
std::tm+mktime做日期加减,容易因夏令时或闰秒出错;坚持用std::chrono::sys_days进行日粒度运算 - 节假日需外部提供,比如用
std::unordered_set<:chrono::sys_days></:chrono::sys_days>预存(注意:构造sys_days时用year/month/day,别用本地时间)
示例片段:
int workdays_between(std::chrono::year_month_day start, std::chrono::year_month_day end,
const std::unordered_set<:chrono::sys_days>& holidays) {
auto sd = std::chrono::sys_days{start};
auto ed = std::chrono::sys_days{end};
if (sd > ed) return 0;
int count = 0;
for (auto d = sd; d = 1 && wd.c_encoding()
<h3>性能敏感时避免逐天遍历</h3>
<p>跨年计算(比如 2020–2030)逐天循环会慢,可先按整周加速:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master"><img
src="https://img.php.cn/upload/skill/000/000/081/179051228971575.jpg" alt="C++ Code Review Master" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master" class="overflowclass">C++ Code Review Master</a>
<p class="overflowclass">组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。</p>
</div>
<a rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>先对齐到下一个周一,算出开头不足一周的部分</li>
<li>中间整周数 × 5,再减去其中覆盖的节假日天数</li>
<li>结尾剩余天数单独判断</li>
</ul>
<p>但要注意:节假日集合必须支持 O(1) 查询,否则优化无效;且一旦节假日跨多天(如调休上班),该优化反而更难维护。日常业务中,10 年以内直接遍历通常不到 1ms,优先保证逻辑清晰。</p>
<h3>时区与输入格式容易踩坑</h3>
<p>用户输入的 "2024-03-15" 默认是本地时间,但 <code>std::chrono::year_month_day</code> 构造时若未明确指定日历系统,可能因编译器/平台差异误读。务必统一用:</p>
<ul>
<li>
<code>std::chrono::year{2024}/std::chrono::month{3}/std::chrono::day{15}</code> —— 明确、无歧义</li>
<li>避免用字符串解析(如 <code>strptime</code>),它依赖 C locale,Windows 和 Linux 表现不同</li>
<li>如果输入来自 HTTP API 或数据库,确认其时区标注(如 "2024-03-15Z" 是 UTC,要转成本地工作日需考虑时区偏移)</li>
</ul>
<p>真正麻烦的不是算周一到周五,而是“某天是不是调休上班日”——这得查政府公告,C++ 本身解决不了。</p></:chrono::sys_days>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










