time.h

時間_t

time_t は、時刻を表す型のエイリアスであり、国際標準時刻 UTC と見なすことができます。 Unix システムでは通常、浮動小数点数または整数が使用されます。

多くのシステムでは、time_t はタイム エポックからの秒数を表します。 Unix 時間エポックは、1970 年 1 月 1 日 UTC の 0 分 0 秒です。 time_t 負の場合、タイム エポックより前の時間を表します。

time_t は通常、現在のシステムに応じて 32 ビットまたは 64 ビットの整数型のエイリアスです。 32 ビットの符号付き整数の場合、time_t は 2038 年 1 月 19 日 03:14:07 UTC までの時間を表すことができ、32 ビットの符号なし整数の場合は、2106 年までの時間を表すことができます。 64 ビットの符号付き整数の場合、「-2,930 億年」から「+2,930 億年」までの時間範囲を表すことができます。

構造体 tm

struct tm は、時間、分、秒、日、月、年など、時間のさまざまな要素を保存するために使用されるデータ構造です。以下にその構造を示します。

構造体 tm {
  int tm_sec; // 秒 [0, 60]
  int tm_min; // 分 [0, 59]
  int tm_hour; // 時間 [0, 23]
  int tm_mday // 月の日数 [1, 31]
  int tm_mon; // 月 [0, 11]、1 月は 0 で表されます。
  int tm_year; // 1900 年からの年数
  int tm_wday; // 曜日 [0, 6]、日曜日は 0 で表されます。
  int tm_yday; // 1 月 1 日からの日数 [0, 365]
  int tm_isdst; // サマータイムを採用するかどうか、1 は採用、0 は採用しない
};

時間()

time() 関数は、時刻から経過した秒数を返します。

time_t time(time_t* 戻り値);

time() はパラメータとして time_t ポインタを受け取り、戻り値はポインタのアドレスに書き込まれます。パラメータにはヌルポインタ NULL を指定できます。

time() の戻り値は、time_t 型の現在時刻です。 コンピュータが現在の秒数を提供できない場合、または戻り値が time_t 型で表すには大きすぎる場合、time() 関数は -1 を返します。

今の時間。

//書き方その1
今 = 時間(NULL);

//書き方2
時間(&now);

上の例は、現在時刻を変数 now に書き込む 2 つの方法を示しています。

操作にかかる正確な時間を知りたい場合は、time() を 2 回呼び出して、2 つの戻り値を減算する必要があります。

time_t begin = time(NULL);

// ... 何かをする

time_t 終了 = 時間(NULL);

printf("%d\n", 終了 - 開始);

上記の方法は秒単位でしか正確ではないことに注意してください。

ctime()

ctime() は、time_t 型の値を人間が読める形式で直接出力するために使用されます。

char* ctime( time_t const * time_value);

ctime() のパラメータは time_t ポインタであり、文字列ポインタを返します。この文字列の形式は、「Sun Jul 4 04:02:48 1976\n\0」に似ており、末尾に改行文字と文字列終了フラグが付いています。

以下に例を示します。

今の時間。

今 = 時間(NULL);

// 出力 2021 年 2 月 28 日 (日) 18:47:25
printf("%s", ctime(&now));

ctime() は文字列の末尾に改行文字を自動的に追加することに注意してください。

localtime()、gmtime()

localtime() 関数は、time_t 型の時刻を現在のタイムゾーンの struct tm 構造体に変換するために使用されます。

gmtime() 関数は、time_t 型の時刻を UTC 時刻の struct tm 構造体に変換するために使用されます。

両者の違いは戻り値で、前者は現地時間、後者は UTC 時間です。

struct tm* localtime(const time_t* タイマー);
struct tm* gmtime(const time_t* タイマー);

以下に例を示します。

time_t now = time(NULL);

// ローカル出力: 2021 年 2 月 28 日 (日) 20:15:27
printf("ローカル: %s", asctime(localtime(&now)));

// 出力 UTC: 2021 年 3 月 1 日月曜日 04:15:27
printf("UTC : %s", asctime(gmtime(&now)));

asctime()

asctime() 関数は、struct tm 構造体を人間が読める形式で直接出力するために使用されます。この関数は、出力の末尾に改行文字を自動的に追加します。

使用例については、前のセクションを参照してください。

mktime()

