QT源码解析(九)解析QDateTime

 

版权声明

本文为原创作品,请尊重作者的劳动成果。转载必须保持文章完整性,并以超链接形式注明原始作者“ 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,自己对照QDateTimeformat格式看了一下,format的字符串的确没有任何错误,那错误到底出在哪里呢?

于是开始调试跟踪,看看这个问题到底是出在什么地方。

第一个疑点出现在这里:

 

注意QLocale::system();这个地方。

然后继续跟踪发现第二个疑点:

 

看清楚了么?看不清楚没有关系,我已经圈出来了。

QDateTimeParser::fromString函数中t是我们要解析的字符串,而val是一个1900-1-1QDateTime值,看看他俩什么区别(就是上图圈出来的那两部分)?没错,一个是英文的,一个是中文的。

真相距离我们越来越近了,接下来继续跟踪。

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.         QDateTimeformat格式与QLocale无关,但是format的结果是与QLocale相关的。

2.         QDateTime用的是系统的时区,所以在用utc的时候也要注意。

3.         以前用wx的时候好像也遇到过类似的问题,时间很久了,就忘记了,当时也没有总结,只是大体记得处理这种问题的过程。依稀记得好像delphi的某个控件也是要修改system中时间,日期的format格式的,具体怎么回事也想不起来了。

 

你可能感兴趣的:(QT)