C++日期与时间
C语言风格函数
#include <ctime>
cpp
#ifndef _CRT_NO_TIME_T
#ifdef _USE_32BIT_TIME_T
typedef __time32_t time_t;
#else
typedef __time64_t time_t;
#endif
#endif
std::time_t其实就是整形
| 函数 | 功能描述 | 返回值类型 |
|---|---|---|
time() |
获取当前日历时间 | time_t |
localtime_s() |
将time_t转换为本地时间的tm结构 | tm* |
gmtime_s() |
将time_t转换为UTC时间的tm结构 | tm* |
mktime() |
将tm结构转换为time_t | time_t |
strftime() |
格式化时间输出(可自定义格式%Y-%m-%d) | size_t |
asctime_s |
格式化时间输出(不可自定义格式) | 返回0表示成功 |
clock() |
获取程序处理器时间(可用来计时) | clock_t |
difftime() |
计算两个time_t的时间差 | double |
| tm结构体 |
| 成员 | 类型 | 描述 | 范围 |
|---|---|---|---|
tm_sec |
int |
秒 | [0, 60] including leap second |
tm_min |
int |
分 | [0-59] |
tm_hour |
int |
时 | [0-23] |
tm_mday |
int |
月中的日 | [1-31] |
tm_mon |
int |
月(从0开始) | [0-11],0表示一月 |
tm_year |
int |
年(从1900开始) | 实际年份-1900 |
tm_wday |
int |
星期几(0=周日) | [0-6],0表示周日 |
tm_yday |
int |
年中的日(从0开始) | [0-365] |
tm_isdst |
int |
夏令时标志 | >0:启用, 0:禁用, <0:未知 |
| 格式说明 |
| 格式 | 说明 |
|---|---|
| %Y | 4位年份 (2025) |
| %y | 2位年份 (23) |
| %m | 月份 (01-12) |
| %d | 日期 (01-31) |
| %H | 小时 (00-23) |
| %M | 分钟 (00-59) |
| %S | 秒 (00-60) |
| %A | 完整星期几名称 |
| %a | 缩写星期几名称 |
| %B | 完整月份名称 |
| %b | 缩写月份名称 |
| %Z | 时区名称 |
cpp
void printTm(std::tm* tm) {
char buffer[50];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm);
std::cout << buffer << std::endl;
//if (asctime_s(buffer, sizeof(buffer), tm) == 0) {
// std::cout << buffer << std::endl;
//}
}
int main()
{
system("chcp 65001");
clock_t start = clock();
// 获取当前时间(秒)
std::time_t now = time(nullptr);
std::cout << "now= " << now << std::endl;
// 获取当前时间(秒)
std::time_t currentTime;
time(¤tTime);
currentTime += 10000;
std::cout << "currentTime= " << currentTime << std::endl;
// 转换为本地时间
std::tm tmNow;
localtime_s(&tmNow, &now);
printTm(&tmNow);
// 转换为UTC时间
std::tm tmCurrentTime;
gmtime_s(&tmCurrentTime, ¤tTime);
printTm(&tmCurrentTime);
// 两个std::time_t时间差
double diff = now > currentTime ? difftime(now, currentTime) : difftime(currentTime, now);
std::cout << "diff= " << diff << std::endl;
// 增加天数(跨月了不会自增计算,直接报错)
tmNow.tm_mday += 1;
printTm(&tmNow);
// std::tm -> d::time_t
now = mktime(&tmNow);
std::cout << "now= " << now << std::endl;
clock_t end = clock();
long duration = (double)(end - start) / CLOCKS_PER_SEC;
std::cout << "duration= " << (end - start) << "ms" << std::endl;
std::cout << "duration= " << duration << "s" << std::endl;
}
C++风格函数
#include <chrono>
三大组件
| 组件类型 | 作用 | 主要类型 | 线程安全 |
|---|---|---|---|
| Clock (时钟) | 提供时间点 | system_clock, steady_clock, high_resolution_clock |
是 |
| Time Point (时间点) | 表示特定时刻 | time_point<Clock, Duration> |
是 |
| Duration (持续时间) | 表示时间间隔 | duration<Rep, Period> |
是 |
1、时钟类型
| 时钟类型 | 描述 | 可转换为 time_t | 单调性 | 用途 | 分辨率 |
|---|---|---|---|---|---|
system_clock |
系统实时时钟 | ✅ 是 | ❌ 否 | 日期时间显示、与其他系统交互 | 通常为纳秒 |
steady_clock |
稳定时钟 | ❌ 否 | ✅ 是 | 时间间隔测量、超时控制 | 高分辨率 |
high_resolution_clock |
高分辨率时钟 | 可能 | 可能 | 高精度计时 | 最高可用分辨率 |
utc_clock |
协调世界时 | 是(通过to_time_t) |
非单调 | 表示协调世界时(UTC),考虑闰秒调整 | 通常为纳秒级 |
tai_clock |
国际原子时 | 是(通过to_time_t) |
单调 | 表示国际原子时(TAI),不考虑闰秒,稳定递增 | 通常为纳秒级 |
gps_clock |
全球定位系统时 | 是(通过to_time_t) |
单调 | 全球定位系统时间,以1980年1月6日为起点 | 通常为纳秒级 |
file_clock |
文件系统时间 | 否 | 取决于实现 | 文件系统时间戳操作,用于文件创建和修改时间 | 通常为100纳秒 |
local_t |
本地时间 | 是(需配合system_clock) | 非单调 | 本地时间,不带时区信息的挂钟时间 | 与system_clock相同 |
cpp
int main()
{
system("chcp 65001");
// system_clock 获取当前日期时间
auto sys_now = std::chrono::system_clock::now();
std::time_t time_t_now = std::chrono::system_clock::to_time_t(sys_now + 1h);
std::cout << "system_clock: " << time_t_now << endl;
// steady_clock 测量时间间隔
auto start = std::chrono::steady_clock::now();
auto end = std::chrono::steady_clock::now();
end += 100s;
std::cout << "steady_clock diff: " << std::chrono::duration_cast<std::chrono::seconds>(end - start) << endl;
// high_resolution_clock 高精度计时(底层可能是steady_clock的别名)
auto high_res_start = std::chrono::high_resolution_clock::now();
auto high_res_end = std::chrono::high_resolution_clock::now();
high_res_end += 10min;
std::cout << "high_resolution_clock diff: " << std::chrono::duration_cast<std::chrono::seconds>(high_res_end - high_res_start) << endl;
// utc_clock 协调世界时间
auto utc_time_start = clock_cast<std::chrono::utc_clock>(sys_now);
utc_time_start = std::chrono::utc_clock::from_sys(sys_now);
auto utc_time_end = std::chrono::utc_clock::now();
utc_time_end += 2h;
std::cout << "utc_clock diff: " << std::chrono::duration_cast<std::chrono::seconds>(utc_time_end - utc_time_start) << endl;
// tai_clock 国际原子时间
auto tai_clock_start = std::chrono::tai_clock::from_utc(utc_time_start);
auto tai_clock_end = std::chrono::tai_clock::now();
tai_clock_end += 1min;
std::cout << "tai_clock diff: " << std::chrono::duration_cast<std::chrono::seconds>(tai_clock_end - tai_clock_start) << endl;
// gps_clock 全球定位系统时
auto gps_clock_start = std::chrono::gps_clock::from_utc(utc_time_start);
auto gps_clock_end = std::chrono::gps_clock::now();
gps_clock_end += 1min;
std::cout << "gps_clock diff: " << std::chrono::duration_cast<std::chrono::seconds>(gps_clock_end - gps_clock_start) << endl;
// file_clock 文件系统时间
auto file_clock_start = std::chrono::file_clock::from_utc(utc_time_start);
auto file_clock_end = std::chrono::file_clock::now();
file_clock_end += 2min;
std::cout << "file_clock diff: " << std::chrono::duration_cast<std::chrono::seconds>(file_clock_end - file_clock_start) << endl;
}
2、时间间隔
| Duration 类型 | Ratio | 描述 | 示例 |
|---|---|---|---|
std::chrono::nanoseconds |
std::ratio<1, 1000000000> |
纳秒 | 1ns |
std::chrono::microseconds |
std::ratio<1, 1000000> |
微秒 | 1μs |
std::chrono::milliseconds |
std::ratio<1, 1000> |
毫秒 | 1ms |
std::chrono::seconds |
std::ratio<1> |
秒 | 1s |
std::chrono::minutes |
std::ratio<60> |
分钟 | 1min |
std::chrono::hours |
std::ratio<3600> |
小时 | 1h |
std::chrono::days |
std::ratio<86400> |
天 | 1d |
std::chrono::weeks |
duration<int, ratio_multiply<ratio<7>, days::period>> |
周 | |
std::chrono::months |
duration<int, ratio_divide<years::period, ratio<12>>> |
月 | |
std::chrono::years |
duration<int, ratio_multiply<ratio<146097, 400>, days::period>> |
年 | 1y |
| 运算符 |
| 运算类型 | 语法 | 说明 | 示例 |
|---|---|---|---|
| 构造 | duration<Rep, Period> d(value) |
创建持续时间 | seconds(5) |
| 转换 | duration_cast<To>(from) |
显式单位转换 | duration_cast<minutes>(seconds(120)) |
| 加法 | d1 + d2 |
相同或兼容单位相加 | seconds(5) + milliseconds(500) |
| 减法 | d1 - d2 |
相同或兼容单位相减 | minutes(10) - seconds(30) |
| 乘法 | d * scalar |
持续时间乘以标量 | seconds(5) * 2 |
| 除法 | d / scalar |
持续时间除以标量 | minutes(10) / 2 |
| 取模 | d1 % d2 |
持续时间取模 | seconds(125) % minutes(2) |
3、时间点
| 操作类型 | 语法 | 说明 | 示例 |
|---|---|---|---|
| 获取当前时间 | Clock::now() |
获取当前时间点 | system_clock::now() |
| 构造 | time_point<Clock, Duration>(duration) |
从持续时间构造 | time_point<system_clock>(seconds(0)) |
| 时间运算 | tp + duration |
时间点加持续时间 | now + hours(24) |
| 时间差 | tp1 - tp2 |
计算两个时间点的差 | end - start |
| 比较 | tp1 < tp2 |
比较时间点先后 | deadline < now |
新特性
1、字面量
| 字面量 | 对应类型 | 示例 |
|---|---|---|
ns |
nanoseconds |
1000ns |
us |
microseconds |
1000us |
ms |
milliseconds |
1000ms |
s |
seconds |
60s |
min |
minutes |
5min |
h |
hours |
24h |
d |
day |
1d |
y |
year |
1y |
2、截取
| 特性 | 描述 | 示例 |
|---|---|---|
floor/ceil/round |
持续时间舍入 | floor<milliseconds>(1234567ns) |
v 后缀 |
无单位数值 | 42s / 2 |