mktime() 関数は、struct tm 構造体を time_t 値に変換するために使用されます。

time_t mktime(struct tm* tm_ptr);

mktime() のパラメータは struct tm ポインタです。

mktime() は struct tm 構造体の tm_wday 属性と tm_yday 属性を自動的に設定します。開発者はこれら 2 つの属性を自分で入力する必要はありません。したがって、この関数は、指定した時刻の曜日 (tm_wday) を取得するためによく使用されます。

struct tm 構造体の tm_isdst 属性を -1 に設定して、夏時間を採用するかどうかを mktime() に決定させることもできます。

以下に例を示します。

struct tm some_time = {
  .tm_year=82, // 1900 年からの年数
  .tm_mon=3, // 月 [0, 11]
  .tm_mday=12, // 日数 [1, 31]
  .tm_hour=12, // 時 [0, 23]
  .tm_min=00, // 分 [0, 59]
  .tm_sec=04, // 秒数 [0, 60]
  .tm_isdst=-1, // 夏時間
};
    
time_t some_time_epoch;
some_time_epoch = mktime(&some_time);
    
// 出力 1982 年 4 月 12 日月曜日 12:00:04
printf("%s", ctime(&some_time_epoch));

// 出力は DST: 0
printf("DST は %d\n", some_time.tm_isdst);

difftime()

difftime() は 2 つの時間の差を計算するために使用されます。 Unix システムでは、2 つの time_t 値を直接減算して差を秒単位で取得できますが、プログラムの移植性を考慮すると、この関数を使用するのが最善です。

double difftime( time_t time1, time_t time2 );

difftime() 関数は、time_t 型の 2 つの時間をパラメータとして受け取り、time1 - time2 の差を計算し、結果を秒に変換します。

その戻り値は double 型であることに注意してください。

#include <stdio.h>
#include <time.h>
    
int main(void) {
  struct tm time_a = {
    .tm_year=82、
    .tm_mon=3、
    .tm_mday=12、
    .tm_hour=4、
    .tm_min=00、
    .tm_sec=04、
    .tm_isdst=-1、
  };
    
  struct tm time_b = {
    .tm_year=120、
    .tm_mon=10、
    .tm_mday=15、
    .tm_hour=16、
    .tm_min=27、
    .tm_sec=00、
    .tm_isdst=-1、
  };
    
  time_t cal_a = mktime(&time_a);
  time_t cal_b = mktime(&time_b);
    
  double diff = difftime(cal_b, cal_a);
    
  2 年 = 差分 / 60 / 60 / 24 / 365.2425;
  
  // イベント間の出力 1217996816.000000 秒 (38.596783 年)
  printf("イベント間の%f 秒 (%f 年)\n", diff, years);
}

上記の例では、年を変換するときに、できる限り正確にするために、正確な 1 年の長さ 365.2425 日が使用されます。これにより、閏年の影響を相殺できます。

strftime()

strftime() 関数は、struct tm 構造体を指定された形式の文字列に変換し、指定されたアドレスにコピーするために使用されます。

size_t strftime(
  char*str、
  size_t 最大サイズ、
  const char* 形式、
  const struct tm* timeptr
)

strftime() は 4 つのパラメータを受け取ります。

  • 最初のパラメータ: ターゲット文字列へのポインタ。
  • 2 番目のパラメータ: ターゲット文字列が受け入れることができる最大長。
  • 3 番目のパラメータ: フォーマット文字列。
  • 4 番目のパラメータ: struct tm 構造体。

実行 (変換とコピー) が成功した場合、strftime() 関数はコピーされた文字列の長さを返します。実行が失敗した場合、-1 を返します。

以下に例を示します。

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

int main(void) {
  文字 s[128];
  time_t now = time(NULL);

  // %c: 現地時間
  strftime(s, sizeof s, "%c", localtime(&now));
  put(s); // 2021 年 2 月 28 日 (日) 22:29:00

  // %A: 曜日の完全な名前
  // %B: 完全な月名
  // %d: 月の日数
  strftime(s, sizeof s, "%A, %B %d", localtime(&now));
  put(s); // 2 月 28 日日曜日

  // %I: 時間 (12 時間形式)
  // %M: 分
  // %S: 秒
  // %p: 午前または午後
  strftime(s, sizeof s, "%I:%M:%S %p です", localtime(&now));
  put(s); // 午後 10 時 29 分です

  // %F: ISO 8601 yyyy-mm-dd 形式
  // %T: ISO 8601 hh:mm:ss 形式
  // %z: ISO 8601 タイムゾーン
  strftime(s, sizeof s, "ISO 8601: %FT%T%z", localtime(&now));
  put(s); // ISO 8601: 2021-02-28T22:29:00-0800
}

