[C言語 標準ライブラリ] time.hの使い方

※本ブログでは、商品・サービスのリンク先にプロモーションを含みます。

スポンサーリンク

time.hには、時間を操作するための型や関数が宣言および定義されています。
多くの関数は、現在の日付と時刻を表すカレンダータイムを扱います。
いくつかの関数は、特定のタイムゾーンで表現されるカレンダータイムであるローカルタイムや、ローカルタイムを決定するアルゴリズムの一時的な変更である夏時間を扱います。ローカルタイムゾーンと夏時間は実装で定義されます。

スポンサーリンク

マクロ

CLOCKS_PER_SEC

1秒あたりのクロック数です。
clock_tの値を秒に変換するために使用されます。
clock関数の返す値をこのマクロで割ることで、秒単位の値を得ることができます。

NULL

NULLポインタ定数です。
stddef.h、locale.h、stdio.h、stdlib.h、string.h、time.h、wchar.hで定義されます。

clock_t

clock関数が返す時刻を表す型です。
算術型として定義されます。
プログラムのCPU使用時間を表現するために使用されます。

size_t

sizeof演算子が生成する結果を表すための符号無し整数型です。
stddef.h、stdio.h、stdlib.h、string.h、time.h、wchar.hで定義されます。

struct tm

暦時刻を要素型の時刻として表す構造体型です。
tmは以下のメンバを含みます。

メンバ名説明(値の範囲)
inttm_sec秒を表します。(0~60、0~61)※1
inttm_min分を表します。(0~59)
inttm_hour時を表します。(0~24)
inttm_mday日を表します。(1~31)
inttm_mon1月からの月数を表します。(0~11)
inttm_year1900年からの年数を表します。
inttm_wday日曜日からの日数を表します。(0~6)
inttm_yday1月1日からの日数を表します。(0~365)
inttm_isdst夏時間フラグです。※2

※1:C89の値の範囲は0~61です。2秒までのうるう秒が考慮されています。C99/C11の値の範囲は0~60です。正のうるう秒が考慮されています。

※2:夏時間を採用しているときに正、夏時間を採用していないときに0,その情報が得られないときに負となります。

time_t

暦時刻を表す型です。
算術型として定義されます。
時間の取得や計算、時間関数の引数として使用されます。

時間を扱う関数

clock_t clock(void)

現在のプロセッサ時間を取得します。
プログラムの実行のみに関係する、経過したプロセッサ時間の値が返されます。
戻り値をCLOCKS_PRE_SECで割ることで、秒での経過時間を算出できます。
プロセッサ時間が使用できない、または値が表現できない場合は-1が返されます。

使用例:

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

int g_i = 0;

int main(void)
{
	clock_t start, end;	// 開始時刻と終了時刻を格納する変数
	double elapsed;		// 経過時間を格納する変数
	
	start = clock();	// 開始時刻を取得
	
	// 何らかの処理
	for(int i=0; i<100000000; i++){
		g_i++;
	}
	
	end = clock();		// 終了時刻を取得
	
	elapsed = (double)(end - start) / CLOCKS_PER_SEC;	// 経過時間を秒単位で計算
	printf("経過時間:%lf秒\n", elapsed);			// 経過時間を表示
	
	return 0;
}

実行結果:(※結果の秒数は実行環境によって異なります)

経過時間:0.214000秒

double difftime(time_t time1, time_t time0)

time1 – time0の2つのカレンダー時間の差を計算します。
秒で計った差が返されます。

使用例:

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

int main(void)
{
    time_t t1, t2;
    double diff;

    // 現在の時刻を取得
    t1 = time(NULL);

    // 5秒待機
    Sleep(5000); // ミリ秒単位で指定するため、5秒は5000ミリ秒です

    // 再度現在の時刻を取得
    t2 = time(NULL);

    // 差分を計算
    diff = difftime(t2, t1);

    printf("経過時間:%.2f秒\n", diff);

    return 0;
}

実行結果:

経過時間:5.00秒

time_t mktime(struct tm *timeptr)

