Appearance
C++ 日期 & 时间
C++ 提供了多种处理日期和时间的方式,包括 C 风格的时间函数和 C++11 引入的<chrono>库。
1. C 风格的时间函数
C 风格的时间函数定义在<ctime>头文件中。
1.1 获取当前时间
cpp
#include <iostream>
#include <ctime>
int main() {
time_t now = time(nullptr);
std::cout << "当前时间(时间戳): " << now << std::endl;
return 0;
}1.2 将时间戳转换为可读格式
cpp
#include <iostream>
#include <ctime>
int main() {
time_t now = time(nullptr);
// 转换为本地时间
struct tm* local_time = localtime(&now);
// 格式化输出
char buffer[80];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local_time);
std::cout << "本地时间: " << buffer << std::endl;
return 0;
}1.3 常用的时间函数
| 函数 | 描述 |
|---|---|
time(nullptr) | 获取当前时间的时间戳 |
localtime(&now) | 将时间戳转换为本地时间 |
gmtime(&now) | 将时间戳转换为 UTC 时间 |
strftime(buffer, size, format, tm) | 格式化时间 |
asctime(tm) | 将时间转换为字符串 |
ctime(&now) | 将时间戳转换为字符串 |
示例
cpp
#include <iostream>
#include <ctime>
int main() {
time_t now = time(nullptr);
// asctime
std::cout << "asctime: " << asctime(localtime(&now));
// ctime
std::cout << "ctime: " << ctime(&now);
// strftime
char buffer[80];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local_time);
std::cout << "strftime: " << buffer << std::endl;
return 0;
}2. C++11 <chrono> 库
<chrono>库是 C++11 引入的,提供了更现代、更类型安全的时间处理方式。
2.1 时钟
<chrono>库提供了三种时钟:
| 时钟 | 描述 |
|---|---|
std::chrono::system_clock | 系统时钟,表示当前时间 |
std::chrono::steady_clock | 稳定时钟,单调递增 |
std::chrono::high_resolution_clock | 高精度时钟 |
示例
cpp
#include <iostream>
#include <chrono>
int main() {
// 获取当前时间
auto now = std::chrono::system_clock::now();
// 转换为时间戳
auto timestamp = std::chrono::system_clock::to_time_t(now);
std::cout << "当前时间: " << std::ctime(×tamp);
return 0;
}2.2 时间点
时间点表示特定的时间点。
cpp
#include <iostream>
#include <chrono>
int main() {
// 获取当前时间点
auto now = std::chrono::system_clock::now();
// 获取过去的时间点
auto past = now - std::chrono::hours(1);
// 转换为时间戳
auto timestamp = std::chrono::system_clock::to_time_t(past);
std::cout << "一小时前的时间: " << std::ctime(×tamp);
return 0;
}2.3 时间段
时间段表示时间的长度。
cpp
#include <iostream>
#include <chrono>
int main() {
// 定义时间段
std::chrono::hours h(1);
std::chrono::minutes m(30);
std::chrono::seconds s(45);
std::chrono::milliseconds ms(500);
std::chrono::microseconds us(100);
std::chrono::nanoseconds ns(50);
std::cout << "1 小时 = " << h.count() << " 小时" << std::endl;
std::cout << "30 分钟 = " << m.count() << " 分钟" << std::endl;
std::cout << "45 秒 = " << s.count() << " 秒" << std::endl;
std::cout << "500 毫秒 = " << ms.count() << " 毫秒" << std::endl;
std::cout << "100 微秒 = " << us.count() << " 微秒" << std::endl;
std::cout << "50 纳秒 = " << ns.count() << " 纳秒" << std::endl;
return 0;
}2.4 时间段的运算
cpp
#include <iostream>
#include <chrono>
int main() {
// 时间段的加法
auto total = std::chrono::hours(1) + std::chrono::minutes(30);
std::cout << "1 小时 30 分钟 = " << std::chrono::duration_cast<std::chrono::minutes>(total).count() << " 分钟" << std::endl;
// 时间段的减法
auto diff = std::chrono::hours(2) - std::chrono::minutes(30);
std::cout << "2 小时 - 30 分钟 = " << std::chrono::duration_cast<std::chrono::minutes>(diff).count() << " 分钟" << std::endl;
return 0;
}2.5 时间段的转换
cpp
#include <iostream>
#include <chrono>
int main() {
// 定义 1 小时
std::chrono::hours h(1);
// 转换为分钟
auto minutes = std::chrono::duration_cast<std::chrono::minutes>(h);
std::cout << "1 小时 = " << minutes.count() << " 分钟" << std::endl;
// 转换为秒
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(h);
std::cout << "1 小时 = " << seconds.count() << " 秒" << std::endl;
return 0;
}3. 计算时间差
3.1 使用 C 风格的时间函数
cpp
#include <iostream>
#include <ctime>
int main() {
time_t start = time(nullptr);
// 模拟耗时操作
volatile int dummy = 0;
for (int i = 0; i < 1000000000; i++) {
dummy += i;
}
// 使用dummy变量防止编译器优化
(void)dummy;
time_t end = time(nullptr);
double elapsed = difftime(end, start);
std::cout << "耗时: " << elapsed << " 秒" << std::endl;
return 0;
}3.2 使用 <chrono> 库
cpp
#include <iostream>
#include <chrono>
int main() {
auto start = std::chrono::high_resolution_clock::now();
// 模拟耗时操作
volatile int dummy = 0;
for (int i = 0; i < 1000000000; i++) {
dummy += i;
}
// 使用dummy变量防止编译器优化
(void)dummy;
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "耗时: " << duration.count() << " 毫秒" << std::endl;
return 0;
}4. 格式化时间
4.1 使用 strftime
cpp
#include <iostream>
#include <ctime>
int main() {
time_t now = time(nullptr);
struct tm* local_time = localtime(&now);
char buffer[80];
// 格式化为 YYYY-MM-DD HH:MM:SS
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local_time);
std::cout << "格式化时间: " << buffer << std::endl;
// 格式化为 MM/DD/YYYY
strftime(buffer, sizeof(buffer), "%m/%d/%Y", local_time);
std::cout << "格式化时间: " << buffer << std::endl;
// 格式化为 Weekday Month Day HH:MM:SS Year
strftime(buffer, sizeof(buffer), "%A %B %d %H:%M:%S %Y", local_time);
std::cout << "格式化时间: " << buffer << std::endl;
return 0;
}4.2 strftime 格式说明符
| 说明符 | 描述 | 示例 |
|---|---|---|
%Y | 四位数的年份 | 2026 |
%m | 两位数的月份(01-12) | 03 |
%d | 两位数的日期(01-31) | 15 |
%H | 24 小时制的小时(00-23) | 14 |
%M | 分钟(00-59) | 30 |
%S | 秒(00-60) | 45 |
%A | 星期几的完整名称 | Friday |
%B | 月份的完整名称 | March |
%I | 12 小时制的小时(01-12) | 02 |
%p | AM 或 PM | PM |
5. 示例:综合运用
现在,让我们看一个综合运用各种时间操作的例子:
cpp
#include <iostream>
#include <ctime>
#include <chrono>
int main() {
// C 风格的时间函数
std::cout << "C 风格的时间函数:" << std::endl;
time_t now = time(nullptr);
std::cout << "当前时间(时间戳): " << now << std::endl;
struct tm* local_time = localtime(&now);
char buffer[80];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local_time);
std::cout << "本地时间: " << buffer << std::endl;
std::cout << std::endl;
// C++11 <chrono> 库
std::cout << "C++11 <chrono> 库:" << std::endl;
auto chrono_now = std::chrono::system_clock::now();
auto timestamp = std::chrono::system_clock::to_time_t(chrono_now);
std::cout << "当前时间: " << std::ctime(×tamp);
std::cout << std::endl;
// 时间段
std::cout << "时间段:" << std::endl;
std::chrono::hours h(1);
std::chrono::minutes m(30);
std::chrono::seconds s(45);
std::cout << "1 小时 = " << h.count() << " 小时" << std::endl;
std::cout << "30 分钟 = " << m.count() << " 分钟" << std::endl;
std::cout << "45 秒 = " << s.count() << " 秒" << std::endl;
std::cout << std::endl;
// 时间段的运算
std::cout << "时间段的运算:" << std::endl;
auto total = h + m;
std::cout << "1 小时 + 30 分钟 = " << std::chrono::duration_cast<std::chrono::minutes>(total).count() << " 分钟" << std::endl;
std::cout << std::endl;
// 时间段的转换
std::cout << "时间段的转换:" << std::endl;
auto minutes = std::chrono::duration_cast<std::chrono::minutes>(h);
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(h);
std::cout << "1 小时 = " << minutes.count() << " 分钟" << std::endl;
std::cout << "1 小时 = " << seconds.count() << " 秒" << std::endl;
std::cout << std::endl;
// 计算时间差
std::cout << "计算时间差:" << std::endl;
auto start = std::chrono::high_resolution_clock::now();
// 模拟耗时操作
volatile int dummy = 0;
for (int i = 0; i < 1000000000; i++) {
dummy += i;
}
// 使用dummy变量防止编译器优化
(void)dummy;
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "耗时: " << duration.count() << " 毫秒" << std::endl;
return 0;
}5. C++20 <chrono> 库的新特性
C++20 扩展了 <chrono> 库,添加了日历库和时区支持等新特性。
5.1 日历库
C++20 引入了日历库,用于处理日期相关的操作:
cpp
#include <iostream>
#include <chrono>
int main() {
// 使用 C++20 日历库
using namespace std::chrono;
// 获取当前日期
auto today = floor<days>(system_clock::now());
auto ymd = year_month_day{today};
std::cout << "当前日期: "
<< static_cast<int>(ymd.year()) << "-"
<< static_cast<unsigned>(ymd.month()) << "-"
<< static_cast<unsigned>(ymd.day()) << std::endl;
// 日期计算
auto tomorrow = today + days{1};
auto ymd_tomorrow = year_month_day{tomorrow};
std::cout << "明天日期: "
<< static_cast<int>(ymd_tomorrow.year()) << "-"
<< static_cast<unsigned>(ymd_tomorrow.month()) << "-"
<< static_cast<unsigned>(ymd_tomorrow.day()) << std::endl;
return 0;
}5.2 时区支持
C++20 还添加了时区支持:
cpp
#include <iostream>
#include <chrono>
int main() {
// 使用 C++20 时区库
using namespace std::chrono;
// 获取当前时间(UTC)
auto now = system_clock::now();
// 转换为本地时间
auto local_now = zoned_time{current_zone(), now};
std::cout << "本地时间: " << local_now << std::endl;
// 转换为其他时区
try {
auto nyc_now = zoned_time{"America/New_York", now};
std::cout << "纽约时间: " << nyc_now << std::endl;
auto tokyo_now = zoned_time{"Asia/Tokyo", now};
std::cout << "东京时间: " << tokyo_now << std::endl;
} catch (const std::exception& e) {
std::cerr << "时区错误: " << e.what() << std::endl;
}
return 0;
}小结
C++ 日期和时间包括:
C 风格的时间函数:
time(nullptr):获取当前时间的时间戳localtime(&now):将时间戳转换为本地时间strftime(buffer, size, format, tm):格式化时间
C++11
<chrono>库:- 时钟:
std::chrono::system_clock、std::chrono::steady_clock、std::chrono::high_resolution_clock - 时间点:表示特定的时间点
- 时间段:表示时间的长度
- 时钟:
计算时间差:
- 使用 C 风格的时间函数:
difftime() - 使用 C++11
<chrono>库:std::chrono::duration_cast<>
- 使用 C 风格的时间函数:
格式化时间:
- 使用
strftime格式化时间
- 使用
关键概念:
- 时间戳:表示从某个固定时间点(通常是 1970 年 1 月 1 日)到现在的秒数
- 时间点:表示特定的时间点
- 时间段:表示时间的长度
- 格式化时间:将时间转换为可读的字符串
掌握日期和时间的处理对于编写需要处理时间的程序非常重要。在后续章节中,我们将学习 C++ 的基本输入输出。