以下は一般的に使用される形式のプレースホルダーです。

  • %%: %文字を出力します。
  • %a: 現地時間の曜日の短縮形。
  • %A: 現地時間での曜日の完全な形式。
  • %b: 現地時間で計算された月の省略形。
  • %B: 現地時間で計算された月の完全な形式。
  • %c: 日付と時刻。「%x %X」を使用します。
  • %d: 月の日数 (01 ~ 31)。
  • %H: 時間、24 時間形式 (00 ~ 23) を使用します。
  • %I: 時間、12 時間形式 (00-12) を使用します。
  • %J: 年間の日 (001 ~ 366)。
  • %m: 月番号 (01 ~ 12)。
  • %M: 分(00~59)。
  • %P: 午前または午後。
  • %R: 「%H:%M」と同等。
  • %S: 秒 (00 ~ 61)。
  • %U: 日曜日を初日とする年間の週 (00 ~ 53)。
  • %w: 曜日。日曜日は 0 日目です。
  • %W: 月曜日を初日とする年間の週 (00 ~ 53)。
  • %x: 現地時間で計算された完全な年、月、日の日付。
  • %X: 現地時間で計算された、時間、分、秒単位の完了時間。
  • %y: 2 桁の年 (00 ~ 99)。
  • %Y: 4 桁の年 (たとえば、1984)。
  • %Z: タイムゾーンの略称。

timespec_get()

timespec_get() は、現在時刻をタイムエポックからのナノ秒 (10 億分の 1 秒) に変換するために使用されます。

int timespec_get (struct timespec* ts, int Base);

timespec_get() は 2 つのパラメータを受け取ります。

最初のパラメータは struct timespec 構造体ポインタで、変換された時間情報を保存するために使用されます。 struct timespecの構造は以下の通りです。

構造体 timespec {
  time_t tv_sec; // 秒
  長い tv_nsec; // ナノ秒
};

2 番目のパラメータは、時間計算の開始点を示す整数です。標準では、マクロ TIME_UTC に指定できる値は 1 つだけであり、タイム エポックからの秒数を返します。

以下に例を示します。

構造体 timespec ts;
    
timespec_get(&ts, TIME_UTC);
    
// 1614581530秒、806325800秒
printf("%ld s, %ld ns\n", ts.tv_sec, ts.tv_nsec);
    
double float_time = ts.tv_sec + ts.tv_nsec/1000000000.0;

// エポックから 1614581530.806326 秒
printf("エポックから%f秒\n", float_time);

クロック()

クロック() 関数は、プログラム実行の開始からの現在の CPU クロック サイクルを返します。 1 クロック サイクルは CPU 周波数の逆数に等しくなります。たとえば、CPU 周波数が 1G Hz の場合、クロック信号は 1 秒間に 10^9 回変化する可能性があるため、各クロック サイクルは 10^-9 秒になります。 。

クロック_t クロック(void);

クロック() 関数は、プログラムの開始からの CPU クロック サイクル数を表す数値を返します。この値の型は Clock_t で、通常は long int 型です。

この値を秒に変換するには、定数 CLOCKS_PER_SEC (1 秒あたりのクロック サイクル数) で割る必要があります。この定数も time.h によって定義されます。

printf("CPU 時間: %f\n", Clock() / (double)CLOCKS_PER_SEC);

上記の例では、プログラムの実行開始からこの行までにかかった秒数を出力できます。

コンピュータが CPU 時間を提供できない場合、または戻り値が Clock_t 型で表すには大きすぎる場合、 Clock() 関数は -1 を返します。

操作にかかる正確な時間を知るには、 Clock() を 2 回呼び出して戻り値を減算します。

クロック_t スタート = クロック();

// ... 何かをする

クロック_t 終了 = クロック();

long double 秒 = (float)(end - start) / CLOCKS_PER_SEC;

参考リンク


作者: wangdoc

アドレス: https://wangdoc.com/

ライセンス: クリエイティブ・コモンズ 3.0