当前位置: 首页 > ops >正文

QDateTime修改时区导致时间戳不对的坑

结论:使用时间戳时,统一使用currentDateTimeUtc()或者currentMSecsSinceEpoch()获取时间戳,而不是currentDateTime()。

QDateTime部分函数源码:

QDateTime QDateTime::currentDateTime()
{QDate d;QTime t;SYSTEMTIME st;memset(&st, 0, sizeof(SYSTEMTIME));GetLocalTime(&st);d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);return QDateTime(d, t);
}QDateTime QDateTime::currentDateTimeUtc()
{QDate d;QTime t;SYSTEMTIME st;memset(&st, 0, sizeof(SYSTEMTIME));GetSystemTime(&st);d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);return QDateTime(d, t, Qt::UTC);
}qint64 QDateTime::currentMSecsSinceEpoch() Q_DECL_NOTHROW
{SYSTEMTIME st;memset(&st, 0, sizeof(SYSTEMTIME));GetSystemTime(&st);return msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds) +qint64(julianDayFromDate(st.wYear, st.wMonth, st.wDay)- julianDayFromDate(1970, 1, 1)) * Q_INT64_C(86400000);
}

通过QDateTime::currentDateTime()和QDateTime::currentDateTimeUtc()源码对比可以发现,在Windows下,currentDateTime()是调用GetLocalTime(&st),而currentDateTimeUtc()是调用GetSystemTime(&st),可能导致这两个函数拿到的时间戳是不一样,比如当前是UTC+8:00时区,如果你修改成UTC+10:00时区,可能会出现currentDateTime()的时间戳比currentDateTimeUtc()多了两个小时,而currentDateTimeUtc()的时间戳是对的;如果是UTC+8:00改成UTC+6:00,可能会出现currentDateTime()的时间戳比currentDateTimeUtc()少了两个小时。同理currentMSecsSinceEpoch()和currentDateTimeUtc是一样,所以QDateTime::currentDateTime().toMSecsSinceEpoch()和currentMSecsSinceEpoch()可能会出现QDateTime::currentDateTime()和QDateTime::currentDateTimeUtc()一样的问题。

例子:程序是定时跑如下代码,先开启程序,然后将时区从UTC+10:00改成UTC+8:00。会偶发出现下面的问题

auto dateTime1 = QDateTime::currentDateTime();
auto dateTime2 = QDateTime::currentDateTimeUtc();
qDebug()  << dateTime1 << dateTime1.toMSecsSinceEpoch()<< dateTime2 << dateTime2.toMSecsSinceEpoch()<< QDateTime::currentMSecsSinceEpoch();

打印:

QDateTime(2025-05-14 14:01:33.989 太平洋西部标准时间 Qt::LocalTime) 1747195293989 QDateTime(2025-05-14 06:01:33.989 UTC Qt::UTC) 1747202493989 1747202493989

结果说明: 从打印结果来看,字符串时间是对的,但QDateTime::currentDateTime().toMSecsSinceEpoch()时间戳是错的,时间戳比字符串时间对应的时间戳是慢两个小时的。

http://www.xdnf.cn/news/6032.html

相关文章:

  • MetaHipMer2:从头组装宏基因组
  • ElasticSearch深入解析(十二):聚合——分桶聚合、指标聚合、管道子聚合
  • 安全扫描之 Linux 杀毒软件 Clamav 安装
  • Django + Celery 打造企业级大模型异步任务管理平台 —— 从需求到完整实践(含全模板源码)
  • AI与机器学习深度集成:从设备端能力爆发到开发工具智能化
  • QML ComboBox部件的使用
  • spark分区器
  • 《Python星球日记》 第68天:BERT 与预训练模型
  • EasyRTC嵌入式音视频通信SDK打造带屏IPC全场景实时通信解决方案
  • GMT之Bash语言使用
  • idea挂掉,会导致进程不结束,切换profile环境,导致token认证不通过
  • Git的安装和配置(idea中配置Git)
  • Spring Boot 自动装配技术方案书
  • 【PostgreSQL数据分析实战:从数据清洗到可视化全流程】附录-C. 常用SQL脚本模板
  • LLaMA-Factory 微调 Qwen2-7B-Instruct
  • 数据的模型分析及可视化
  • docker-compose——安装redis
  • 什么是物联网 IoT 平台?
  • 三轴云台之控制算法协同技术篇
  • 【教程】Docker更换存储位置
  • 微信小程序智能商城系统(uniapp+Springboot后端+vue管理端)
  • 如何下载 MySQL 驱动 JAR 包
  • 详细说说Spring的IOC机制
  • Seata源码—1.Seata分布式事务的模式简介
  • Kotlin 协程实战:实现异步值加载委托,对值进行异步懒初始化
  • Flutter 与HarmonyOS Next 混合渲染开发实践:以 fluttertpc_scan 三方库为例
  • 进程信号的学习
  • 游戏盾SDK的防护介绍
  • NC65开发环境(eclipse启动)在企业报表中的报表数据中心里计算某张报表时,一直计算不出数据的解决办法。
  • 数字高程模型(DEM)公开数据集介绍与下载指南