30

コードをプラットフォーム/実装に依存しないようにしたい。time_tコードがコンパイルされているときに、プラットフォーム上でどのように実装されるかわかりません。t使用する書式指定子を決定するための型を知るにはどうすればよいですか?

...
time_t t = time(NULL);
printf("%s", t);
...
4

4 に答える 4

27

通常、キャストを使用して、オペランドを適切な形式がわかっている型に変換できます。

提案されたソリューション:

time_t t = time(NULL);
printf("%s", t);

は数値型であり、 ではないため、明らかに機能しません。time_tchar*

time_t一般に、これは算術型であることがわかっています。このようなもの:

 printf("%ld\n", (long)t);

ほとんどのシステムで動作する可能性があります。time_t(a)が unsigned 型でunsigned longあり、 の現在の値が をt超えているLONG_MAX場合、または (b)time_tが浮動小数点型である場合、失敗する可能性があります。

C99 をサポートしている場合long longは、少し優れた を使用できます。

printf("%lld\n", (long long)t);

移植性を本当に重視したい場合は、どのようなタイプtime_tであるかを検出できます。

if ((time_t)-1 > 0) {
    // time_t is an unsigned type
    printf("%ju\n", (uintmax_t)t);
}
else if ((time_t)1 / 2 > 0) {
    // time_t is a signed integer type
    printf("%jd\n", (intmax_t)t);
}
else {
    // time_t is a floating-point type (I've never seen this)
    printf("%Lg\n", (long double)t);
}

必要な出力形式に応じて、形式をやの%Lgように微調整したい場合があります。%Lf%.10Lf

繰り返しますが、これは C99 がサポートされていることを前提としてい#include <stdint.h>ます。uintmax_tintmax_t

time_tclock_tは少し変わっています。標準では、時間を表すことができる算術型であるとだけ述べられています。(原則として、それらは複雑な型である可能性がありますが、その可能性を無視することはリスクに値すると思います。)

他のほとんどの場合、特定の型が符号付き、符号なし、または浮動小数点のいずれであるかをおそらく知っており、その種類の最も広い型に変換できます。

time_tがどのように表されているのかわからない場合は、 printf( などの1379375215) の出力もおそらく理解できないことに注意してください。それを理解することが目的でない限りは。

(C ではなく C++ でプログラミングしている場合はstd::cout << t << "\n";、正しいオーバーロードされた が自動的に使用されますoperator<<。)

人間が読める出力 ( など) が必要な場合は、またはなど、 でMon 2013-09-16 16:46:55 PDT宣言されている変換関数のいずれかを使用する必要があります。<time.h>asctime()strftime()

于 2013-09-16T23:46:07.433 に答える
11

一般に、 a の値を表示する方法は、time_tそのコンポーネントをまたはをstruct tm使用して表示するか、 で必要に応じて変換するか、から直接現地時間を示す文字列に移動することです。gmtimelocaltimestrftimectimetime_t

何らかの目的で生の値を表示したい場合、C 標準では、これtime_trealであると指定されています。これは、整数または浮動小数点であることを意味します (C 2011 (N1570) 6.2.5 17)。doubleしたがって、それを変換して印刷できるはずです。time_t表現できない値を表現できる可能性があるdoubleため、エキゾチックな実装に注意したい場合は、それを防ぐ必要があるかもしれません。2 つのオブジェクトdifftimeの差を として返すため、Cはを超える精度で真にサポートしていないようです。time_tdoubletime_tdouble

于 2013-09-16T23:42:30.323 に答える
8

を使用difftime()して取得できdoubleます。

time_t t = time(NULL);
printf("seconds 1970->now: %.f\n", difftime(t, (time_t) 0));

シンプルで持ち運びやすいと思います。

于 2015-12-05T17:04:45.540 に答える
3

C標準はtime_t、「実数型」になると言っています(整数型または浮動小数点型を意味しますが、実際には常に整数型です)。

では、 orで分析time_tした後に でフォーマットするのが最善の策です— これは移植可能に行うことができます。strftime()localtime()gmtime()

移植性に欠けるため、正しい書式指定子を何らかのメカニズムで判断する必要があります。PRI_[Xxodi]_time非標準だが標準に近いものとしてandまたは類似のものを使用できますSCN_[Xxodi]_time(予約された名前空間を踏みにじることはありません。これは、PRIまたはSCNで始まり、その後に小文字またはXが続く名前です)。何らかのメカニズムを使用して、それを指定します...移植できない情報を1か所にカプセル化します。

于 2013-09-16T23:47:37.467 に答える