1

[更新]UTCのタイムスタンプを別のタイムゾーンに変換する正しい方法を見つけようとしています。

正確な問題:プログラムにタイムスタンプがあり、常にUTCで保存されているので問題ありません。ただし、ユーザーの好みに応じて、さまざまなタイムゾーンでそれらを表示(実際にはファイルに書き込む)できる必要があります。

Linuxで作業していますが、pateformに依存しないコードを記述したいと思います。Boostライブラリを使用したくありません(日付のBoostほど多くの機能を提供しないQtをすでに使用しています)。スレッドセーフなコードを記述したいUS/Easternのようなタイムゾーンを特定して、構成を簡素化します(これはユーザーによって行われ、EST、CET、CESTなどの略語を正しく使用することに自信がありません。 ...)。

私はすでにインターネットを調べて、多かれ少なかれ機能するコードを見つけましたが、

  • ほとんどの場合、スレッドセーフではないと言われているTZenv変数を使用します。
  • タイムゾーンの略語を使用します(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");
}

出力(最初:時間変更の1秒前、2番目:1秒後)。

カスタムTSLOC:03:25:2012 01:00:00

カスタムTSUTC:03:25:2012 01:00:00

カスタムTSKL: "03:25:2012 09:00:00"

カスタムTSパリ: "03:25:2012 03:00:00"


カスタムTSLOC:03:25:2012 03:00:00

カスタムTSUTC:03:25:2012 03:00:00

カスタムTSKL: "03:25:2012 11:00:00"

カスタムTSパリ: "03:25:2012 05:00:00"

4

2 に答える 2

1

このスレッドによると、QDateTimeを使用するとdateTime.addSecs(3600*timeZoneOffset);、dateTimeがQDateTimeである場合に実行できます。

gmtimeリファレンスによると、Cライブラリには組み込みのタイムゾーンサポートはありませんが、にrequired offsetを追加することで、それらを「ちょっと」シミュレートできますtm->tm_hour。ちなみに、これは(QDateTimeメソッドとは異なり)日付を正しく調整しません。

mktimeのリファレンスによると、mktimeは日時の値を「正規化」するため、tm_hourに時間オフセットを追加してmktimeを呼び出すことができます。ただし、mktimeがstruct tmのファイルをどのように調整するかは指定されていません-たとえば、tm_hourを27に設定すると、tm_hourを23にクランプするのでしょうか、それともtm_hourを3に設定するのでしょうか?

私があなたなら、私は単にQDateTime::addSecs方法を使うでしょう。

于 2012-04-30T10:22:59.780 に答える
0

彼の答えは建設的だったので、私はSigTermに+1を与えます。最後に、実行中の1つのプロセスに必要なタイムゾーンは2つだけであることをユーザーに確認します。指定されたタイムゾーンとUTCタイムゾーン(主にロギング用)です。したがって、最終的には、プログラムの先頭でこれを使用しますunsetenv( "TZ"); setenv( "TZ"、 ""、1);

次に、UTC時間が必要な特定の部分では、常にQttoUTCメソッドを呼び出します。それは本当に満足のいくものではありませんが、完全なソフトウェアはデータ取得に関するものであり、タイムスタンプはその重要な部分であるため、コードで独自の計算を行いたくありませんでした。Qt5には、Boostライブラリに存在するものと同様のタイムゾーン操作の実装があると聞きました。たぶん、コードがリリースされるときに、コードをリファクタリングするのは悪いことです。

于 2012-07-08T11:13:54.757 に答える