Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

  1. トップページ
  2. C言語辞典
  3. localtime() / gmtime() / mktime()

localtime() / gmtime() / mktime()

『time_t』型の時刻と『struct tm』構造体(年・月・日・時・分・秒などのフィールドに分解した形式)を相互変換する関数です。『<time.h>』に定義されています。

構文
// time_t をローカル時刻の struct tm に変換します(スレッドアンセーフ)。
// 戻り値: 内部の静的な struct tm へのポインタ(次の呼び出しで上書きされます)。
struct tm *localtime(const time_t *timer);

// time_t を UTC(協定世界時)の struct tm に変換します(スレッドアンセーフ)。
// 戻り値: 内部の静的な struct tm へのポインタ。
struct tm *gmtime(const time_t *timer);

// struct tm を time_t に変換します(localtime の逆操作)。
// 戻り値: 成功時は time_t 値、エラー時は (time_t)(-1)。
time_t mktime(struct tm *tm);
struct tm のメンバ一覧
メンバ意味値の範囲
tm_year年(1900 を引いた値)例: 2024年 → 124
tm_mon月(0から始まります)0〜11(0 = 1月)
tm_mday1〜31
tm_hour0〜23
tm_min0〜59
tm_sec0〜60(閏秒を含む)
tm_wday曜日(0 = 日曜日)0〜6
tm_yday年初からの日数0〜365
tm_isdst夏時間フラグ正: 夏時間、0: 標準時、負: 不明
サンプルコード
#include <stdio.h>
#include <time.h>

int main(void) {
    // 現在時刻を取得します。
    time_t now = time(NULL);

    // localtime でローカル時刻の struct tm に変換します。
    struct tm *local = localtime(&now);
    printf("ローカル時刻:\n");
    printf("  %04d年%02d月%02d日 %02d:%02d:%02d\n",
        local->tm_year + 1900, // tm_year は 1900 引いた値なので加算します。
        local->tm_mon + 1,     // tm_mon は 0始まりなので 1 加算します。
        local->tm_mday,
        local->tm_hour,
        local->tm_min,
        local->tm_sec);

    // 曜日を文字列で表示します。
    const char *weekdays[] = {"日", "月", "火", "水", "木", "金", "土"};
    printf("  曜日: %s曜日\n", weekdays[local->tm_wday]);
    printf("  年初からの経過日数: %d 日目\n", local->tm_yday + 1);

    // gmtime で UTC 時刻を取得します(日本時間との差が 9 時間あります)。
    struct tm *utc = gmtime(&now);
    printf("UTC時刻: %02d:%02d:%02d\n", utc->tm_hour, utc->tm_min, utc->tm_sec);

    // mktime で特定の日時を time_t に変換します。
    struct tm target = {0}; // すべてのメンバをゼロ初期化します。
    target.tm_year = 2024 - 1900; // 2024年
    target.tm_mon  = 0;           // 1月(0始まり)
    target.tm_mday = 1;           // 1日
    target.tm_hour = 0;
    target.tm_min  = 0;
    target.tm_sec  = 0;
    time_t new_year = mktime(&target);
    printf("2024年元旦のタイムスタンプ: %ld\n", (long)new_year);

    return 0;
}
概要

『struct tm』の『tm_year』は 1900 を引いた値、『tm_mon』は 0 始まりという点が誤りやすいポイントです。年を表示するには『tm_year + 1900』、月を表示するには『tm_mon + 1』と補正する必要があります。

localtime() と gmtime() はスレッドアンセーフです。内部の静的な領域を返すため、複数のスレッドから同時に呼び出すとデータが競合します。マルチスレッド環境では POSIX 拡張の localtime_r() / gmtime_r()(またはWindows の localtime_s())を使用してください。

『mktime()』は不正な値(tm_mday = 32 など)を自動的に正規化します。例えば 1月32日は 2月1日に補正されます。この機能を利用して日付の加算処理ができます。また、mktime() は tm_wday(曜日)と tm_yday(年初からの日数)も自動計算して書き込みます。

時刻を文字列に変換するには『strftime() / asctime() / ctime()』を使用してください。time_t の取得については『time() / difftime() / clock()』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。