時刻・時間に関する、以下の関数を使うには、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 の間にはスペースを入れない)とせよ。