将UTC time_t转换为不同的时区C ++线程安全

时间:2012-04-30 09:13:29

标签: c++ timezone

[更新] 我试图找到正确的方法将UTC中的时间戳转换为不同的时区。

确切的问题:我的程序中有时间戳,并且它始终以UTC存储,所以很好。但是,我必须能够根据用户的喜好在不同的时区显示它们(实际上将它们写入文件)。

我正在使用linux,但我想编写与专利无关的代码。 我不想使用boost库(我们已经在使用Qt,它没有提供与日期提升一样多的功能)。 我想编写线程安全的代码 我想确定像美国/东方这样的时区来简化配置(它由用户完成,我不太相信他们会正确使用EST,CET,CEST等缩写。)

我已经在互联网上找到了一些或多或少的工作代码,但是

  • 大部分时间它使用 TZ env变量,据说这是一个非线程安全的方法。
  • 它使用时区缩写(如EST,CET ......)。

有人能指出我一个好方法吗?

这是我现在所拥有的(几天前在互联网上找到并修改为在此示例中使用我的Qt库)。 此代码可能不是线程安全的。

新版本: 仍然不是线程安全的但它或多或少地完成了这项工作。 可能不容易移植到窗户环境。

它处理日光变化 参见下面的例子(巴黎的日光变化发生在2012年2月25日的UTC时间01:00(从当地时间03H00当地时间02H00开始)。 这是将时间戳从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");
}

输出(第一次:时间变化前一秒,第二次:之后一秒)。

CUSTOM TS LOC:03:25:2012 01:00:00

CUSTOM TS UTC:03:25:2012 01:00:00

CUSTOM TS KL:“03:25:2012 09:00:00”

CUSTOM TS Paris:“03:25:2012 03:00:00”


CUSTOM TS LOC:03:25:2012 03:00:00

CUSTOM TS UTC:03:25:2012 03:00:00

CUSTOM TS KL:“03:25:2012 11:00:00”

CUSTOM TS Paris:“03:25:2012 05:00:00”

2 个答案:

答案 0 :(得分:1)

根据this thread,使用QDateTime可以执行dateTime.addSecs(3600*timeZoneOffset);,其中dateTime是QDateTime。

根据gmtime reference,C库中没有内置的时区支持,但您可以通过向tm->tm_hour添加要求偏移来“有点”模拟它们。顺便说一句,这不会正确调整日期(与QDateTime方法不同)。

根据mktime参考,mktime将“规范化”日期时间值,因此您可以将时间偏移添加到tm_hour,调用mktime。但是,没有指定mktime如何调整struct tm的文件 - 如果你说,将tm_hour设置为27,它会将tm_hour钳位到23还是将tm_hour设置为3,增加tm_day(可能还有月/年)?

如果我是你,我只需使用QDateTime::addSecs方法。

答案 1 :(得分:0)

我给SigTerm +1,因为他的答案是有建设性的。 最后,我向用户验证一个正在运行的进程只需要2个时区:一个指定的时区和一个时区(主要用于日志记录)。 所以最后我在程序的顶部使用它     unsetenv( “TZ”);     setenv(“TZ”,“”,1);

然后在我需要UTC时间的特定部分,我总是调用Qt toUTC方法。 这真的不令人满意,但完整的软件是关于数据采集的,时间戳是它的一个重要部分,所以我不想在代码中进行自己的计算。 我听说Qt5将实现类似于boost库中存在的时区操作。可能会在代码出错时重构代码。