C++如何判断一个日期是否落在指定的时间跨度内

星降

星降

2026-06-13

890人浏览

原创

应将日期统一转换为绝对时间点(如std::chrono::sys_days)再比较,c++20推荐year_month_day+sys_days,c++11/17需用mktime并注意时区、无效日期和2038问题。

c++如何判断一个日期是否落在指定的时间跨度内

std::chrono 比较日期需要先统一成时间点

直接比较年月日结构(比如 struct tm 或自定义 Date)无法判断是否在时间跨度内,因为缺少时区、日历规则和可比性。必须转成可排序的绝对时间点,std::chrono::system_clock::time_point 是最常用选择。

关键前提是:你得有起始、结束和待测日期的完整时间点(至少精确到日)。如果只有年/月/日,需补零构造为当天 00:00:00 UTC(或本地时区,但必须一致)。

  • 推荐用 C++20 的 std::chrono::year_month_day + sys_days 转换,简洁且无歧义
  • 若限于 C++11/14/17,可用 std::mktime,但注意它会修改 tm_isdst、受本地时区影响,且 2038 年问题需警惕
  • 避免用字符串比较(如 "2023-05-01" > "2023-04-30"),虽对 ISO 格式有效,但不表达语义,且无法处理跨年/闰秒等边界

C++20:用 year_month_daysys_days 做安全区间判断

C++20 提供了类型安全、无时区陷阱的日历操作。核心是把日期转成 sys_days(即 system_clock::time_point 的天精度封装),再用常规比较运算符。

#include <chrono>
#include <iostream><p>namespace c = std::chrono;</p><div class="aritcle_card flexRow artxards">
											<div class="artcardd flexRow">
												<a class="aritcle_card_img" rel="nofollow" href="/xiazai/shouce/1510" title="C函数速查手册(CHM版)"><img
														src="https://img.php.cn/upload/manual/000/000/001/5d6de31fedca2993.png" alt="C函数速查手册(CHM版)" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
												<div class="aritcle_card_info flexColumn">
													<a rel="nofollow" href="/xiazai/shouce/1510" title="C函数速查手册(CHM版)" class="overflowclass">C函数速查手册(CHM版)</a>
													<p class="overflowclass">C函数速查手册(CHM版)</p>
												</div>
												<a rel="nofollow" href="/xiazai/shouce/1510" title="C函数速查手册(CHM版)" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
												</a>
											</div>
										</div>
<p>bool is_in_range(int y, int m, int d,
c::year_month_day start, c::year_month_day end) {
c::sys_days target{c::year{y}/c::month{m}/c::day{d}};
c::sys_days s{start};
c::sys_days e{end};
return s </p>
<p>// 使用示例:判断 2024-02-29 是否在 [2024-01-01, 2024-12-31] 内
int main() {
auto start = c::year{2024}/c::month{1}/c::day{1};
auto end   = c::year{2024}/c::month{12}/c::day{31};
std::cout </p></iostream></chrono>
  • c::year{y}/c::month{m}/c::day{d} 构造合法 year_month_day;若非法(如 2023-02-30),运行时抛 std::runtime_error
  • sys_days 自动归一化:传入 2024/2/30 会被转成 2024-03-01,但建议先校验再转换
  • 区间是闭区间:包含起始和结束当天的整个 24 小时

C++11/17:用 std::mktime 需手动处理时区与无效输入

老标准下没有日历类型,只能靠 std::tm + std::mktime。它把本地时间转为 time_t(通常为秒数),但行为依赖本地时区设置,且对无效日期返回 -1。

<pre class="brush:php;toolbar:false;">#include <ctime>
#include <climits><p>bool is_in_range_tm(int y, int m, int d, std::tm start, std::tm end) {
std::tm t = {};
t.tm_year = y - 1900;
t.tm_mon  = m - 1; // 0-based
t.tm_mday = d;
t.tm_hour = t.tm_min = t.tm_sec = 0;
t.tm_isdst = -1; // 让 mktime 推断夏令时</p>
<pre class="brush:php;toolbar:false;"><code>std::time_t target = std::mktime(&t);
if (target == -1) return false;

std::time_t s = std::mktime(&start);
std::time_t e = std::mktime(&end);
return s != -1 && e != -1 && target >= s && target <p>}</p></code>
  • tm_isdst = -1
是必须项,否则可能误判(尤其跨 DST 边界时)
  • std::mktime 会修改传入的 tm 结构体(如调整 tm_wday),不能复用同一变量判断多个日期
  • 所有日期必须在同一时区上下文里处理;若需 UTC,改用 std::timegm(非标准但广泛支持),或用 std::put_time + std::get_time 手动解析
  • 容易被忽略的边界:闰年、月末、时区与精度

    看似简单的“日期在范围内”判断,实际藏着几个高频翻车点:

    • 2024-02-29 合法,但 2023-02-29 传给 std::mktime 会静默变成 2023-03-01 —— 你本意是“无效日期即不在范围内”,结果却误判为在
    • std::chrono::system_clock::now() 获取当前时间再截断到日,和用 year_month_day 构造的“今天”可能因时区偏移差一天(尤其在 UTC+13 或 UTC-12 地区)
    • 若时间跨度含小时分钟(如 “2024-01-01 14:00 到 2024-01-03 09:00”),仅比较日期会漏掉精度信息;此时必须用 sys_seconds 或更高精度类型
    • 跨年计算(如 2023-12-31 到 2024-01-02)看似简单,但手写逻辑易错;用 sys_daystime_t 可交给标准库处理

    真正麻烦的从来不是“怎么写”,而是“怎么定义‘落在范围内’——按本地日?UTC 日?还是带具体时刻的区间?” 这个前提没对齐,代码越写越像补丁。

    C++免费学习笔记(深入):立即使用
    在学习笔记中,你将探索 C++ 的入门与实战技巧!

    相关文章

    PHP速学视频免费教程(入门到精通)
    PHP速学视频免费教程(入门到精通)

    PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

    下载

    相关标签:

    c++ c++日期时间

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    相关专题

    更多
    c++和c语言的区别有哪些
    c++和c语言的区别有哪些

    c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

    2024.03.14

    834

    9

    c++和python学习顺序推荐
    c++和python学习顺序推荐

    一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

    2024.03.14

    753

    6

    python和c++学习性价比分析
    python和c++学习性价比分析

    Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

    2024.03.14

    244

    5

    c语言和c++一样吗
    c语言和c++一样吗

    c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    2024.03.14

    242

    5

    c语言和c++先学哪个好
    c语言和c++先学哪个好

    初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    2024.03.14

    224

    5

    c语言和c++的区别和联系
    c语言和c++的区别和联系

    c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    2024.03.14

    463

    5

    c++软件中文更改教程
    c++软件中文更改教程

    对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

    2024.03.21

    1130

    9

    python和java和c++学习性价比分析
    python和java和c++学习性价比分析

    Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

    2024.03.22

    859

    7

    c++和c语言学习顺序推荐
    c++和c语言学习顺序推荐

    对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

    2024.03.25

    1028

    9

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    RabbitMQ 教程手册
    RabbitMQ 教程手册

    共0课时 | 0人学习

    Linux man-pages 项目
    Linux man-pages 项目

    共0课时 | 0人学习

    C# 教程
    C# 教程

    共94课时 | 20.2万人学习