C初級:日付と時刻を取得する

C言語初級カテゴリのロゴ画像 C言語初級

C言語では、お使いの端末(コンピュータなど)で設定されている現在時刻を取得できます。
日付や曜日、時刻などが取得できるとより実用的なプログラムに利用できます。

とりあえず日付と時刻を表示してみる

まずは簡単なプログラムで今日の日時を取り出してみます。

時刻の取得に関しての基本
時刻表示はtime_t型(中身はunsigned long型)の変数とstruct tm構造体を使って取得できます。
そのままの時刻を取り出すとグリニッジ標準時となってしまう為、localtime関数を使って現地時刻に変換します。
具体的に言うと、日本の場合グリニッジ標準時に+9時間したものが現地時間となります。これをlocaltime関数がやってくれます。

time_t型、tm構造体、localtime関数を利用するには、time.hをインクルードします。

サンプルプログラム:localtime.c

/* localtime.c: 今日の日時を表示する */
#include <stdio.h>
#include <time.h>

int main(void)
{
	time_t timer;		/* 時刻を取り出すための型(実際はunsigned long型) */
	struct tm *local;	/* tm構造体(時刻を扱う */

	/* 年月日と時分秒保存用 */
	int year, month, day, hour, minute, second;
	
	timer = time(NULL);		/* 現在時刻を取得 */
	local = localtime(&timer);	/* 地方時に変換 */

	/* 年月日と時分秒をtm構造体の各パラメタから変数に代入 */
	year = local->tm_year + 1900;		/* 1900年からの年数が取得されるため */
	month = local->tm_mon + 1;		/* 0を1月としているため */
	day = local->tm_mday;
	hour = local->tm_hour;
	minute = local->tm_min;
	second = local->tm_sec;

	/* 現在の日時を表示 */
	printf("%d年%d月%d日 %d時%d分%d秒です\n", year, month, day, hour, minute, second);
	
	return 0;
}

実行イメージ

2018年11月5日 9時46分9秒です

解説
まずは、エポック秒と呼ばれる世界標準時の1970年1月1日の0時0分0秒から何秒経過しているかの時間を取り出します。
以下の部分です。

time_t timer; /* 時刻を取り出すための型(実際はunsigned long型) */
timer = time(NULL); /* 現在時刻を取得 */

エポック秒とは – はてなキーワード

変数timerには、前述の1970年1月1日の0時0分0秒からの経過秒数が保存されます。ただ、このままだと世界標準時のため、現地時刻に直す必要があります。そのためにはlocaltime関数を利用します。

local = localtime(&timer); /* 地方時に変換 */

経過秒数を年月日や時分秒として取り出してくれる便利な構造体がtm構造体です。
サンプルでは、西暦、月、日、時、分、秒を取り出して表示しています。

西暦と月は注意が必要です。
西暦は、1900年から何年経過したかが戻り値となるため1900を足しています。
月は1月~12月を0~11の戻り値で表現するため、+1しています。

year = local->tm_year + 1900;
month = local->tm_mon + 1;

1970年からの経過秒数を表示してみる

/* epoc.c : エポック秒を取り出す */
#include <stdio.h>
#include <time.h>

int main(void)
{
	/* 時刻を取り出すための型(実際はunsigned long型) */
	time_t timer;
	
	/* 現在時刻を取得 */
	timer = time(NULL);
	
	/* 1970/1/1 00:00:00からの経過秒数(=エポック秒)を表示 */
	printf("%d秒\n", timer);

	return 0;
}

実行イメージ

1541389547秒

時刻取得に便利なtm構造体

tm構造体は、time.hで定義されている構造体です。
わたしが使っているBorlandのC/C++コンパイラ(bcc32.exe)では、以下のように定義されていました。

tm構造体(time.hよりそのまま抜粋)

struct tm
{
  int   tm_sec;
  int   tm_min;
  int   tm_hour;
  int   tm_mday;
  int   tm_mon;
  int   tm_year;
  int   tm_wday;
  int   tm_yday;
  int   tm_isdst;
};

きちんと解説すると以下の通りです。

メンバ名 取得できる値 説明
tm_sec 0-61
最大2秒までのうるう秒を考慮してある為、60と61まである。
利用する環境により範囲が0-60と0-61までが存在する。
tm_min 0-59
tm_hour 0-23 時、24時間表記
tm_mday 1-31
tm_mon 0-11 1月からの月数。使用するときは+1する
tm_year 0- 1900年からの経過年数
tm_wday 0-6 日曜日を0として土曜日の6まで
tm_yday 0-365 1月1日からの経過日数
tm_isdst 正数、0、負数 夏時間(サマータイム)フラグ
正:夏時間を採用している、0:夏時間を不採用、負:夏時間情報が得られない

次にtm構造体のメンバを全て表示してみます。

tm構造体のメンバ全てを表示してみる

xGetLocalTime.c

/* xGetLocalTime.c : tm構造体のメンバ全てを表示する */
#include <stdio.h>
#include <time.h>

int main(void)
{
	time_t timer;
	struct tm *t;
	int year, month, day, hour, minute, second, wday;

	/* wdayの値を使って文字列にする */
	char weekday[][3] = {"日", "月", "火", "水", "木", "金", "土"};

	/* 現在時刻を取得 */
	time(&timer);

	/* 現在時刻を構造体に変換 */
	t = localtime(&timer);
	
	/* tm構造体の全ての要素を表示してみる */
	printf("tm構造体\n------------------------\n");
	printf("%5d /秒\n",t->tm_sec);
	printf("%5d /分\n",t->tm_min);
	printf("%5d /時\n",t->tm_hour);
	printf("%5d /日\n",t->tm_mday);
	printf("%5d /月\n",t->tm_mon);
	printf("%5d /西暦年\n",t->tm_year);
	printf("%5d /曜日\n",t->tm_wday);
	printf("%5d /経過日数\n",t->tm_yday);
	printf("%5d /サマータイムフラグ\n",t->tm_isdst);

	/* 現在日時を表示 */
	year = t->tm_year + 1900;
	month = t->tm_mon + 1;
	day = t->tm_mday;
	
	hour = t->tm_hour;
	minute = t->tm_min;
	second = t->tm_sec;
	
	wday = t->tm_wday;

	printf("\n%04d/%02d/%02d(%s) at %02d:%02d:%02d\n",
				year, month, day, weekday[wday], hour, minute, second);

	return 0;
}

実行イメージ

tm構造体
————————
29 /秒
43 /分
12 /時
5 /日
10 /月
118 /西暦年
1 /曜日
308 /経過日数
0 /サマータイムフラグ

2018/11/05(月) at 12:43:29

コメント

タイトルとURLをコピーしました