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

int main(int argc, char* argv[])
{
    struct tm stm;
    stm.tm_sec = 27;
    stm.tm_min = 5;
    stm.tm_hour = 18;
    stm.tm_mday = 2;
    stm.tm_mon = 0;
    stm.tm_year = 43;
    stm.tm_wday = 0;
    stm.tm_yday = 0;
    printf("%d\n", mktime(&stm));
    getchar();
    return 0;
}

-1を出力します

私は何を誤解していますか?

[+編集]これは、32ビットターゲットでVisualStudio2012を使用しています。フォローアップの質問は、「任意の日付/時刻値(つまり、1900年より前の値)を格納するための推奨される方法は何ですか?」

4

3 に答える 3

17

あなたの場合、43(1943)は無効な年と見なされます。その理由はmktime、型を返すためですtime_t。このタイプは実際には標準化されていません。ドキュメントの内容:

タイプは、time_t1970年1月1日UTCの00:00時間から経過した秒数を表す整数値です。そしてtm_yearは1900年からの年数です

このリンク最終的にはtime_ttypedefとは何ですか?言う:

time_tUnixエポックの開始からの秒数を表します:1970年1月1日のUTC午前0時(うるう秒はカウントされません)。一部のシステムは負の時間値を正しく処理しますが、他のシステムは処理しません

これが符号付き32ビット整数であると考える場合time_t、最良のシナリオでは、〜13/12/1901から19/1/2038までの日付を作成できます。

ただし、あなたの場合、実装はの負の部分を使用しないため、time_t1970年より前の日付を。で作成することはできませんmktime

于 2013-01-02T18:16:00.393 に答える
3

time_tはシステム上の64ビット整数であり、出力に間違ったフォーマットフラグ指定子を使用しています。ll修飾子を使用して、64ビットであることを示す必要があります。

time_t t = mktime(&stm);
printf("%lld", (int64_t)t);  // This will be correct if time_t is 32 or 64 bits

時刻はエポック(1970年1月1日)より前であるため、時刻は-851910873のような負の値になります。これは、64ビット整数として16進数で0xffffffffcd38df27です。32ビット整数として出力しようとすると、上位32ビット(0xffffffffまたは-1)が得られます(ただし、技術的には、これはC標準による未定義の動作であるため、これに依存しないでください)。

他の人が言っているように、の実際のサイズtime_tは指定されていないので、それについて何も仮定するべきではありません。最も安全な方法は、実際にその大きさを知る必要がある場合は、常に64ビットに拡張することです。

于 2013-01-02T18:38:07.803 に答える
0

あなたは「1943年1月2日」の日付を表現しようとしています。Unix / Linuxシステムでは、これらのシステムは「1970年1月1日」を参照日として使用するため
、この日付は値で表すことができません。time_t

更新:
POSIXは、mktimeが「エポックからの秒数」(エポック= 01-01-1970 00:00:00)で時間を返すことを指定しています。厳密に解釈すると、「秒から」は本質的に正の数であるため、1970年1月1日より前の日付を表すことはできません。

ANSI / ISO Cは、の結果が負の値になる可能性についてはあまり明確ではありませんmktime

于 2013-01-02T18:26:40.693 に答える