展開時間をtime_t型に変換します。
引数timeptrが指すオブジェクトの局所時間で表した展開時間が、time関数が返す値と同じ形式で返されます。
構造体メンバのtm_wdayとtm_ydayは無視されます。
正常に終了した場合は、構造体メンバのtm_wdayおよびtm_ydayには、適切な値が格納されます。
tm_mdayの終端値はtm_monおよびtm_yearが決定されるまで設定されません。
指定されたカレンダー時間をtime_t型としてエンコードした値が返されます。
カレンダー時間が表現不可能な場合は、-1が返されます。

使用例:

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

int main(void)
{
    struct tm timeinfo;
    time_t rawtime;

    // struct tm のメンバーを設定
    timeinfo.tm_year  = 2023 - 1900; // 年
    timeinfo.tm_mon   = 5 - 1;       // 月 (0-based, なので5月は4)
    timeinfo.tm_mday  = 26;          // 日
    timeinfo.tm_hour  = 14;          // 時
    timeinfo.tm_min   = 30;          // 分
    timeinfo.tm_sec   = 0;           // 秒
    timeinfo.tm_isdst = -1;          // 夏時間情報はシステムに依存

    // mktimeを使って、エポック時間に変換
    rawtime = mktime(&timeinfo);

    if(rawtime != -1){
        printf("算出された時間は、%s", ctime(&rawtime));
    }

    return 0;
}

実行結果:

算出された時間は、Fri May 26 14:30:00 2023

time_t time(time_t *timer)

現在のカレンダー時間を取得します。
カレンダー時間が使用できない場合は、-1が返されます。
timerがNULLポインタでなければ、ポインタが指すオブジェクトにも戻り値が格納されます。

使用例:

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

int main(void)
{
    time_t current_time;

    // 現在のエポック時間を取得
    current_time = time(NULL);

    // 成功した場合(つまり、timeが-1を返さない場合)、
    // ctimeを使ってエポック時間を人が読める形式に変換して出力する
    if(current_time != -1){
        printf("現在の時刻は、%s", ctime(&current_time));
    }

    return 0;
}

実行結果:

現在の時刻は、Fri May 26 03:54:49 2023

スポンサーリンク

時間変換関数

char *asctime(const struct tm *timeptr)

struct tm型のオブジェクトを以下の形式の文字列に変換します。

Sun Sep 16 01:03:52 1973\n\0

この文字列へのポインタが返されます。

使用例:

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

int main(void){
    struct tm timeinfo;
    char *time_str;

    // struct tm のメンバーを設定
    timeinfo.tm_year  = 2023 - 1900; // 年
    timeinfo.tm_mon   = 5 - 1;       // 月 (0-based, なので5月は4)
    timeinfo.tm_mday  = 26;          // 日
    timeinfo.tm_wday  = 5;           // 曜日
    timeinfo.tm_hour  = 14;          // 時
    timeinfo.tm_min   = 30;          // 分
    timeinfo.tm_sec   = 0;           // 秒
    timeinfo.tm_isdst = -1;          // 夏時間情報はシステムに依存

    // asctimeを使って、人が読める時間文字列に変換
    time_str = asctime(&timeinfo);

    if(time_str != NULL){
        printf("フォーマットされた時刻は、%s", time_str);
    }

    return 0;
}

実行結果:

フォーマットされた時刻は、Fri May 26 14:30:00 2023

char *ctime(const time_t *timer)

time_t型のオブジェクトを文字列に変換します。
asctime(localtime(timer))と同等です。
asctime関数が返す値が返されます。

使用例:

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

int main(void)
{
    time_t current_time;
    char *c_time_string;

    // 現在の時間を取得
    current_time = time(NULL);

    // 時間を文字列に変換
    c_time_string = ctime(&current_time);

    // 時間を表示
    printf("現在の時刻は、%s", c_time_string);

    return 0;
}

実行結果:

現在の時刻は、Sat May 27 14:03:47 2023

struct tm *gmtime(const time_t *timer)

time_t型のオブジェクトをUTC(Coordinated Universal Time:協定世界時)としてstruct tmに変換します。
渡されたオブジェクトへのポインタが返されます。
UTC が使用不能な場合はNULLポインタが返されます。

使用例:

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

int main(void)
{
    time_t current_time;
    struct tm *time_info;

    // 現在の時間を取得
    current_time = time(NULL);

    // 時間をUTC基準のstruct tmに変換
    time_info = gmtime(&current_time);

    // 年、月、日を表示
    printf("現在の年月日は、%d-%02d-%02d\n",
           time_info->tm_year + 1900, 
           time_info->tm_mon + 1,
           time_info->tm_mday);

    return 0;
}

