怠日記

写真・金魚・昆虫・プログラミングの趣味を語るサイトです。似たようなことをnoteにも書いたり書いてなかったり。

C言語: 現在の日時を取得する(1) | gettimeofday(), localtime()

C言語で現在の日時を取得するには次のようにする。

  1. gettimeofday() でUNIX時間を取得
  2. UNIX時間を localtime() で tm 構造体に変換

次のプログラムは現在の日時を yyyy/MM/dd HH:mm:ss.fff 形式で出力する。

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

void main() {
    /* UNIX時間を取得 */
    struct timeval tv;
    if ( gettimeofday(&tv, NULL) != 0 ) {
        printf("gettimeofday failed\n");
        return;
    }

    /*
     * NOTE: MinGW 環境は tv_sec が long なので time_t にキャスト
     * struct tm *tmptr = localtime(&tv.tv_sec);
     */
    /* UNIX時間を tm 構造体に変換 */
    time_t currentTime = (time_t)tv.tv_sec;
    struct tm *tmptr = localtime(&currentTime);
    if (tmptr == NULL) {
        printf("localtime failed\n");
        return;
    }

    /* tm 構造体の内容を出力(yyyy/MM/dd HH:mm:ss.fff 形式) */
    printf("%04d/%02d/%02d %02d:%02d:%02d.%03d\n",
           tmptr->tm_year + 1900,
           tmptr->tm_mon + 1,
           tmptr->tm_mday,
           tmptr->tm_hour,
           tmptr->tm_min,
           tmptr->tm_sec,
           (int)(tv.tv_usec / 1000L));
}

gettimeofday()

gettimeofday() は、UNIX時間(1900年1月1日午前0時0分0秒(UTC))からの経過秒を取得する。

#include <sys/time.h>

int gettimeofday(struct timeval *tv, struct timezone *tz);

取得した時刻は、第1引数の timeval 構造体に格納される。

struct timeval {
    time_t      tv_sec;     /* 秒(UNIX時間) */
    suseconds_t tv_usec;    /* マイクロ秒 */
};

第2引数は廃止(obsolete)されている。
そのため timezone 構造体の代わりに NULL を指定する。

/* 第2引数はNULL */
struct timeval tv;
gettimeofday(&tv, NULL);

例)次のプログラムはUNIX時間を出力する。

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

void main() {
    struct timeval tv;
    if ( gettimeofday(&tv, NULL) == 0 ) {
        /* 取得成功 */
        printf("seconds: %ld\n", tv.tv_sec);
        printf("microseconds: %ld\n", tv.tv_usec);
    } else {
        /* 取得失敗 */
        printf("gettimeofday failed\n");
    }
}

↓ 実行結果

seconds: 1696062600
microseconds: 435209

localtime()

UNIX時間を tm 構造体に変換する。

#include <time.h>

struct tm *localtime(const time_t *timep);

tm 構造体のメンバーは以下のとおり。

  • tm_sec 秒(0 - 59)
  • tm_min 分(0 - 59)
  • tm_hour 時(0 - 23)
  • tm_mday 日(1 - 31)
  • tm_mon 月(0 - 11、1月 = 0)
  • tm_year 年(実際の西暦から 1900 を引いた数)
  • tm_wday 曜日(0 - 6、日曜日 = 0)
  • tm_yday 年内の通算日(0 - 365、1月1日 = 0)
  • tm_isdst 夏時間が有効な場合は正の値。夏時間が有効でない場合は 0。夏時間の状態が不明な場合は負の値。