iso周数需通过strftime("%v")配合localtime获取,因std::chrono不直接支持;c++20虽增强日历功能,但仍需手动计算或借助第三方库如howard hinnant的date库。

ISO 周数和 std::chrono 不直接兼容
标准 std::chrono(C++20 之前)不提供 ISO 周数计算,std::chrono::system_clock::now() 返回的是时间点,不是日历信息。C++20 引入了 <chrono></chrono> 的日历扩展,但默认仍不暴露 ISO 周数——你需要手动计算或借助 <ctime></ctime> 的底层支持。
用 std::gmtime + strftime 最可靠
ISO 周数定义为:一年中包含该年第一个周四的周为第 1 周,且每周从周一算起。POSIX 的 strftime 支持 %G(ISO 年)和 %V(ISO 周数),但必须配合 std::gmtime 或 std::localtime 使用,且注意时区影响。
实操建议:
-
std::time_t t = std::time(nullptr)获取当前秒级时间戳 - 用
std::localtime(&t)转为本地时区的std::tm(ISO 周数通常按本地日历理解,除非明确要求 UTC) - 调用
strftime(buf, sizeof(buf), "%V", &tm)提取两位数字字符串,再转为整数 - 注意:
std::localtime返回静态缓冲区指针,多线程下需用std::localtime_r(POSIX)或std::localtime_s(Windows)
C++20 std::chrono::year_month_day 怎么绕不过去 ISO 周逻辑
C++20 可以把时间点转成日历日期:auto ymd = std::chrono::year_month_day{std::chrono::floor<:chrono::days>(std::chrono::system_clock::now())}</:chrono::days>,但它只给年、月、日,不提供周数。你得自己实现 ISO 周计算:
- 先算出该日期所在星期的周一(例如:用
std::chrono::weekday得到星期几,再减去偏移) - 再算出该周一属于哪一年的第几周:找到当年第一个周四,反推第 1 周的周一,再比较距离
- 容易踩坑:1 月 1 日可能属于上一年的第 52 或 53 周;12 月 31 日可能属于下一年的第 1 周
- 推荐直接复用已验证逻辑,比如 Howard Hinnant 的
date库(非标准但广泛使用),它提供iso_week::year_weeknum_day
跨平台输出整数周数的最小可行代码
以下代码在 Linux/macOS/Windows(启用 _CRT_SECURE_NO_WARNINGS)均可编译运行,返回 int 类型的 ISO 周数:
#include <ctime>
#include <iostream>
int get_iso_week() {
std::time_t t = std::time(nullptr);
std::tm tm_buf{};
#if defined(_WIN32)
localtime_s(&tm_buf, &t);
#else
localtime_r(&t, &tm_buf);
#endif
char buf[3];
strftime(buf, sizeof(buf), "%V", &tm_buf);
return std::atoi(buf);
}
// 调用示例
// std::cout
<p>真正麻烦的不是获取,而是理解:ISO 周数是日历系统的一部分,和“自然周”或“月份内第几周”完全无关。哪怕你只想要一个整数,也得先确认时区语义、边界年份归属,否则一月第一周可能返回 52 而不是 1。</p></iostream></ctime>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











