咨询:Poco::LocalDateTime::timestamp()未转换为UTC时间的异常问题
这绝对是违反直觉的异常行为,你完全不是一个人!
首先得明确Poco框架里这个设计的矛盾点:
- 根据
Poco::Timestamp的头文件定义,它本质是UTC时间戳,代表从UTC纪元开始的毫秒数 - 但
Poco::LocalDateTime::timestamp()的实现却完全没遵循这个规则——它直接把本地时间的日期时间值当作UTC时间来生成时间戳,根本没做本地时区到UTC的转换 - 反过来,
Poco::LocalDateTime::operator=(const Timestamp&)却会正确执行UTC时间戳到本地时间的转换,这就导致了双向转换的不对称,直接触发你代码里的断言失败
你的代码示例问题拆解
拿这段代码来说:
Poco::LocalDateTime local1 = Poco::LocalDateTime( 2020, 1, 30 ); Poco::Timestamp timestamp = local1.timestamp(); Poco::LocalDateTime local2 = timestamp; assert( local1 == local2 );
假设你在东八区(UTC+8):
local1代表本地时间的2020-01-30 00:00:00local1.timestamp()生成的是把2020-01-30 00:00:00当作UTC时间对应的时间戳,而不是把本地时间转成UTC后的2020-01-29 16:00:00的时间戳- 当
local2 = timestamp时,会把这个错误的UTC时间戳转成本地时间,也就是2020-01-30 08:00:00(东八区加8小时) - 自然
local1和local2不相等,断言触发
正确的转换方式
要实现LocalDateTime和Timestamp的双向一致转换,必须手动引入时区处理,用Poco::TimeZone来做正确的时区转换:
#include <Poco/LocalDateTime.h> #include <Poco/Timestamp.h> #include <Poco/TimeZone.h> #include <cassert> int main() { Poco::LocalDateTime local1(2020, 1, 30); Poco::TimeZone tz; // 获取当前系统时区 // 正确将LocalDateTime转换为UTC Timestamp Poco::Timestamp timestamp = tz.timestamp(local1); Poco::LocalDateTime local2 = timestamp; assert(local1 == local2); // 现在断言会成功 return 0; }
补充说明
这个设计确实是Poco框架的一个坑,文档没有明确强调LocalDateTime::timestamp()的行为和Timestamp的UTC定义不符,很容易让开发者误以为它会自动做时区转换。你可以去Poco的官方代码仓库查看是否有相关的issue,或者提交一个新的issue反馈这个不一致性。
内容的提问来源于stack exchange,提问作者Martin Arvidssson




