本文为原创作品,请尊重作者的劳动成果。转载必须保持文章完整性,并以超链接形式注明原始作者“ tingsking18 ”和 主站点 地址,方便其他朋友提问和指正。
QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数
QT源码解析(二)深入剖析QT元对象系统和信号槽机制
QT源码解析(三)深入剖析QT元对象系统和信号槽机制(续)
QT源码解析(四)剖析Qt的事件机制原理
QT源码解析(五)QLibrary跨平台调用动态库的实现
QT源码解析(六)Qt信号槽机制与事件机制的联系
QT源码解析(七)Qt创建窗体的过程
QT源码解析(八)Qt是如何处理windows消息的
QT源码解析(九)解析QDateTime
本篇主要侧重于通过分析一个问题来解析QDateTime的代码
问题提出:
前几天一个朋友问我一个QDateTime的问题:
QDateTime d = QDateTime::fromString("Mon,26 Apr 2010, 08:21:03","ddd,d MMM yyyy, hh:mm:ss");
这种格式返回的QDateTime总是null。
问题分析:
于是我亲自试验了一下,没错,果然是null
Q_ASSERT(d.isNull());
然后拿出Qt Assistant,自己对照QDateTime的format格式看了一下,format的字符串的确没有任何错误,那错误到底出在哪里呢?
于是开始调试跟踪,看看这个问题到底是出在什么地方。
第一个疑点出现在这里:
注意QLocale::system();这个地方。
然后继续跟踪发现第二个疑点:
看清楚了么?看不清楚没有关系,我已经圈出来了。
在QDateTimeParser::fromString函数中t是我们要解析的字符串,而val是一个1900-1-1的QDateTime值,看看他俩什么区别(就是上图圈出来的那两部分)?没错,一个是英文的,一个是中文的。
真相距离我们越来越近了,接下来继续跟踪。
findDay函数for循环这一部分的意思就是循环比较”星期一”到”星期日”和传入的字符串”星期几”这一部分是否相等,传入的字符串中”星期几”这一部分时”mon”,显然不会相等了。于是我们找到了错误的根源。
错误是找到了,但是我们该如何解决这个错误呢?
根据上面提到的两个疑点,我们判断可能跟QLocale有关。我的系统是简体中文版的winxp,系统缺省的defaultLocale语言就是chinese,国家就是china。
问题解决:
所以解决这个问题有两个办法:
1. 装个英文版的系统。上面的代码肯定可以正确执行。
2. 想办法修改QLocale,或者看看QLocale有没有提供相应的方法。
办法1显然是不好办了,那就只好寻找办法2了。
首先查找QLocale帮助,发现有一个setDefault()方法。我们设置了之后起作用么?
看看图1中的代码defaultLocale = QLocale::system();这里defaultLocale又被重置了,所以即使我们设置了也不会起作用的。
继续看帮助:发现QLocale有一个toDateTime方法:
QDateTime QLocale::toDateTime ( const QString & string, const QString & format ) const
没错,就是他了。
下面,我们构造一个语言是英文的QLocale,然后toDateTime就可以了。
QLocale lo(QLocale::C);
QDateTime d = lo.toDateTime("Mon,26 Apr 2010, 08:21:03","ddd,d MMM yyyy, hh:mm:ss");
Q_ASSERT(d.isValid());
总结:
1. QDateTime的format格式与QLocale无关,但是format的结果是与QLocale相关的。
2. QDateTime用的是系统的时区,所以在用utc的时候也要注意。
3. 以前用wx的时候好像也遇到过类似的问题,时间很久了,就忘记了,当时也没有总结,只是大体记得处理这种问题的过程。依稀记得好像delphi的某个控件也是要修改system中时间,日期的format格式的,具体怎么回事也想不起来了。