実行結果:

現在の年月日は、2023-05-27

struct tm *localtime(const time_t *timer)

time_t型のオブジェクトを現在の時間帯でstruct tmに変換します。
オブジェクトへのポインタが返されます。

使用例:

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

int main(void)
{
    time_t current_time;
    struct tm *time_info;

    // 現在の時間を取得
    current_time = time(NULL);

    // 時間をローカルタイム基準のstruct tmに変換
    time_info = localtime(&current_time);

    // ローカル時刻を表示
    printf("現在のローカル時刻は、%d-%02d-%02d %02d:%02d:%02d\n",
           time_info->tm_year + 1900, 
           time_info->tm_mon + 1,
           time_info->tm_mday,
           time_info->tm_hour,
           time_info->tm_min,
           time_info->tm_sec);

    return 0;
}

実行結果:

現在のローカル時刻は、2023-05-27 14:13:48

size_t strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)

引数sが指す配列にformatに制御される文字列を格納します。

引数意味
char *s変換した文字列が格納されるバッファへのポインタ
size_t maxsizeバッファの最大サイズ
const char *format出力形式を指定する文字列へのポインタ
const struct tm *timeptr変換するtm構造体へのポインタ

書式はマルチバイト文字の連なりで、初期シフト状態に始まり初期シフト状態で終わる必要があります。
format文字列は0以上の変換指定子とマルチバイト文字から成っています。
変換指定子は1文字の%と、その後の変換動作を決定する一文字から成っています。
終端のNULL文字を含む全てのマルチバイト文字は、変更を加えられずに配列にコピーされます。
コピーが重複するオブジェクト間で発生した場合の動作は未定義です。
maxsize以下の文字が配列に格納されます。
各変換指定子は下表の文字列によって置き換えられます。
適切な文字列は、LC_TIME分野のロケールおよびtimeptrが指すオブジェクトによって決定されます。

変換指定子説明
%aロケールでの曜日の略名で置換されます。
%Aロケールでの曜日の名前で置換されます。
%bロケールでの月の略名で置換されます。
%Bロケールでの月の名前で置換されます。
%cロケールでの適切な日付と時刻で置換されます。
%d月の中の日が10進数で置換されます。(01-31)
%H24時間時計での時間が10進数で置換されます。(00-23)
%I12時間時計での時間が10進数で置換されます。(01-12)
%j年の中の日が10進数で置換されます。(001-366)
%m月が10進数で置換されます。(01-12)
%M分が10進数で置換されます。(00-59)
%pロケールでの、12時間時計でいう午前・午後に相当する文字列で置換されます。
%S秒が10進数で置換されます。(00-61)
%U年の始まりから経過した週の数(最初の日曜を最初の週の最初の日として)が10進数で置換されます。(00-53)
%w日曜を0として、曜日が10進数で置換されます。(0-6)
%W年の始まりから経過した週の数(最初の月曜を最初の週の最初の日として)が10進数で置換されます。(00-53)
%xロケールでの適切な日付表現で置換されます。
%Xロケールでの適切な時刻表現で置換されます。
%y世紀を除いた年が10進数で置換されます。(00-99)
%Y世紀を含んだ年が10進数で置換されます。
%z時間帯の略名か、時間帯が決定されない場合は空文字列で置換されます。
%%%で置換されます。

変換指定子が上記のものに該当しない場合の動作は未定義です。
終端のNULL文字を含む結果の文字数がmaxsize以下なら、sが指す配列に配置された終端のNULL文字を含まない文字数が返されます。
そうでなければ0が返され、配列の内容は不定となります。

使用例:

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

int main(void)
{
    time_t current_time;
    struct tm *time_info;
    char buffer[80];

    // 現在の時間を取得
    current_time = time(NULL);

    // 時間をローカルタイム基準のstruct tmに変換
    time_info = localtime(&current_time);

    // 時間を指定した形式で文字列に変換
    strftime(buffer, 80, "現在のローカル時刻は、%Y-%m-%d %H:%M:%S", time_info);

    // 時間を表示
    printf("%s\n", buffer);

    return 0;
}

実行結果:

現在のローカル時刻は、2023-05-27 17:36:30

スポンサーリンク
C言語

コメント