来自带有时区和夏令时的字符串的 Qt QDateTime

Posted

技术标签:

【中文标题】来自带有时区和夏令时的字符串的 Qt QDateTime【英文标题】:Qt QDateTime from string with timezone and daylight saving 【发布时间】:2019-08-17 15:13:30 【问题描述】:

我正在从字符串中插入时间

QDateTime time =QDateTime::fromString("Wed Mar 26 22:37:40 2019 GMT-08");
qDebug()<<time.toLocalTime().toString();
qDebug()<<time.toUTC().toString();
qDebug()<<time.isDaylightTime();

我得到的输出

“2019 年 3 月 26 日星期二 23:37:40” “格林威治标准时间 2019 年 3 月 27 日星期三 06:37:40” 假

应该给的

“2019 年 3 月 26 日星期二 23:37:40” “格林威治标准时间 2019 年 3 月 27 日星期三 05:37:40” 是的

如何通过时间戳字符串传递夏令时?

【问题讨论】:

【参考方案1】:

如果您查看官方文档,它会说:

如果 Qt::TimeSpec 不是 Qt::LocalTime 或 Qt::TimeZone 则将始终返回 false。

首先,检查QDateTime::timeSpec 是否返回了您期望的结果。

如果事先知道格式,请尝试使用等效函数QDateTime::fromString指定要解析的字符串的格式。

结合这两件事你可以做这样的事情:

const char* s = "2009-11-05T03:54:00";
QDateTime d = QDateTime::fromString(s, Qt::ISODate).toLocalTime();
d.setTimeSpec(Qt::LocalTime); // Just to ensure that the time spec are the proper one, i think is not needed
qDebug() << d.isDaylightTime();

【讨论】:

【参考方案2】:

首先,从“2019 年 3 月 26 日星期三 22:37:40 2019 GMT-08”计算得出的 UTC 时间“2019 年 3 月 27 日星期三 06:37:40 GMT”绝对正确。你觉得怎么可能是 5 点 37 分?

解释为什么 GMT 或 UTC 不包括 DST:

UTC 和 GMT 都不会改变夏令时 (DST)。 但是,一些使用 GMT 的国家/地区会切换到不同的时间 夏令时期间的区域。例如,AKDT(阿拉斯加日光 时间)是夏令时(夏令时)的 GMT-8 时区之一 节省时间)在 2019 年 3 月 10 日至 11 月 3 日之间。 冬季,正在使用 AKST(阿拉斯加标准时间),即 GMT-9。

第二,正如在其他回答时间QDateTime::isDaylightTime always returns false if the Qt::TimeSpec is not Qt::LocalTime or Qt::TimeZone 中已经指出的那样。

当您使用QDateTime::fromString 代码示例中的时区信息时,时间规范正确设置为Qt::OffsetFromUTC。您可以将另一个 QDateTime 对象实例化为同一时间,但 TimeSpec 为 Qt::LocalTime 或 Qt::TimeZone。你可以例如使用QDateTime::toLocalTime 转换为本地时间,或者使用QDateTime::fromSecsSinceEpoch 转换为Qt::LocalTime 或Qt::TimeZone,后者接受时区的偏移秒数。

请参阅下面的示例代码。我位于芬兰,夏令时从 3 月 31 日开始,因此您可以看到使用标准时间和使用夏令时时的当地时间差异:

QDateTime time = QDateTime::fromString("Wed Mar 26 22:37:40 2019 GMT-08");

qDebug()<<"\nLocal time EET:";
QDateTime localTime = time.toLocalTime();
// This works too, here to local time:
//QDateTime localTime = QDateTime::fromSecsSinceEpoch(time.toSecsSinceEpoch());
qDebug()<<localTime.timeSpec();
qDebug()<<localTime.timeZone();
qDebug()<<localTime.timeZoneAbbreviation();
qDebug()<<localTime.toLocalTime().toString();
qDebug()<<localTime.toUTC().toString();
qDebug()<<localTime.isDaylightTime();

time = QDateTime::fromString("Wed Apr 26 22:37:40 2019 GMT-08");

qDebug()<<"\nLocal time EEST:";
localTime = time.toLocalTime();
qDebug()<<localTime.timeSpec();
qDebug()<<localTime.timeZone();
qDebug()<<localTime.timeZoneAbbreviation();
qDebug()<<localTime.toLocalTime().toString();
qDebug()<<localTime.toUTC().toString();
qDebug()<<localTime.isDaylightTime();

输出:

Local time EET:
Qt::LocalTime
QTimeZone("Europe/Helsinki")
"EET"
"Wed Mar 27 08:37:40 2019"
"Wed Mar 27 06:37:40 2019 GMT"
false

Local time EEST:
Qt::LocalTime
QTimeZone("Europe/Helsinki")
"EEST"
"Sat Apr 27 09:37:40 2019"
"Sat Apr 27 06:37:40 2019 GMT"
true

【讨论】:

“2019 年 3 月 26 日星期三 22:37:40 GMT-08”包括夏令时,我还查看了谷歌显示的 5:37 我更新了我的答案,解释了 GMT 不包括夏令时。我以目前处于 GMT-8 的阿拉斯加为例。希望它澄清。

以上是关于来自带有时区和夏令时的字符串的 Qt QDateTime的主要内容,如果未能解决你的问题,请参考以下文章

时区转换和夏令时

PHP 处理夏令时的时区

将日期字符串解析为某个时区(支持夏令时)

来自第三方设备的时区

C# 英国夏令时 (BST) 时区缩写

在使用利用夏令时的 Python 时区时,应该传递啥 tzinfo?