4

strftime関数を使用して、現在の utc 時刻を文字列にエンコードしようとしています。

time_t now;
struct tm nowLocal;
struct tm nowUtc;

now = time(NULL);
localtime_r(&now, &nowLocal);
gmtime_r(&now, &nowUtc);

これまでのところnowLocal、私のタイムゾーン(CET)で現在の時刻が含まnowUtcれており、utc 時刻が含まれています。違いはtm_gmtoff値に正確に従っています。

nowLocal: {tm_sec = 28, tm_min = 27, tm_hour = 13, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8127a38 "CEST"}

nowUtc: {tm_sec = 28, tm_min = 27, tm_hour = 11, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 0, tm_gmtoff = 0, tm_zone = 0x3e9907 "GMT"}

次に、エポックからの秒数を取得するために formatstrftime()を呼び出します。"%s"

char tsFromLocal[32];
char tsFromUtc[32];

strftime(tsFromLocal, sizeof(tsFromLocal), "%s", &nowLocal);
strftime(tsFromUtc, sizeof(tsFromUtc), "%s", &nowUtc);

結果は私には奇妙に思えます。フォーマットは次のように記述されているため、両方のstrftime()呼び出しからまったく同じ文字列を取得することを期待していました。%s

エポックからの秒数、つまり since 1970-01-01 00:00:00 UTC。うるう秒のサポートが利用可能でない限り、うるう秒はカウントされません。

しかし、私は2つの異なる値を得ました:

tsFromLocal:"1337772448"

tsFromUtc: "1337768848"

しかもその差は7200 ( tm_gmtoff) ではなく3600です。誰もそのような行動を説明できますか? それともバグですか?

これを行っている理由は、時間の値をネットワーク経由で転送し、異なるタイム ゾーンにあるターゲット マシンの現在の時間と比較する必要があるためです。ターゲットマシンで私がしたかった:

struct tm restoredUtc;
time_t restored;

strptime(tsFromUtc, "%s", &restoredUtc);
restored = timegm(&restoredUtc);

しかし、私は得ました:

restoredUtc:{tm_sec = 28, tm_min = 27, tm_hour = 12, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8127a38 "CEST"}

とにかく、現在のタイムゾーンに従って をstrptime()設定します。tm_zoneしかし、timelocal()代わりに使用しても、 12:27:28 CESTではなく11:27:28 CESTtimegm()である必要があるため、正しい値が得られません。このエラーは の異なる結果に関連していますか?strftime()

この後半へのコメントはありますか?

4

3 に答える 3

2

gmtime_rどこでも常に同じ答えが得られることを考えると、全体で GMT を使用するのがおそらく最善です。個々のマシンが現地時間で表示したい場合は、後で行うことができますが、ストレージとネットワーク転送のために 1 つのタイムゾーンに固執することをお勧めします。GMT 値は簡単に取得できます。

于 2012-10-15T22:39:43.563 に答える
0

コメントは正しいと思いますstrftime()。時刻を現地時間として解釈しています。tm_gmtoffこれは標準化されたフィールドではないことに注意してください。見ているのかしらstrftime()。しかし、これを確認するための具体的なものは何も見つかりません。

ただし、質問の2番目の部分に答えてtime(NULL)、ネットワークを介して結果を直接転送してみませんか?または、すでに時間がある場合は、に変換してから転送 するためstruct tmに使用しますか?は、 C99またはPOSIXで標準化されていないを使用するよりもはるかに簡単です。mktime()time_tprintf("%lu", (unsigned long) time)strftime("%s")

于 2013-03-17T02:49:40.763 に答える
0

Q1: 誰かそのような振る舞いを説明できますか? それともバグですか?

はい、そのtsFromLocal:"1337772448"!=のバグですtsFromUtc: "1337768848"。しかし、バグはtsFromUtcにあります。それらは同じである必要があり、両方とも 1337772448 である必要があります。

1337772448%(24*60*60) --> 41248 は、1 日の UTC 秒または 11:27:28 であり、これnowUtcは構造に一致し、現在の時刻 (UTC) です。

Q2: ... このエラーは strftime() の異なる結果に関連していますか?

time_tネットワーク通信の整数として使用するという一般的な考え方には同意します。

はい、そう見えます。

nowこの投稿をさらに進めたい場合:直後の数値を投稿することを検討し、そのときのtime(&now)予想時間を明確に示してください。

于 2013-08-25T04:54:34.010 に答える