year_month_day不能直接比较大小,需拆为int y,m,d手动比较或转sys_days;构造自动归一化但需调用.ok()校验合法性;加减运算必须显式指定days/months/years单位;与time_point互转要注意sys_days和local_days时区差异。

year_month_day不能直接比较大小
它不是时间点,也不重载 或 <code>==(C++20 中仅支持 operator== 和 operator,但需显式启用比较),直接写 ymd1 会编译失败。必须先转成 <code>sys_days 才能做区间判断或排序。
常见错误写法:if (ymd >= start_ymd && ymd —— 这里 <code>start_ymd 和 end_ymd 若仍是 year_month_day 类型,就无法通过编译。
- 正确做法:用
sys_days{ymd}转换后比较,例如sys_days{ymd} >= sys_days{start_ymd} -
sys_days是system_clock::time_point的天精度别名,底层是整数天数,天然支持算术和比较 - 若只比年月日字典序(如配置过滤),拆成
int y, m, d手动比较反而更轻量、无转换开销
构造时会静默归一化,但 ok() 才是真校验
year_month_day{2024y/2/30} 不会报错,而是自动变成 2024y/3/1(因为 2 月只有 29 天);但业务上你往往需要知道“用户输入是否合法”,这时不能依赖构造结果,而要主动调用 .ok()。
-
year_month_day{2023y/2/29}.ok()返回false,表示该日期在公历中不存在 -
year_month_day{2024y/2/29}.ok()返回true,闰年有效 - 从字符串解析时(如
from_stream),非法输入可能抛std::runtime_error,但构造字面量不会
加减运算单位必须显式指定,days{} 不能省略
想加 10 天,必须写 ymd + days{10};写成 ymd + 10 会触发编译错误。这是类型安全的核心设计——防止把“10 小时”误当“10 天”。
- 支持的单位:
days、months、years,分别处理不同粒度的进位逻辑(比如+ months{1}自动跨月,保留日部分;+ days{30}是纯天数偏移 -
year_month_day_last类型支持+ months{1},但不支持+ days{1}—— 它只管“某月最后一天”,没定义“下一天”语义 - 跨年计算(如
2024y/12/31 + days{1})自动进到2025y/1/1,无需手动判断
与 time_point 互转必须注意精度和时区含义
sys_days{ymd} 表示该日期在 system_clock 纪元(1970-01-01)起的第 N 天,对应 UTC 时间的 00:00:00;而 local_days{ymd} 对应本地时区的 00:00:00 —— 两者数值可能不同,尤其在夏令时切换日附近。
- 统一用
sys_days做存储和比较,避免本地时区漂移 - 若需输出本地时间,优先用
zoned_time(C++20)而非手动加偏移 - 从
system_clock::now()提取日期,推荐floor<days>(tp)</days>,比time_t → tm更简洁且无时区歧义
.ok() 或错用 local_days 时,问题才真正浮现。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











