You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

咨询: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):

  1. local1代表本地时间的2020-01-30 00:00:00
  2. local1.timestamp()生成的是2020-01-30 00:00:00当作UTC时间对应的时间戳,而不是把本地时间转成UTC后的2020-01-29 16:00:00的时间戳
  3. local2 = timestamp时,会把这个错误的UTC时间戳转成本地时间,也就是2020-01-30 08:00:00(东八区加8小时)
  4. 自然local1local2不相等,断言触发

正确的转换方式

要实现LocalDateTimeTimestamp的双向一致转换,必须手动引入时区处理,用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

火山引擎 最新活动