1

指定された時間より 24 時間少ないコードを作成しようとすると、mktime()一貫性のない出力が表示されます。これを次のように計算しcurrent_time(GMT) - 86400ます。これは正しい値を返すはずです。入力時間に基づいて計算するだけです。以前mktime()は時刻を変更して GMT 時刻を取得し、通常の計算を行っていました。以下にコードを含めました。

#include <stdio.h>
#include <time.h>

int main()
{
    time_t currentTime, tempTime;
    struct tm *localTime;

    time(&currentTime);
    //localTime = localtime(&currentTime);
    localTime = gmtime(&currentTime); //get the time in GMT as we are in PDT

    printf("Time %2d:%02d\n", (localTime->tm_hour)%24, localTime->tm_min);
    localTime->tm_hour = 19; // Set the time to 19:00 GMT
    localTime->tm_min = 0;
    localTime->tm_sec = 0;
    tempTime = mktime(localTime);
    //tempTime = mktime(localTime) - timezone;

    printf("Current time is %ld and day before time is %ld\n", currentTime, (currentTime - 86400));
    printf("Current timezone is %ld \n", timezone);

    printf("New time is %ld and day before time is %ld\n",tempTime, (tempTime - 86400));
}

しかし、出力を確認すると、 call の呼び出し後に間違った結果が返されていますmktime()。以下は、上記のプログラムの出力です。

$ ./a.out
Time 11:51
Current time is 1341229916 and day before time is 1341143516
New time is 1341284400 and day before time is 1341198000
$ ./print_gmt 1341229916
Mon Jul  2 11:51:56 2012
$ ./print_gmt 1341143516
Sun Jul  1 11:51:56 2012
$ ./print_gmt 1341284400
Tue Jul  3 03:00:00 2012
$ ./print_gmt 1341198000
Mon Jul  2 03:00:00 2012
$ date
Mon Jul  2 04:52:46 PDT 2012

ここで、タイムゾーンを減算する行 (time.h に存在) のコメントを外すと、出力は期待どおりになります。以下は、上記のプログラムのタイムゾーンの値です

$ ./a.out
. . .
Current timezone is 28800
. . .

mktime()では、マニュアルページではタイムゾーンの調整について言及されていないのに、なぜこのような一貫性のない動作があるのでしょうか。そのような変換を行う際に何か欠けているものはありますか?

前もって感謝します。

4

5 に答える 5

2

問題はここにあると思います:

The mktime() function shall convert the broken-down time, expressed as local time, in the structure pointed to by timeptr, into a time since the Epoch value...

言葉に注意してくださいlocal time。C標準には、次の説明にもそれらがありますmktime()

The mktime function converts the broken-down time, expressed as local time, in the structure pointed to by timeptr into a calendar time value with the same encoding as that of the values returned by the time function.

gmtime()一方、タイム ゾーンではなく GMT/UTC で時刻を生成します。

The gmtime() function shall convert the time in seconds since the Epoch pointed to by timer into a broken-down time, expressed as Coordinated Universal Time (UTC).

編集: 前の GMT/UTC 日の 19:00 だけが必要な場合は、次のようにします。

#include <stdio.h>
#include <time.h>

int main(void)
{
    time_t currentTime;
    struct tm *brokenDownTime;

    time(&currentTime);

    // get the time in GMT as we are in PDT
    brokenDownTime = gmtime(&currentTime);
    printf("Current Time (GMT): %2d:%02d\n"
           "  seconds since Epoch: %ld\n", 
           brokenDownTime->tm_hour,
           brokenDownTime->tm_min,
           (long)currentTime);

    // "Unwind" time to 0:00:00 (assuming time_t is an integer):
    currentTime /= 24 * (time_t)3600;
    currentTime *= 24 * (time_t)3600;

    brokenDownTime = gmtime(&currentTime);
    printf("Time at the beginning of the current GMT day: %2d:%02d\n"
           "  seconds since Epoch: %ld\n", 
           brokenDownTime->tm_hour,
           brokenDownTime->tm_min,
           (long)currentTime);

    // Add 19 hours:
    currentTime += 19 * (time_t)3600;

    brokenDownTime = gmtime(&currentTime);
    printf("Time at 19:00:00 of the current GMT day: %2d:%02d\n"
           "  seconds since Epoch: %ld\n", 
           brokenDownTime->tm_hour,
           brokenDownTime->tm_min,
           (long)currentTime);

    // Subtract 1 day:
    currentTime -= 24 * (time_t)3600;

    brokenDownTime = gmtime(&currentTime);
    printf("Time at 19:00:00 of the previous GMT day: %2d:%02d\n"
           "  seconds since Epoch: %ld\n", 
           brokenDownTime->tm_hour,
           brokenDownTime->tm_min,
           (long)currentTime);

    return 0;
}

出力:

Current Time (GMT): 13:23
  seconds since Epoch: 1341235429
Time at the beginning of the current GMT day:  0:00
  seconds since Epoch: 1341187200
Time at 19:00:00 of the current GMT day: 19:00
  seconds since Epoch: 1341255600
Time at 19:00:00 of the previous GMT day: 19:00
  seconds since Epoch: 1341169200
于 2012-07-02T12:35:01.710 に答える
1

mktime(3)現在のタイムゾーンを使用して変換を実行します。これは、標準でやや不可解に書かれています。

ローカル タイムゾーン情報は、mktime()呼び出されたかのように設定されますtzset()

于 2012-07-02T12:39:13.753 に答える
1

mktime 仕様では、その引数が「ローカル時間として表現される分解された時間」を表すと述べています。したがって、mktime に渡すものはすべて、GMT ではなく、現地時間でなければなりません。変数の名前にlocalTimelocalが含まれていますが、実際には から取得されたものgmtimeであるため、その結果はGMT の現在の時刻を表します。それをに渡すことmktimeは矛盾しています。

于 2012-07-02T12:44:13.860 に答える