時間管理


時間関数

ある程度高度なシステムを組む場合、システムが持つ時間を利用する場合があります
たとえば、タイムスライシング(時間割り)プログラムなどに必要となります

時間関係の情報を要求する場合は time.h ヘッダファイルを用います
この関数はシステムから時間を得、またそれをカレンダーに置きかえるなどの作業をサポートします
現在のシステム時間を得るにはtime()関数を使用します

time_t time( time_t *timer );

ここで、新しい標準型のtime_tというのが出てきました
これは、time()関数などの値による時間値を表す型です

timerには、得られた時間を格納するポインタを指定します
戻り値も同じ値が得られ、返すべきエラーはありません
戻り値からも値が得られるので引数にNULLを指定することができます
#include <stdio.h>
#include <time.h>

int main() {
        time_t cl;
        time(&cl);
        printf("%d : %d" , cl , time(NULL));
        return 0;
}
time(&cl); というように、time_t型の変数に値を格納することも可能ですし
time(NULL)を指定して、戻り値だけを期待することもできます

ここで表示される時間は、万国標準時 (UCT)の1970年1月1日の00:00:00からの
経過時間を秒単位で表した数値です
ということは、983228400 というような、見た感じ時間とは思えない値が返されます

もしカレンダー値のような値を得たい場合は時間構造体を使用します
時間構造体はstruct tmでtime.hヘッダファイルに定義されています
通常は、time()関数で得られた値をlocaltime()関数で構造体に変換します

struct tm *localtime( const time_t *timer );

timerには、time_t型のポインタを渡します
この関数は、時間構造体のへのポインタを返します
ただし、timerの値が1970年1月1日午前0時0分以前を示している場合はNULLを返します

得られた時間構造体 tm のメンバから、現在の時刻をカレンダー値として得られます
時間構造体のメンバは、次のようになっています

tm_sec 秒(0 - 59)
tm_min 分(0 - 59)
tm_hour 時(0 - 23)
tm_mday 日(1 - 31)
tm_mon 月(0 - 11)
tm_year 年(現在の年から1900引いた値)
tm_wday 曜日(0 - 6)
tm_yday 通算日数(0 - 365)
tm_isdst 夏時間

月は1月を0としますので、表示させる場合は1を加算します
曜日は日曜日を0としています
夏時間は、有効な場合は0以外を、無効な場合は0を、不明の場合は負の値を返します
#include <stdio.h>
#include <time.h>

int main() {
        time_t timeValue;
        struct tm *timeObject;

        time(&timeValue);
        timeObject = localtime(&timeValue);

        printf("%d年 %d月 %d日 || %d : %d : %d" ,
                timeObject->tm_year + 1900 , timeObject->tm_mon + 1 ,
                timeObject->tm_mday , timeObject->tm_hour ,
                timeObject->tm_min , timeObject->tm_sec);

        return 0;
}
画面には、今年の年月日と実行された瞬間の時刻が表示されます
プロンプトではあまり良いことではありませんが、次のようにリアルタイム時計を作ることもできます

スレッドプログラム未経験の方にはよくわからないかもしれませんが
Windowsなどのマルチタスクプログラム環境下で無意味なループは厳禁です
しかし、この場ではとりあえずシングルタスクと考えて、次のようにループで時計を作ります

次のプログラムを実行すると無限ループが発生するので、付加がかかります
終了するにはCtrl + Cで強制終了してください
#include <stdio.h>
#include <time.h>

int main() {
	time_t timeValue , timeTmp;
	struct tm *timeObject;

	while (1) {
		if (time(&timeValue) != timeTmp) {
			timeObject = localtime(&timeValue);

			if (timeObject == NULL) {
				puts("システム時刻が正常に得られません");
				break;
			}

			printf("%2.2d : %2.2d : %2.2d\r" , timeObject->tm_hour ,
				timeObject->tm_min , timeObject->tm_sec);
		}
		timeTmp = timeValue;
	}
		
	return 0;
}
コンソールプログラムでは非常に珍しく、動的に更新しているでしょ
最初に時刻を得て、最後にチェック用変数 timeTmp に値を格納します
新しく時間を得るごとにtimeTmpと比較し、異なる場合は画面に出力します

このほかにも、何らかのプロセスの時間を計算したい場合があります
2つの異なる時刻の差を計算する場合はdifftime()関数が非常に便利です

double difftime( time_t timer1, time_t timer0 );

timer1に終了時間を、timer0に開始時間を指定します
この関数はtimer0からtimer1までの時間を秒単位の倍精度浮動小数点で返します

この関数を用いれば、何らかの処理時間を量ることができます
#include <stdio.h>
#include <time.h>

int main() {
	int i;
	double d;
	time_t timeValue[2];

	puts("演算中…");
	timeValue[0] = time( NULL );
	for (i = 0 ; i < 100000 ; i++) printf("%d\r" , i);
	timeValue[1] = time( NULL );

	printf("処理に %d 秒かかりました" , (int)difftime(timeValue[1] , timeValue[0]));
		
	return 0;
}
因みに、ループのprintf()関数の出力部分を浮動小数点演算などに変えても
最近のコンピュータであれば一瞬で作業は終わるでしょう
いかに主記憶と周辺機器の入出力作業に時間がかかるかわかると思います


time_t time( time_t *timer );

システム時刻を返します
万国標準時 (UCT)の1970年1月1日の00:00:00からの経過時間を秒単位で表した数値を得ます

ヘッダ - time.h timer - 時間を格納する変数へのポインタ

戻り値 - 格納する値

struct tm *localtime( const time_t *timer );

時刻値を変換し、時間構造体を返します

ヘッダ - time.h
timer - 時刻値が格納されている変数へのポインタ

戻り値 - 時刻値を変換した構造体へのポインタ。1970以前の値の場合はNULL

double difftime( time_t timer1, time_t timer0 );

二つの時刻の差を得る

ヘッダ - time.h
timer0 - 開始時刻
timer1 - 終了時刻

戻り値 - timer0からtimer1までの秒単位の経過時間



前のページへ戻る次のページへ