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
相关产品推荐
相关产品推荐

