[更新]我正在尝试找到将 UTC 时间戳转换为不同时区的正确方法。
确切的问题:我的程序中有时间戳,并且它始终以 UTC 格式存储,所以很好。 但是,我必须能够根据用户偏好在不同的时区显示它们(实际上将它们写入文件(。
我正在研究 linux,但我想编写独立于 pateform 的代码。我不想使用提升库(我们已经在使用Qt,它没有提供与日期提升那么多的功能(。我想编写线程安全代码我想确定像美国/东部这样的时区来简化配置(这是由用户完成的,我不太有信心他们会正确使用EST,CET,CEST......等缩写(。
我已经在互联网上查找并找到了一些或多或少的工作代码,但是
- 大多数情况下,它使用 TZ env 变量,据说这是一种非线程安全的方法。
- 它使用时区的缩写(如EST,CET...(。
有人能告诉我一个好方法吗?
这是我现在拥有的(几天前在互联网上找到并修改为在此示例中使用我的Qt库(。此代码可能不是线程安全的。
新版本:仍然不是线程安全的,但它或多或少可以完成工作。可能不容易移植到窗口环境。
它处理日光变化参见下面的例子(巴黎的日光变化发生在2012年3月25日01H00 UTC(从当地时间02H00到当地时间03H00(。这是一个将时间戳从UTC转换为巴黎(有日光变化(和Kuala_Lumpur(没有日光变化(的例子。
#include <QtCore/QCoreApplication>
#include <QDateTime>
#include <stdio.h>
#include <stdlib.h>
#include <QDebug>
void treatTimestamp(QString timestamp,QString format);
int main(int argc, char *argv[])
{
QString format = "MM:dd:yyyy hh:mm:ss";
treatTimestamp("03:25:2012 00:59:59",format);
qDebug()<<"---------------------";
treatTimestamp("03:25:2012 01:00:00",format);
return 0;
}
void treatTimestamp(QString timestamp_s,QString format)
{
unsetenv("TZ");
setenv("TZ", "UTC", 1);
QDateTime timestamp = QDateTime::fromString(timestamp_s, format);
qDebug()<<"CUSTOM TS UTC:"<<timestamp.toUTC().toString(format).toStdString().c_str();;
time_t tmp = timestamp.toUTC().toTime_t();
setenv("TZ", ":Asia/Kuala_Lumpur", 1);
qDebug()<<"CUSTOM TS KL:"<<QDateTime::fromTime_t(tmp).toString(format);
setenv("TZ", "Europe/Paris", 1);
qDebug()<<"CUSTOM TS Paris:"<<QDateTime::fromTime_t(tmp).toString(format);
unsetenv("TZ");
}
输出(第一个:时间变化前一秒,第二个:后一秒(。
自定义 TS LOC:03:25:2012 01:00:00
自定义 TS UTC:03:25:2012 01:00:00
自定义 TS KL:"03:25:2012 09:00:00"
定制 TS 巴黎:"03:25:2012 03:00:00"
自定义 TS LOC:03:
25:2012 03:00:00
自定义 TS UTC:03:25:2012 03:00:00
自定义 TS KL:"03:25:2012 11:00:00"
定制 TS 巴黎:"03:25:2012 05:00:00"
根据这个线程,使用 QDateTime 可以做dateTime.addSecs(3600*timeZoneOffset);
其中 dateTime 是 QDateTime。
根据 gmtime 参考,C 库中没有内置的时区支持,但您可以通过向 tm->tm_hour
添加需要偏移来"有点"模拟它们。顺便说一下,这不会正确调整日期(与QDateTime方法不同(。
根据 mktime 参考,mktime 将"规范化"日期时间值,因此您可以将时间偏移量添加到tm_hour,调用 mktime。但是,没有指定 mktime 如何调整结构 tm 的文件 - 如果您说,将tm_hour设置为 27,它会将tm_hour钳制为 23 还是将tm_hour设置为 3,增加tm_day(可能还有月/年(?
如果我是你,我会简单地使用QDateTime::addSecs
方法。
我给SigTerm+1,因为他的回答是建设性的。最后,我与用户验证一个正在运行的进程只需要 2 个时区:一个指定的时区和 UTC 时区(主要用于日志记录(。所以最后我在程序的顶部使用它 unsetenv("TZ"(; setenv("TZ", ", 1(;
然后在我需要UTC时间的特定部分,我总是调用Qt toUTC方法。这真的不令人满意,但完整的软件是关于数据采集的,时间戳是其中的重要组成部分,所以我不想在代码中进行自己的计算。我听说Qt5将实现类似于boost库中存在的时区操作。也许在代码出来时会重构代码。