時刻・時間に関する、以下の関数を使うには、time.h の #include が必要である。
#include <stdio.h> #include <time.h> int main() { int i, j; time_t start, end; time(&start); /* 現在時刻を取得 */ for (i = 0; i < 10*1000; i++) { /* 時間稼ぎ */ for (j = 0; j < 1000*1000; j++) { ; } } end = time(NULL); /* 現在時刻を取得 */ printf("%f 秒かかりました.\n", difftime(end, start)); }
time_t は時刻を保持する型である。 関数 time() は現在時刻を取得する関数である。二通りの使い方がある。 一つは time(&start) のように、引数として time_t 型へのポインタをとるもの。 そこに現在時刻がはいる。 もう一つは、end = time(NULL) のように使うもの。 end に現在時刻がはいる。
この数値は、世界協定時 (UTC) の1970 年 01 月 01 日 00 時 00 分 00 秒からの経過秒数であることが多いようだ。 「計算数学a」「計算数学b」ではこの数値を乱数の種として使ったのだった。
関数 difftime(time_t time2, time_t time1) は、 time_1 から time_2 までの時間を秒を単位として返す。 返り値の型は double である。
上のプログラムは、時間稼ぎのため空(から)ループを回し、 かかった時間をはかっている。
#include <stdio.h> #include <time.h> int main() { time_t now; time(&now); /* 現在時刻を取得 */ printf("%s\n", ctime(&now)); }
関数 ctime(time_t *tp) は tp が示す時刻を、 ローカルタイム(=地方時)に変換し、アメリカ合衆国において標準的な方法で表した文字列にして返す。 たとえば Wed Jan 31 10:40:26 2024\n\0 のようになる。
time.h で定義されている構造体 struct tm には次のメンバがある。
int tm_sec; | 秒、範囲は 0 から 61 まで。正のうるう秒にも対応 |
int tm_min; | 分、範囲は 0 から 59 まで |
int tm_hour; | 時、範囲は 0 から 23 まで |
int tm_mday; | 日、範囲は 1 から 31 まで |
int tm_mon; | 月、範囲は 0 から 11 まで。一月が 0 であることに注意 |
int tm_year; | 年、1900 年からの年であることに注意 |
int tm_wday; | 曜日、日曜日が 0, 土曜日が 6 |
int tm_yday; | 年内の通算日、1 月 1 日が 0 |
int tm_isdst; | 夏時間のフラグ(詳細略) |
#include <stdio.h> #include <time.h> void printdate(struct tm *tp); int main() { time_t now; struct tm nowp; time(&now); /* 現在時刻を取得 */ nowp = *localtime(&now); /* struct tm 型に変換 */ printdate(&nowp); /* 年月日を出力 */ nowp.tm_mday++; /* mday を 1 だけ増す。きょうなら 32 日になる */ printdate(&nowp); /* ありえない年月日を出力 */ mktime(&nowp); /* それを修正する */ printdate(&nowp); /* 今度は正しくあすの年月日を出力 */ } /* *tp の年月日を出力 */ void printdate(struct tm *tp) { printf("%d-%02d-%02d\n", 1900 + tp->tm_year, 1 + tp->tm_mon, tp->tm_mday); }
関数 localtime(time_t *tp) は *tp を struct tm に変換する。 ただしその時刻はローカルタイム(=地方時)である。 変換されたものを nowp に代入している。 自作関数 void printdate(struct tm *tp) は *tp の中の年、月、日を出力する。
「mday を 1 だけ増す」の行。 きょうこれを実行すると 2024-01-32 と、ありえない年月日になる。 関数 mktime(struct tm *tp) はこれを正しい年月日に変換してくれる。 返り値は time_t 型だが、それはここでは用いていない。 次に printdate() で出力すると、今度は正しくあすの年月日を出力する。
関数 strftime() を使うと、日付時刻をさまざまな形で文字列化できる。 第一引数はどの文字列に書き込むか、 第二引数は文字数の上限、 第三引数は何を書き込むか、 第四引数は struct tm 型へのポインタ、である。 「何を書き込むか」は、printf() のときと同様、 普通の文字はそのまま、% で始まる文字は規則に従って変換されて、となる。 以下のプログラムに、すべての例をあげておいた。 (週番号には、 「1 月 1 日を含む週を第 1 週とするもの」と、 「1 月 4 日を含む週を第 1 週とするもの」とがあるので注意。)
#include <stdio.h> #include <time.h> int main() { char str[64+1]; time_t now; struct tm nowp; time(&now); /* 現在時刻を取得 */ nowp = *localtime(&now); /* struct tm 型に変換 */ strftime(str, 64, "%a: 曜日の略称", &nowp); printf("%s\n", str); strftime(str, 64, "%A: 曜日", &nowp); printf("%s\n", str); strftime(str, 64, "%b: 月の略称", &nowp); printf("%s\n", str); strftime(str, 64, "%B: 月", &nowp); printf("%s\n", str); strftime(str, 64, "%c: 地方時", &nowp); printf("%s\n", str); strftime(str, 64, "%d: 日", &nowp); printf("%s\n", str); strftime(str, 64, "%H: 時、二十\四時制", &nowp); printf("%s\n", str); strftime(str, 64, "%I: 時、十\二時制", &nowp); printf("%s\n", str); strftime(str, 64, "%j: 年内通算日", &nowp); printf("%s\n", str); strftime(str, 64, "%m: 月", &nowp); printf("%s\n", str); strftime(str, 64, "%M: 分", &nowp); printf("%s\n", str); strftime(str, 64, "%p: 午前/午後", &nowp); printf("%s\n", str); strftime(str, 64, "%S: 秒", &nowp); printf("%s\n", str); strftime(str, 64, "%U: 週番号(日曜日を週の始まりとして、かつ、0 週目から始まる)", &nowp); printf("%s\n", str); strftime(str, 64, "%w: 曜日(日曜日が 0)", &nowp); printf("%s\n", str); strftime(str, 64, "%W: 週番号(月曜日を週の始まりとして、かつ、0 週目から始まる)", &nowp); printf("%s\n", str); strftime(str, 64, "%x: 日付", &nowp); printf("%s\n", str); strftime(str, 64, "%X: 時刻", &nowp); printf("%s\n", str); strftime(str, 64, "%y: 年下二桁", &nowp); printf("%s\n", str); strftime(str, 64, "%Y: 年", &nowp); printf("%s\n", str); strftime(str, 64, "%Z: タイムゾーン", &nowp); printf("%s\n", str); strftime(str, 64, "%%: %% そのもの", &nowp); printf("%s\n", str); }
現在の日付時刻について少なくとも 6 個以上の情報を出力するプログラムを書け。
レポートの本文冒頭に、氏名を、なるべく大学に届けるある通りの文字で書け。 次に、プログラムソースファイルを、添付ファイルではなく、本文に貼りつけよ。
件名は「??? kadai6」(←全て半角文字、小文字、 ??? は自分の履修者番号、その後ろに半角スペース一つ、 kadai と 6 の間にはスペースを入れない)とせよ。