C言語基礎|現在の日付と時刻の取得

「今この瞬間を、プログラムでつかまえる。time と localtime で“現在時刻”を表示しよう!」

プログラムを動かした“今”って、意外と大事なんです。
ログに残したり、処理の開始時刻を記録したり、ファイル名に日付を付けたり…「現在時刻が取れる」だけで、できることが一気に増えます。

C言語では、標準ライブラリの time と localtime を呼び出すだけで、現在の日時を取り出せます。
ただし、内部で扱う形式は人間向けではないので、まずは
「コンピュータ向けの暦時刻(time_t)」 → 「人間向けの要素別時刻(struct tm)」
という変換の流れを押さえるのがコツです。

まず全体像:暦時刻と要素別の時刻

2つの時刻表現

表現イメージ得意なこと
暦時刻(calendar time)time_t1つの数値(例:経過秒)計算・比較がしやすい
要素別の時刻(broken-down time)struct tm年/月/日/時/分/秒のまとまり表示・人間の理解がしやすい

表の説明

  • time_t は「今」を数値で表すので、差分計算などが得意です。
  • struct tm は「今」を部品(年/月/日…)に分けて持つので、表示に向いています。
  • 普段は time で time_t を得て、localtime で struct tm に変換して使います。

図でつかむ:時刻取得の基本フロー

図:time → localtime の流れ

time(NULL)
  ↓  現在の暦時刻(time_t)
localtime(&current)
  ↓  地方時の要素別時刻(struct tm*)
年・月・日・曜日・時・分・秒を取り出して表示

図の説明

  • time(NULL) は「現在の暦時刻」を返します。
  • localtime は「暦時刻」を「地方時の年/月/日…」に変換します。
  • 地方時というのは、その環境のタイムゾーン設定に基づく時刻です(日本設定なら日本時間)。

サンプルプログラム

英語で現在時刻を表示するプログラム例です。
よく使われる「YYYY-MM-DD HH:MM:SS」形式で表示します。

プロジェクト名:chap13-6-1 ソースファイル名:chap13-6-1.c

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

int main(void)
{
    /* 現在の暦時刻を取得する */
    time_t current = time(NULL);

    /* 暦時刻を地方時の要素別時刻に変換する */
    struct tm *t = localtime(¤t);

    /* 取得に失敗する可能性があるので軽くチェックする */
    if (t == NULL) {
        printf("ERROR: Failed to get local time.\n");
        return 1;
    }

    /* YYYY-MM-DD HH:MM:SS 形式で表示する */
    printf("Current local time is %04d-%02d-%02d %02d:%02d:%02d.\n",
           t->tm_year + 1900,   /* 年は1900年からの差なので補正する */
           t->tm_mon + 1,       /* 月は0始まりなので補正する */
           t->tm_mday,          /* 日 */
           t->tm_hour,          /* 時 */
           t->tm_min,           /* 分 */
           t->tm_sec            /* 秒 */
    );

    return 0;
}

time_t 型ってなに?

time_t は「暦時刻」を表す型です。実体は処理系依存ですが、多くの環境では「1970-01-01 00:00:00 からの経過秒数」に近い意味合いで使われています。

time_t の特徴

項目内容
役割現在時刻を“数値”で表す
実体unsigned long などの算術型になっていることが多い(処理系依存)
メリット時刻の差、比較、並び替えが簡単
デメリットそのままでは年/月/日が直感的に分からない

表の説明

  • time_t を直接 printf で表示しても「大きい数」が出るだけになりやすいです。
  • 人間向け表示には localtime(または gmtime)で struct tm にしてから出すのが定番です。

time 関数の書式と呼び方(A/B/C の整理)

time の書式

項目内容
ヘッダ#include <time.h>
形式time_t time(time_t *t);
動作現在の暦時刻を返す。引数が NULL でなければ *t にも格納する

代表的な3つの呼び出し方

呼び出し意味current に入る?
time(&current)返り値も *引数 も使える入る
current = time(NULL)返り値だけ使う(よく使う)入る
current = time(&current)どっちも同じ値を受け取る入る

表の説明

  • 一番スッキリしていてよく使われるのは current = time(NULL) です。
  • 「引数にも入れて返り値も返す」タイプの関数だと思うと納得しやすいです。

struct tm(要素別の時刻)を表で理解

struct tm は「年・月・日…」の部品箱です。定義の細部は処理系依存ですが、代表的なメンバは共通です。

よく使う struct tm のメンバ

メンバ意味範囲表示用の注意
tm_sec0〜60閏秒で60があり得る
tm_min0〜59そのまま
tm_hour0〜23そのまま
tm_mday1〜31そのまま
tm_mon月(1月からの月数)0〜11+1 が必要
tm_year年(1900からの年数)例:126+1900 が必要
tm_wday曜日(日〜土)0〜6文字列に変換すると便利
tm_yday元旦からの日数0〜365必要なら使う
tm_isdst夏時間フラグ正/0/負日本では通常0

表の説明

  • tm_year と tm_mon の補正は「定番のつまずきポイント」です。
  • 曜日が欲しいときは tm_wday を配列で文字列に変換すると楽です。

localtime の役割(暦時刻 → 地方時の要素別時刻)

localtime の書式

項目内容
ヘッダ#include <time.h>
形式struct tm *localtime(const time_t *timep);
動作timep の暦時刻を、地方時の struct tm に変換して返す

図:localtime の変換イメージ

暦時刻(time_t)
  current
    ↓ localtime(&current)
要素別の時刻(struct tm)
  tm_year / tm_mon / tm_mday / tm_wday / tm_hour / tm_min / tm_sec ...

図の説明

  • localtime は「その環境のタイムゾーン設定」に従った時刻に変換します。
  • 返り値は struct tm* で、そこから各メンバを取り出して表示します。

曜日表示をしたいとき(配列で変換する考え方)

元の文章にあった「wday_name 配列」は、tm_wday を文字列に変換する典型パターンです。

曜日変換の基本

tm_wday の値0123456
曜日SunMonTueWedThuFriSat

表の説明

  • tm_wday は 0 が日曜、6 が土曜です。
  • 配列を用意して wday_name[t->tm_wday] のように引けば簡単に文字列化できます。

まとめ:理解のポイントはこの3つ

  • time(NULL) で「今」を time_t として取る。
  • localtime(&current) で「今」を struct tm に分解する。
  • tm_year は +1900、tm_mon は +1 して表示する。

この型が身につくと、次に「ファイルへ時刻を書き込む」「ログを作る」がとてもスムーズに進みます。