C++ 日期与时间处理:从入门到精通
日期与时间处理是编程中的基本任务之一。它无处不在:从事件日志记录到截止日期计算和图表绘制。在 C++ 中,这一领域历来不太方便,但随着 C++11 及后续版本(C++14、C++17、C++20)的到来,情况发生了根本性改变。本文将涵盖所有关键方面:从经典的 C 函数到现代的 chrono 库、定时器、格式化和解析。内容对新手和经验丰富的开发者均有帮助,有助于系统化知识。
1. 经典方法:time_t 和 tm 结构体
在 chrono 出现之前,主要工具是 <ctime> 中的函数。这种方法在支持旧代码和简单任务时仍然适用。
主要函数:
time()— 返回当前时间作为time_t(自 1970 年 1 月 1 日以来的秒数)。localtime()— 将time_t转换为tm结构体(本地时间)。gmtime()— 转换为 UTC。strftime()— 将tm格式化为字符串。mktime()— 反向转换:tm→time_t。
#include <iostream>#include <ctime>
int main() { // 获取当前时间 std::time_t now = std::time(nullptr);
// 转换为本地时间 std::tm* local_tm = std::localtime(&now);
// 格式化为字符串 char buffer[80]; std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local_tm);
std::cout << "当前时间: " << buffer << std::endl; return 0;}方法的缺点:
- 仅支持秒级精度(不支持毫秒和微秒)。
- 在多线程环境中不安全(在 POSIX 中使用
localtime_r)。 tm结构体的字段容易混淆(年份偏移 1900,月份从 0 开始)。- 不支持时区和时间间隔。
2. 现代 C++:chrono 库(C++11 及更新版本)
chrono 库是一个强大且类型安全的时间处理工具。它是所有现代 C++ 项目的基础。
主要组件:
- 时钟(clocks):
system_clock(系统时间)、steady_clock(用于测量的单调时钟)、high_resolution_clock(最高精度)。 - 时间点(time_point):绑定到特定时钟。
- 时长(duration):时间间隔(秒、毫秒、纳秒)。
#include <iostream>#include <chrono>#include <thread>
int main() { using namespace std::chrono;
// 当前时间点 auto now = system_clock::now();
// 转换为 time_t 以便显示 std::time_t now_c = system_clock::to_time_t(now); std::cout << "当前时间: " << std::ctime(&now_c);
// 测量执行时间 auto start = steady_clock::now(); std::this_thread::sleep_for(milliseconds(500)); // 模拟工作 auto end = steady_clock::now();
auto duration = duration_cast<milliseconds>(end - start); std::cout << "已过时间: " << duration.count() << " 毫秒" << std::endl;
return 0;}chrono 的优势:
- 高精度(纳秒级)。
- 类型安全(不会意外地将秒与毫秒相加)。
- 支持算术运算(加/减