Ch 7: 日期与时间
- 掌握 chrono 库的基本用法
- 处理时间戳和 Duration
- 使用时钟类型
- 理解时区处理
7.1 Python datetime
Section titled “7.1 Python datetime”datetime 是 Python 处理时间的标准方式:
from datetime import datetime, timedelta, timezone
# 当前位置时间now = datetime.now()utc_now = datetime.now(timezone.utc)
# 构造时间dt = datetime(2024, 1, 15, 12, 30, 45)
# 时间戳(秒)timestamp = now.timestamp()
# 从时间戳构造from_ts = datetime.fromtimestamp(timestamp)
# 时间运算later = dt + timedelta(days=7, hours=3)earlier = dt - timedelta(weeks=1)diff = later - dt # timedelta 对象
# 格式化formatted = dt.strftime("%Y-%m-%d %H:%M:%S")# "2024-01-15 12:30:45"
# 解析parsed = datetime.strptime("2024-01-15", "%Y-%m-%d")Python timedelta
Section titled “Python timedelta”from datetime import timedelta
# 创建td = timedelta(days=7, hours=3, minutes=30, seconds=15)
# 属性td.days # 7td.seconds # 3*3600 + 30*60 + 15 = 12615td.total_seconds() # 7天的总秒数
# 运算td1 = timedelta(days=3)td2 = timedelta(days=5)td3 = td1 + td2 # 8天td4 = td2 - td1 # 2天td5 = td1 * 2 # 6天7.2 C++ chrono 库
Section titled “7.2 C++ chrono 库”chrono 是 C++ 处理时间的标准库:
#include <chrono>#include <ctime>#include <format>#include <iostream>
int main() { // 当前时间 auto now = std::chrono::system_clock::now();
// Duration - 时间段 using namespace std::chrono; seconds sec(42); milliseconds ms(1000); microseconds us = ms * 1000;
// Duration 转换 auto total_ms = std::chrono::duration_cast<milliseconds>(sec); // 42000 ms
// 时间点 auto tp = std::chrono::system_clock::now();
// time_t 转换 std::time_t t = std::chrono::system_clock::to_time_t(now);
// tm 转换 std::tm* tm = std::localtime(&t);
// 格式化 (C++20) std::string formatted = std::format("{:%Y-%m-%d %H:%M:%S}", *tm); std::cout << formatted << std::endl;
return 0;}chrono 核心组件
Section titled “chrono 核心组件”#include <chrono>
// 1. Duration - 时间段using namespace std::chrono;
// 预定义类型seconds s = 42;milliseconds ms = s * 1000;microseconds us = std::chrono::duration_cast<microseconds>(s);minutes m = std::chrono::duration_cast<minutes>(s);
// 2. Time Point - 时间点auto now = std::chrono::system_clock::now();
// 3. Clocks - 时钟// system_clock - 系统时钟,可调// steady_clock - 单调时钟,不受系统时间调整// high_resolution_clock - 高精度时钟7.3 Duration 详解
Section titled “7.3 Duration 详解”#include <chrono>#include <iostream>
int main() { using namespace std::chrono;
// 创建 Duration seconds s1(42); seconds s2 = 42s; // C++14 字面量 milliseconds ms = 1000ms;
// 转换 seconds from_ms = std::chrono::duration_cast<seconds>(ms);
// 算术运算 seconds total = s1 + s2; seconds doubled = s1 * 2; seconds halved = s1 / 2;
// 比较 if (s1 < s2) { /* ... */ }
// 获取数值 std::cout << s1.count() << " seconds" << std::endl;
// 睡眠 std::this_thread::sleep_for(seconds(1));
return 0;}Duration 常用类型
Section titled “Duration 常用类型”| 类型 | 定义 | Python timedelta |
|---|---|---|
std::chrono::nanoseconds | 10⁻⁹ 秒 | microseconds |
std::chrono::microseconds | 10⁻⁶ 秒 | milliseconds |
std::chrono::milliseconds | 10⁻³ 秒 | - |
std::chrono::seconds | 1 秒 | seconds |
std::chrono::minutes | 60 秒 | minutes |
std::chrono::hours | 3600 秒 | hours |
std::chrono::days | 86400 秒 | days |
std::chrono::weeks | 604800 秒 | weeks |
7.4 时钟类型
Section titled “7.4 时钟类型”| 时钟 | 说明 | Python 等价 |
|---|---|---|
system_clock | 系统真实时间,可调 | datetime |
steady_clock | 单调时钟,不受系统时间调整 | time.monotonic |
high_resolution_clock | 高精度时钟 | time.perf_counter |
#include <chrono>#include <iostream>
int main() { using namespace std::chrono;
// system_clock - 适合显示给用户 auto sys_now = system_clock::now(); std::time_t t = system_clock::to_time_t(sys_now); std::cout << std::ctime(&t) << std::endl;
// steady_clock - 适合测量时间间隔 auto start = steady_clock::now(); // ... 做些工作 ... auto end = steady_clock::now();
auto elapsed = end - start; std::cout << "Elapsed: " << duration<double, std::milli>(elapsed).count() << " ms" << std::endl;
return 0;}7.5 测量执行时间
Section titled “7.5 测量执行时间”Python
Section titled “Python”import time
# 方法1: time.time()start = time.time()# ... 工作 ...end = time.time()print(f"Elapsed: {end - start:.3f}s")
# 方法2: time.perf_counter()(更高精度)start = time.perf_counter()# ... 工作 ...end = time.perf_counter()print(f"Elapsed: {end - start:.6f}s")
# 方法3: timeitimport timeitresult = timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)print(f"Elapsed: {result:.3f}s")#include <chrono>#include <iostream>
// 方法1: steady_clockauto start = std::chrono::steady_clock::now();// ... 工作 ...auto end = std::chrono::steady_clock::now();
auto elapsed = end - start;std::cout << "Elapsed: " << std::chrono::duration<double, std::milli>(elapsed).count() << " ms" << std::endl;
// 方法2: system_clockauto wall_start = std::chrono::system_clock::now();// ... 工作 ...auto wall_end = std::chrono::system_clock::now();
// 高精度方式template<typename Func>auto measure(Func f) { auto start = std::chrono::high_resolution_clock::now(); f(); auto end = std::chrono::high_resolution_clock::now(); return end - start;}
auto dur = measure([]() { // ...});7.6 时间格式化
Section titled “7.6 时间格式化”Python
Section titled “Python”from datetime import datetime
dt = datetime(2024, 1, 15, 12, 30, 45)
# strftime - 格式化formatted = dt.strftime("%Y-%m-%d %H:%M:%S")formatted = dt.strftime("%B %d, %Y") # "January 15, 2024"formatted = dt.strftime("%a %b %d") # "Mon Jan 15"
# strptime - 解析parsed = datetime.strptime("2024-01-15", "%Y-%m-%d")C++20 std::format
Section titled “C++20 std::format”#include <chrono>#include <format>#include <iostream>#include <ctime>
int main() { std::time_t t = std::time(nullptr); std::tm* tm = std::localtime(&t);
// C++20 格式化 std::cout << std::format("{:%Y-%m-%d %H:%M:%S}", *tm) << std::endl; std::cout << std::format("{:%B %d, %Y}", *tm) << std::endl; std::cout << std::format("{:%a %b %d}", *tm) << std::endl;
// 手动格式化(C++17 之前) char buf[100]; std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm); std::cout << buf << std::endl;
return 0;}格式化说明符
Section titled “格式化说明符”| Python | C++ | 说明 |
|---|---|---|
%Y | %Y | 四位年份 |
%m | %m | 月份 |
%d | %d | 日期 |
%H | %H | 小时(24制) |
%M | %M | 分钟 |
%S | %S | 秒 |
%B | %B | 月份全名 |
%b | %b | 月份缩写 |
%a | %a | 星期缩写 |
7.7 时区处理
Section titled “7.7 时区处理”Python
Section titled “Python”from datetime import datetime, timezone, timedelta
# UTCutc = datetime.now(timezone.utc)
# 本地时间local = datetime.now() # 本地时区
# 转换from zoneinfo import ZoneInfony = datetime.now(ZoneInfo("America/New_York"))
# 手动时区tz = timezone(timedelta(hours=8))china = datetime(2024, 1, 15, 12, tzinfo=tz)C++ 时区(C++20)
Section titled “C++ 时区(C++20)”#include <chrono>#include <format>
int main() { using namespace std::chrono;
// C++20 支持时区 auto now = system_clock::now();
// 转换为 time_t auto t = system_clock::to_time_t(now);
// 转换为 UTC tm std::tm utc_tm = *std::gmtime(&t);
// 转换为本地 tm std::tm local_tm = *std::localtime(&t);
// C++20 chrono 支持时区(需要 <chrono> + <format> // 很多编译器尚未完全支持
return 0;}std::chrono是 C++ 时间库system_clock对应datetimesteady_clock用于测量时长- C++20
std::format格式化时间 - 时区支持在 C++20 引入,但编译器支持不完整
下章预告:ch08 数学与随机数。