6

複数の相互通信システムで実行されるコードを書いています。time() を使用して time_t を取得していましたが、これがシステム間のタイム ゾーンの違いに問題を引き起こしていたため、GMT で time_t を取得したいと考えています。私は time.h 関数を調べてきましたが、時間を正しく取得できることをどのように確認できるかは不明です。これは私がこれまでに思いついたものです:

time_t t = time();
struct tm *gtm = gmtime(&t);
time_t gt = mktime(gtm);

今、これは私のマシンで正しい答えを得ているようですが、他のマシンの時計が現地時間またはGMTに設定されているか、別のタイムゾーンなどに設定されている場合でも、プッシュする前にそれが普遍的に機能するかどうかを知りたいです. . 私が心配している理由は、mktime のためです。説明では、tm 構造体を「現地時間で表された暦時間」として解釈すると述べています。私のマシンにはあるようですが、GMT時間を返さないように思えます。また、gt を印刷すると、t より 4 時間進んでいるように見えます。しかし、次を実行すると:

time_t t = time();
struct tm *gtm = gmtime(&t);
struct tm *ltm = localtime(&t);
printf("%d, %d\n", gtm->tm_hour, ltm->tm_hour);

時間は同じで現地時間ですが、これは私が期待したものではありません。

記録として、別の回答で timegm() への参照を見ました。これは完璧に聞こえますが、私のシステムには存在しません。

要するに、C の Windows マシンで GMT の time_t を取得するにはどうすればよいですか?

編集:msvcrtを使用していないため、追加されたmsvcrtタグを削除しました。

4

4 に答える 4

6

定義により、time_t は常に UTC です。したがって、 time() はあなたが望むことを行います。タイムゾーンは、time_t と分解された時間表現の間で変換する場合にのみ有効になります。

分解された時刻表現で UTC の時刻がある場合は、次のように、一時的にタイムゾーンを UTC に切り替え、mktime() を使用して time_t に変換し、タイムゾーンを元に戻す必要があります。

time_t convert_utc_tm_to_time_t (struct tm *tm)
{
    char *tz;
    time_t result;

    /* temporarily set timezone to UTC for conversion */
    tz = getenv("TZ");
    if (tz) {
      tz = strdup (tz);
      if (!tz) {
        // out of memory
        return -1;
      }
    }
    setenv("TZ", "", 1);
    tzset();

    tm->tm_isidst = 0;
    result = mktime (tm);

    /* restore timezone */
    if (tz) {
      setenv("TZ", tz, 1);
      free (tz);
    }
    else {
      unsetenv("TZ");
    }
    tzset();

    return result;
}
于 2012-08-02T21:11:34.850 に答える
2

GMT での時間の数値を必要に応じて使用gmtime()します。localtimeローカル タイム ゾーンで時刻を報告し、ローカル タイム ゾーンも GMT である場合にのみ GMT で報告します。

Windows には、時間とタイム ゾーンを処理するための独自のコードとデータ構造があります。Windows 固有の C コードを使用して GMT を取得するには、GetSystemTime(). 詳細については、次の URL を参照してください: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724390(v=vs.85).aspx

Windows は独自の日付/時刻構造を使用していることに注意してください。ただし、これについてはGetSystemTime()および関連ページでも詳しく説明されています。つまり、GetSystemTime()協定世界時 (UTC) (GMT とも呼ばれます) で表される現在のシステムの日付と時刻を取得します。これは、多くの時間要素を持つ構造である Windows 構造 SYSTEMTIME を使用します。

于 2012-08-02T21:06:04.093 に答える
0

Note that for such a trivial conversion, you can use your own function. There is a copy here of the mkgmtime()

https://github.com/m2osw/snapcpp/blob/master/snapwebsites/libsnapwebsites/src/snapwebsites/mkgmtime.c

This allows you to convert a struct tm to a time_t value ignoring any timezone information. Not including the comments, this is probably less than 100 lines of code, so very easy to add it to your project.

于 2014-12-02T08:24:03.777 に答える