gettimeofday

Autres langues

Langue: ja

Version: 2004-05-27 (mandriva - 01/05/08)

Section: 2 (Appels système)

名前

gettimeofday, settimeofday - 時刻を取得/設定する

書式

#include <sys/time.h>

int gettimeofday(struct timeval *tv, struct timezone *tz);
int settimeofday(const struct timeval *tv , const struct timezone *tz);

説明

関数 gettimeofday() と settimeofday() は時刻とタイムゾーンを取得または設定する。 tv 引き数は struct timeval である (<sys/time.h> で定義されている):
 struct timeval {
     time_t      tv_sec;     /* 秒 */
     suseconds_t tv_usec;    /* マイクロ秒 */
 };
 

これにより紀元 (the Epoch: time(2) を参照) からの秒とマイクロ秒が取得できる。 tz 引き数は struct timezone である:

 struct timezone {
     int tz_minuteswest;     /* グリニッジ標準時との差 (西方に分単位) */
     int tz_dsttime;         /* 夏時間調整の型 */
 };
 

tvtz が NULL の場合、対応する構造体の設定/取得は行われない。

timezone 構造体を使うのは時代遅れ (obsolete) である: tz 引き数は通常は NULL に指定すべきである。 tz_dsttime フィールドは Linux では一切使われてこなかった; libc や glibc でもサポートされてこなかったし、 これからもサポートされることはない。 カーネルのソース中の宣言以外で、このフィールドが存在するのは全てバグである。 よってこれ以降の記述は、純粋に歴史的興味に基づいたものである。

tz_dsttime フィールドには (以下で与えられるような) シンボル定数が格納される。 これは一年のうちでいつ夏時間 (Daylight Savings Time) を実施するかを示している (注意: その値は年間を通した定数である: 夏時間が実施中であることを示すわけではなく、 アルゴリズムを選択しているだけである)。 夏時間は以下のように定義される:

DST_NONE /* 夏時間を採用していない */
DST_USA /* アメリカ合衆国式夏時間 */
DST_AUST /* オーストラリア式夏時間 */
DST_WET /* 西ヨーロッパ式夏時間 */
DST_MET /* 中央ヨーロッパ式夏時間 */
DST_EET /* 東ヨーロッパ式夏時間 */
DST_CAN /* カナダ */
DST_GB /* グレートブリテンおよびアイルランド */
DST_RUM /* ルーマニア */
DST_TUR /* トルコ */
DST_AUSTALT /* 1986年に移行されたオーストラリア式 */

当然のことながら、夏時間がどの期間に実施されるかを 国ごとの簡単なアルゴリズムで導くことができないことが判明した。 実際、夏時間の期間は予測不可能な政治的決定で決まる。 そのためこの方法でタイム・ゾーンを表すことは断念された。 Linux において settimeofday() を呼び出すときは、 tz_dsttime フィールドを 0 にするべきである。

Linux では、 settimeofday() システム・コールに関連して、独特の「クロックのズレ (warp clock)」が存在する。 これは (ブート後の) 最初の呼び出しで tz 引き数が NULL でなく、 tv 引き数が NULL で tz_minuteswest フィールドが 0 でない場合に起こる。 このような場合、 settimeofday() は CMOS クロックが地方時 (local time) であり、 UTC システム時間を得るためには、 tz_minuteswest の分だけ増加させなくてはならないとみなしてしまう。 疑いもなく、この機構を使うことは良い考えではない。

struct timeval を操作するために以下のマクロが定義されている:

 #define timerisset(tvp)\
 
((tvp)->tv_sec || (tvp)->tv_usec) #define timercmp(tvp, uvp, cmp)\ ((tvp)->tv_sec cmp (uvp)->tv_sec ||\ (tvp)->tv_sec == (uvp)->tv_sec &&\ (tvp)->tv_usec cmp (uvp)->tv_usec)
#define timerclear(tvp)\
((tvp)->tv_sec = (tvp)->tv_usec = 0)

返り値

gettimeofday() と settimeofday() は成功すると 0 を返し、失敗した場合は -1 を返す (この場合は errno が適切に設定される)。

エラー

EFAULT
tvtz の指す領域のどちらかがアクセス可能なアドレス空間にない。
EINVAL
タイムゾーン (または他の何か) が不正である。
EPERM
呼び出し元プロセスに settimeofday() を呼び出すための十分な特権がない。 Linux では CAP_SYS_TIME ケーパビリティ (capability) が必要である。

準拠

SVr4, 4.3BSD に準拠する。 POSIX.1-2001 は gettimeofday() については記述しているが、 settimeofday() については記述していない。

注意

settimeofday() のプロトタイプと timercmp, timerisset, timerclear, timeradd, timersub の定義は (glibc 2.2.2 以降は) _BSD_SOURCE が定義されている場合にのみ利用可能となる。

昔は struct timeval のフィールドは long 型であった。

関連項目

date(1), adjtimex(2), time(2), ctime(3), ftime(3), capabilities(7), time(7)