Time API文档
概述
mc::time 模块提供毫秒精度和秒精度的时间抽象,封装 std::chrono 并扩展 ISO 8601 字符串解析/格式化、variant 序列化等能力。核心类型包括:milliseconds(毫秒精度时长)、time_point(毫秒精度时间点)、time_point_sec(秒精度时间点,轻量替代)。
主要特性
- 双精度支持:
milliseconds + time_point 提供毫秒精度,time_point_sec 提供秒精度轻量替代
- 直观的时长字面量:
seconds(n)、minutes(n)、hours(n)、days(n) 工厂函数,可读性强
- ISO 8601 解析与格式化:
from_iso_string 解析、to_iso_string / to_string 格式化,与外部系统交互简便
- 全方位比较与算术:所有类型均支持完整的比较运算符和
+= -= + - 算术运算
- 与 std::chrono 无缝互转:所有类型均可通过构造函数或转换运算符与
std::chrono 互操作
- variant 序列化:三种时间类型均支持
to_variant / from_variant,可存入 variant 或通过 D-Bus 传输
- 编译期友好:大量
constexpr 构造函数和运算符,支持编译期计算
基本用法
创建时长和进行算术运算
#include <mc/time.h>
#include <cassert>
int main()
{
mc::milliseconds timeout = mc::seconds(30);
mc::milliseconds interval = mc::minutes(5);
mc::milliseconds one_day = mc::days(1);
mc::milliseconds total = timeout + interval;
total += mc::seconds(10);
int64_t ms = total.count();
int64_t sec = total.to_seconds();
auto std_dur = std::chrono::milliseconds(500);
mc::milliseconds mc_dur(std_dur);
assert(mc_dur.count() == 500);
std::chrono::seconds std_sec = mc_dur;
assert(std_sec.count() == 0);
return 0;
}
获取当前时间和计算时间差
#include <mc/time.h>
#include <thread>
#include <iostream>
int main()
{
mc::time_point start = mc::time_point::now();
std::this_thread::sleep_for(std::chrono::milliseconds(150));
mc::time_point end = mc::time_point::now();
mc::milliseconds elapsed = end - start;
std::cout << "耗时: " << elapsed.count() << " ms" << std::endl;
if (end > start) {
std::cout << "end 在 start 之后" << std::endl;
}
mc::time_point deadline = start + mc::seconds(10);
mc::time_point before = deadline - mc::milliseconds(500);
return 0;
}
ISO 8601 字符串解析与格式化
#include <mc/time.h>
#include <string>
#include <iostream>
int main()
{
mc::time_point tp = mc::time_point::from_iso_string("2024-06-15T08:30:00Z");
std::cout << "解析成功: " << tp.to_string() << std::endl;
mc::time_point now = mc::time_point::now();
mc::string_view sv = now.to_iso_string();
std::string persistent(sv.data(), sv.size());
std::cout << "当前时间: " << persistent << std::endl;
return 0;
}
使用 time_point_sec 轻量时间点
#include <mc/time.h>
#include <cassert>
int main()
{
mc::time_point_sec epoch;
assert(epoch.sec_since_epoch() == 0);
mc::time_point_sec tp(1700000000u);
mc::time_point_sec now = mc::time_point_sec::now();
mc::time_point fine = mc::time_point::now();
mc::time_point_sec coarse(fine);
mc::time_point back = static_cast<mc::time_point>(coarse);
mc::time_point_sec later = now + 3600u;
mc::time_point_sec earlier = now - 60u;
mc::time_point result = now + mc::milliseconds(500);
return 0;
}
API 详细说明
时长工厂函数
| 函数 |
描述 |
异常 |
seconds(int64_t s) |
创建 s 秒的 milliseconds 时长 |
不抛异常 |
minutes(int64_t m) |
创建 m 分钟的 milliseconds 时长 |
不抛异常 |
hours(int64_t h) |
创建 h 小时的 milliseconds 时长 |
不抛异常 |
days(int64_t d) |
创建 d 天的 milliseconds 时长 |
不抛异常 |
mc::milliseconds
毫秒精度时长类,内部以 int64_t 存储毫秒数。
| 方法/运算符 |
描述 |
异常 |
explicit milliseconds(int64_t count = 0) |
从毫秒数构造 |
不抛异常 |
template milliseconds(const std::chrono::duration<Rep, Period>&) |
从 std::chrono::duration 构造,自动转换精度 |
不抛异常 |
static constexpr milliseconds maximum() |
返回最大正时长(0x7fffffffffffffff ms) |
不抛异常 |
static constexpr milliseconds zero() |
返回零时长 |
不抛异常 |
count() const |
返回原始毫秒数(int64_t) |
不抛异常 |
to_seconds() const |
返回秒数(int64_t,向下取整) |
不抛异常 |
operator std::chrono::duration<Rep, Period>() |
转换为 std::chrono::duration,自动转换精度 |
不抛异常 |
operator+ operator-(友元) |
时长相加减,返回新的 milliseconds |
不抛异常 |
operator+= operator-= |
原地加减 |
不抛异常 |
operator== operator!= |
相等/不等比较 |
不抛异常 |
operator> operator>= operator< operator<=(友元) |
全序比较 |
不抛异常 |
mc::time_point
毫秒精度时间点类,内部以 milliseconds 存储自纪元以来的时长。
| 方法/运算符 |
描述 |
异常 |
explicit time_point(milliseconds elapsed = milliseconds()) |
从时长构造,默认为零时刻 |
不抛异常 |
template time_point(const std::chrono::time_point<Clock, Duration>&) |
从 std::chrono::time_point 构造,自动转换精度 |
不抛异常 |
static time_point now() |
获取当前时间点 |
不抛异常 |
static constexpr time_point maximum() |
返回最大时间点 |
不抛异常 |
static constexpr time_point min() |
返回最小时间点(零时刻) |
不抛异常 |
static time_point from_iso_string(mc::string_view s) |
从 ISO 8601 字符串解析时间点 |
字符串格式无效时抛出 std::invalid_argument |
operator mc::string_view() |
隐式转换为 ISO 8601 字符串(thread_local 存储) |
不抛异常 |
operator std::string_view() |
隐式转换为 std::string_view(thread_local 存储) |
不抛异常 |
to_string() const |
格式化为 ISO 8601 字符串(thread_local 存储) |
不抛异常 |
to_iso_string() const |
同 to_string(),格式化为 ISO 8601 字符串 |
不抛异常 |
time_since_epoch() const |
返回自纪元以来的 milliseconds(const 引用) |
不抛异常 |
sec_since_epoch() const |
返回自纪元以来的秒数(uint32_t) |
不抛异常 |
template operator std::chrono::time_point<Clock, Duration>() |
转换为 std::chrono::time_point |
不抛异常 |
operator> operator>= operator< operator<= |
全序比较 |
不抛异常 |
operator== operator!= |
相等/不等比较 |
不抛异常 |
operator+=(const milliseconds&) operator-=(const milliseconds&) |
原地加减时长 |
不抛异常 |
operator+(const milliseconds&) operator-(const milliseconds&) |
时间点 ± 时长 → 新时间点 |
不抛异常 |
operator-(const time_point&) |
时间点 − 时间点 → milliseconds 时长 |
不抛异常 |
mc::time_point_sec
秒精度时间点类,内部以 uint32_t 存储自纪元以来的秒数,比 time_point 更轻量。
| 方法/运算符 |
描述 |
异常 |
constexpr time_point_sec() |
默认构造为零时刻 |
不抛异常 |
constexpr explicit time_point_sec(uint32_t seconds) |
从秒数构造 |
不抛异常 |
constexpr time_point_sec(const time_point& t) |
从 time_point 构造(截断到秒) |
不抛异常 |
template time_point_sec(const std::chrono::time_point<Clock, Duration>&) |
从 std::chrono::time_point 构造 |
不抛异常 |
static time_point_sec now() |
获取当前时间点(秒精度) |
不抛异常 |
static constexpr time_point_sec maximum() |
返回最大时间点(0xffffffff 秒) |
不抛异常 |
static constexpr time_point_sec min() |
返回最小时间点(零时刻) |
不抛异常 |
static time_point_sec from_iso_string(mc::string_view s) |
从 ISO 8601 字符串解析时间点 |
字符串格式无效时抛出 std::invalid_argument |
sec_since_epoch() const |
返回自纪元以来的秒数(uint32_t) |
不抛异常 |
operator time_point() |
转换为 time_point(毫秒精度) |
不抛异常 |
template operator std::chrono::time_point<Clock, Duration>() |
转换为 std::chrono::time_point |
不抛异常 |
operator mc::string_view() |
隐式转换为 ISO 8601 字符串(thread_local 存储) |
不抛异常 |
operator std::string_view() |
隐式转换为 std::string_view(thread_local 存储) |
不抛异常 |
to_string() const |
格式化为 ISO 8601 字符串(thread_local 存储) |
不抛异常 |
to_iso_string() const |
同 to_string(),格式化为 ISO 8601 字符串 |
不抛异常 |
operator=(const time_point&) |
从 time_point 赋值(截断到秒) |
不抛异常 |
operator> operator>= operator< operator<=(友元) |
全序比较 |
不抛异常 |
operator== operator!=(友元) |
相等/不等比较 |
不抛异常 |
operator+=(uint32_t) operator-=(uint32_t) |
原地加减秒数 |
不抛异常 |
operator+=(milliseconds) operator-=(milliseconds) |
原地加减毫秒时长(截断到秒) |
不抛异常 |
operator+(uint32_t) operator-(uint32_t) |
时间点 ± 秒数 → 新 time_point_sec |
不抛异常 |
operator+(const milliseconds&)(友元)operator-(const milliseconds&)(友元) |
时间点 ± 毫秒时长 → 新 time_point |
不抛异常 |
operator-(const time_point_sec&)(友元) |
时间点 − 时间点 → milliseconds 时长 |
不抛异常 |
variant 序列化
| 函数 |
描述 |
异常 |
to_variant(const milliseconds&, variant&) |
将 milliseconds 写入 variant |
不抛异常 |
from_variant(const variant&, milliseconds&) |
从 variant 读取 milliseconds |
variant 类型不匹配时抛出 std::bad_variant_access |
to_variant(const time_point&, variant&) |
将 time_point 写入 variant |
不抛异常 |
from_variant(const variant&, time_point&) |
从 variant 读取 time_point |
variant 类型不匹配时抛出 std::bad_variant_access |
to_variant(const time_point_sec&, variant&) |
将 time_point_sec 写入 variant |
不抛异常 |
from_variant(const variant&, time_point_sec&) |
从 variant 读取 time_point_sec |
variant 类型不匹配时抛出 std::bad_variant_access |
类型别名
| 别名 |
定义 |
描述 |
opt_time_point |
std::optional<time_point> |
可选时间点,用于表示可能不存在的时间值 |
最佳实践
✅ 使用 time_point_sec 存储不关心毫秒的时间戳
struct AuditEntry {
mc::time_point_sec timestamp;
mc::string user;
mc::string action;
};
AuditEntry entry;
entry.timestamp = mc::time_point_sec::now();
entry.user = "admin";
entry.action = "login";
✅ 复制字符串输出以避免悬空引用
mc::time_point now = mc::time_point::now();
std::string iso_str(now.to_iso_string().data(), now.to_iso_string().size());
std::string iso_str2(static_cast<std::string_view>(now));
store_persistent(iso_str);
❌ 不应该在时间比较中使用 count() 原始值
mc::milliseconds a = mc::seconds(5);
mc::milliseconds b = mc::seconds(3);
if (a.count() > b.count()) {
}
if (a > b) {
}
❌ 不应该忽略 from_iso_string 的异常
mc::time_point tp = mc::time_point::from_iso_string(user_input);
mc::time_point tp;
try {
tp = mc::time_point::from_iso_string(user_input);
} catch (const std::invalid_argument&) {
tp = mc::time_point::now();
wlog("无效的时间字符串: ${input}", ("input", user_input));
}
✅ 利用 constexpr 特性定义编译期常量
constexpr mc::milliseconds DEFAULT_TIMEOUT = mc::seconds(30);
constexpr mc::milliseconds RETRY_INTERVAL = mc::minutes(5);
constexpr mc::milliseconds MAX_WAIT = mc::hours(2);
void connect()
{
wait_for(DEFAULT_TIMEOUT);
}
❌ 不应该在循环内反复调用 now() 做高精度计时
for (auto& task : tasks) {
mc::time_point start = mc::time_point::now();
execute(task);
mc::milliseconds elapsed = mc::time_point::now() - start;
record(elapsed);
}
mc::time_point batch_start = mc::time_point::now();
for (auto& task : tasks) {
execute(task);
}
mc::milliseconds total = mc::time_point::now() - batch_start;