You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QDateTimeEdit时区显示错误求助(PySide2/QT5环境)

QDateTimeEdit无法正确显示指定时区(如Asia/Dubai)的标识

问题现象

在Python3/PySide2/QT5环境下使用QDateTimeEdit组件时,切换本地时间与UTC时间功能正常,但无法让组件显示指定时区(例如Asia/Dubai)的正确标识。测试代码执行后控制台能正确输出迪拜时间与时区+04,但组件显示的时间正确,时区却显示本地时区(如CEST)。

测试代码

#!/usr/bin/python3

import sys
import datetime
from PySide2 import QtWidgets, QtCore, QtGui

def main():
    app = QtWidgets.QApplication(sys.argv)
    dte = QtWidgets.QDateTimeEdit()
    timezone = QtCore.QTimeZone(b'Asia/Dubai')
    now = datetime.datetime.now()
    print("datetime local = {0}".format(now))
    now = QtCore.QDateTime(now)
    print("QDateTime local = {0}".format(now))
    now = now.toTimeZone(timezone)
    print("QDateTime Dubai = {0}".format(now))
    print("  time zone = {0}".format(now.timeZone()))
    print("  time spec = {0}".format(now.timeSpec()))
    print("  formated  = {0}".format(now.toString("dddd, MMMM d. yyyy hh:mm t")))
    dte.setDisplayFormat("dddd, MMMM d. yyyy hh:mm t")
    dte.setTimeSpec(QtCore.Qt.TimeZone)
    dte.setDateTime(now)
    dte.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

控制台输出

datetime local = 2023-08-23 10:51:40.678874
QDateTime local = PySide2.QtCore.QDateTime(2023, 8, 23, 10, 51, 40, 678, 0)
QDateTime Dubai = PySide2.QtCore.QDateTime(2023, 8, 23, 12, 51, 40, 678, 3)  
  time zone = <PySide2.QtCore.QTimeZone("Asia/Dubai") at 0x7fd415ccb300>
  time spec = PySide2.QtCore.Qt.TimeSpec.TimeZone
  formated  =  Wednesday, August 23. 2023 12:51 +04

问题分析

这不是PySide2的专属bug,在Qt的C++环境中也会复现。核心原因是:QDateTimeEdit调用setTimeSpec(Qt.TimeZone)时,并不会自动关联QDateTime对象携带的时区信息,而是默认使用系统本地时区渲染时区标识。组件能正确显示转换后的时间值,但时区部分被本地时区覆盖。

解决方案

方案1:手动设置格式化字符串(适合仅展示场景)

放弃组件的自动时区渲染,直接将已格式化好的带有时区的字符串设置为组件显示内容。注意此方式会失去时间编辑功能,仅适合展示需求:

# 替换原代码中dte的设置部分
formatted_str = now.toString("dddd, MMMM d. yyyy hh:mm t")
dte.setDisplayFormat("dddd, MMMM d. yyyy hh:mm t")
dte.setDateTime(now)
# 手动覆盖显示文本
dte.lineEdit().setText(formatted_str)

方案2:自定义QDateTimeEdit子类(支持编辑场景)

继承QDateTimeEdit,重写textFromDateTime方法,强制使用QDateTime自身的时区进行格式化,既能保留编辑功能,又能确保时区标识正确:

class CustomDateTimeEdit(QtWidgets.QDateTimeEdit):
    def textFromDateTime(self, dt: QtCore.QDateTime) -> str:
        # 使用传入的dt自身的时区进行格式化
        return dt.toString(self.displayFormat())

# 在main函数中替换dte的创建
dte = CustomDateTimeEdit()

C++环境验证

对应的C++测试代码如下,执行后同样会出现QDateTimeEdit显示本地时区的问题,验证这是Qt框架层面的行为,而非PySide2的绑定bug:

#include <QApplication>
#include <QDateTimeEdit>
#include <QTimeZone>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QDateTimeEdit dte;
    QTimeZone timezone("Asia/Dubai");
    QDateTime now = QDateTime::currentDateTime();
    qDebug() << "QDateTime local =" << now;
    now = now.toTimeZone(timezone);
    qDebug() << "QDateTime Dubai =" << now;
    qDebug() << "formated =" << now.toString("dddd, MMMM d. yyyy hh:mm t");
    
    dte.setDisplayFormat("dddd, MMMM d. yyyy hh:mm t");
    dte.setTimeSpec(Qt::TimeZone);
    dte.setDateTime(now);
    dte.show();
    return a.exec();
}

编译运行后,组件显示正确的迪拜时间,但时区标识为系统本地时区,与PySide2表现一致。

内容的提问来源于stack exchange,提问作者Goswin von Brederlow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 22:37:09