web-dev-qa-db-ja.com

time_tのような実装定義型のフォーマット指定子

コードをプラットフォーム/実装に依存しないようにしたい。 time_tは、コードのコンパイル時にプラットフォームと同じように実装されます。 tのタイプを知って、どのフォーマット指定子を使用するかを決定するにはどうすればよいですか?

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

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

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

10

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

あなたが提案する解決策:

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

_time_t_は_char*_ではなく数値型であるため、明らかにnotは機能します。

一般的に、_time_t_は算術型であることを知っています。このようなもの:

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

ほとんどのシステムで動作する可能性があります。 (a)_time_t_が_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_t_を表示するには、_intmax_t_が必要です。

_time_t_と_clock_t_は、標準ではonlyが時間を表すことができる算術型であることを示しているため、少し変わっています。 (原則として、それらは複雑なタイプである可能性がありますが、その可能性を無視することはリスクに見合う価値があると私は言います。)

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

_time_t_の表現方法がわからない場合は、printf(_1379375215_など)の出力も理解できない可能性があります。それを理解してください。

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

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

24
Keith Thompson

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

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

シンプルで持ち運びに便利だと思います。

6
chus

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

_time_t_を使用する場合、strftime()またはlocaltime()を使用して分析した後、gmtime()を使用してフォーマットすることをお勧めします。これは、移植性のある方法で実行できます。

不運にも、正しいフォーマット指定子が何かであるメカニズムによって決定しなければなりません。 _PRI_[Xxodi]_time_および_SCN_[Xxodi]_time_または非標準であるが標準に近いもの(予約された名前空間を踏みにじることなく、PRIまたはSCNの後に小文字またはXが続きます。いくつかのメカニズムを使用して、移植できない情報を1か所にカプセル化することを指定します。

3