使用date::floor从time_t转换日期时得到提前2天结果的原因咨询
我太懂你这种摸不着头脑的感觉了——明明选对了日期,用date::floor处理就平白少了两天,换ceil就正常,这事儿确实让人费解。咱们来一步步拆解问题根源:
核心矛盾:时区不匹配
wxWidgets的wxDateTime和wxDatePickerCtrl默认都是基于本地时间工作的,但time_t本质是从1970-01-01 UTC开始的秒数(UTC时间戳),std::chrono::system_clock也是基于UTC的,而date::floor<date::days>是对UTC时间点做向下取整,取到UTC当天的午夜0点。举个具体的例子,假设你在东八区(UTC+8):当你选中本地日期
2024-05-20,wxDateTime对应的是本地时间2024-05-20 00:00:00,转换成time_t后,对应的UTC时间是2024-05-19 16:00:00。这时候用date::floor取整,得到的是UTC的2024-05-19,对应本地日期就是2024-05-19——比你选中的日期少一天。你遇到的“少两天”情况,大概率是更极端的时区(比如UTC+14的基里巴斯线岛,或者夏令时叠加的特殊时区),导致本地时间和UTC的差超过12小时,再加上
wxDateTime的时间点转换细节,就出现了两天的偏差。为什么
date::ceil能得到正确结果?date::ceil<date::days>是向上取整到UTC下一天的午夜0点。还是用东八区的例子:UTC时间2024-05-19 16:00:00向上取整后是UTC2024-05-20 00:00:00,对应本地时间2024-05-20 08:00:00,刚好落在你选中的本地日期范围内,所以显示的日期和wx一致。
如果你想让date::floor得到和wx显示一致的本地日期,得把UTC时间转换成本地时区后再取整,借助date库的时区模块就能实现:
// 需要包含date/tz.h auto tp = std::chrono::system_clock::from_time_t(dateTicks); // 转换为本地时区的时间点 auto local_time = date::make_zoned(date::current_zone(), tp); // 对本地时间做floor取整 auto dateFloor = date::floor<date::days>(local_time.get_local_time());
备注:内容来源于stack exchange,提问作者segmentation_fault

