時間情報の取得方法と扱い方
ここではC言語での時間情報の取得方法について説明していく、 時間情報には様々な種類があり、また環境により利用できる関数も変わってくる。 C言語の環境であればどこでも利用できる標準関数から始まり、POSIX環境、Windows環境で利用できるAPIも紹介する。
POSIX環境
ここからは、Linux をはじめとする POSIX 環境で使用できる方法を紹介する。 C言語標準ではないので、使用できる環境は幾分狭まるが、Windowsを除けばほとんどの環境で利用できる。
gettimeofday()
POSIX環境では以下の関数が使用できる。
#include <sys/time.h>
struct timeval {
time_t tv_sec; /* Seconds. */
suseconds_t tv_usec; /* Microseconds. */
};
int gettimeofday(struct timeval *tv, struct timezone *tz);
struct timeval
は、
timespec_get()
で紹介した
struct timespec
と非常によく似ている。
tv_sec
は秒単位の値を格納する。
tv_usec
はマイクロ秒、1,000,000 分の 1 秒単位の値で、
0~999,999 の範囲で 1 秒未満の時間を格納する。
この2つの構造体は現在の時刻以外に任意の時間の表現にも使用され、 以下の様な変換マクロも用意されている。値の関係が一目瞭然だろう。
# define TIMEVAL_TO_TIMESPEC(tv, ts) { \
(ts)->tv_sec = (tv)->tv_sec; \
(ts)->tv_nsec = (tv)->tv_usec * 1000; \
}
# define TIMESPEC_TO_TIMEVAL(tv, ts) { \
(tv)->tv_sec = (ts)->tv_sec; \
(tv)->tv_usec = (ts)->tv_nsec / 1000; \
}
gettimeofday()
で得られる値は、この構造体で UNIX 時間を表現した値となる。
つまり、tv_sec
の値についてはtime()
で取得した値と同じで、
秒未満の値がtv_usec
に格納される。
こちらもどれだけの分解能が得られるかは環境依存となるが、 ソフトウェア制御としては十分な精度で時間を取得できる。
第二引数のstruct timezone *tz
は、
名前の通りタイムゾーンの情報を格納するために使用されるのだが、
現在は廃止予定となっており、
POSIX規格では NULL 以外の値を指定した場合の挙動は「未定義」になっている。
そのため、利用する際は必ず NULL を指定する。
使用例は以下
#include <stdio.h>
#include <sys/time.h>
int main(int argc, char **argv) {
struct timeval tv;
gettimeofday(&tv, NULL);
printf("%ld %06lu\n", tv.tv_sec, tv.tv_usec);
gettimeofday(&tv, NULL);
printf("%ld %06lu\n", tv.tv_sec, tv.tv_usec);
return 0;
}
実行すると以下のようになる。
1446720502 328669 1446720502 328759
……と、ここまで紹介しておいて今更ではあるが、
現在はgettimeofday()
という関数自体が非推奨となっており、
今後は次に紹介するclock_gettime()
を使用すべきとなっている。
だが、おそらく既存のコードの多くで、もしくは現在開発中のものであっても、まだまだ利用されている関数である。
使用にあたっては臨機応変に対応し、選択可能であれば次項で説明するclock_gettime()
を利用するようにしよう。