日付時刻(2)

asctime_r()、ctime_r()、gmtime_r()、localtime_r()

char *asctime_r(const struct tm *tm,char *buf);
char *ctime_r(const time_t *timep,char *buf);
struct tm *gmtime_r(const time_t *timep,struct tm *result);
struct tm *localtime_r(const time_t *timep, struct tm *result);


asctime()、ctime()、gmtime()、localtime()は静的に確保された領域を返します。これらの領域は、別の場所で呼び出された関数によって結果が上書きされる可能性があります。

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

int main() {
  char *s;
  time_t clock;
  struct tm *time_ptr;

  time(&clock);

  s=ctime(&clock);
  printf("ctime(1): %s",s);

  time_ptr=localtime(&clock);
  printf("asctime(1): %s",asctime(time_ptr));

  clock=clock+1*60*60; // 一時間進める
  printf("asctime(2): %s",asctime(localtime(&clock))); // 一時間先の時刻を出力
  printf("ctime(1): %s",s); // 元の時刻を出力
  printf("asctime(1): %s",asctime(time_ptr)); // 元の時刻を出力

  return 0;
}


この結果は次の様になります。

ctime(1): Sat Feb 27 16:09:41 2010
asctime(1): Sat Feb 27 16:09:41 2010
asctime(2): Sat Feb 27 17:09:41 2010 <- 一時間後
ctime(1): Sat Feb 27 17:09:41 2010     <- 一時間後になってる!?
asctime(1): Sat Feb 27 17:09:41 2010 <- 一時間後になってる!?


上書きされると困る場合は複製すれば良いのですが、マルチスレッド環境で同時に実行される可能性がある場合は次の関数を使います。

char *asctime_r(const struct tm *tm,char *buf);
char *ctime_r(const time_t *timep,char *buf);
struct tm *gmtime_r(const time_t *timep,struct tm *result);
struct tm *localtime_r(const time_t *timep, struct tm *result);

二番目の引数に、結果を格納する為のバッファを渡します。asctime_r()とctime_r()で使うバッファは、最低でも26文字分必要です。

使い方

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

int main() {
  char s1[26],s2[26];
  time_t clock;
  struct tm time_ptr1,time_ptr2;

  time(&clock);

  ctime_r(&clock,s1);
  printf("ctime_r(1): %s",s1);

  localtime_r(&clock,&time_ptr1);
  printf("asctime(1): %s",asctime(&time_ptr1));

  clock=clock+1*60*60; // 一時間進める

  // 一時間先の時刻を出力
  printf("asctime_r(2): %s",asctime_r(localtime_r(&clock,&time_ptr2),s2));
  printf("ctime_r(1): %s",s1); // 元の時刻を出力
  printf("asctime(1): %s",asctime(&time_ptr1)); // 元の時刻を出力

  return 0;
}

コンパイル

プログラムが書かれたファイル名をtest.cとします。

gcc test.c

結果

ctime_r(1): Sat Feb 27 16:19:30 2010
asctime(1): Sat Feb 27 16:19:30 2010
asctime_r(2): Sat Feb 27 17:19:30 2010 <- 一時間後
ctime_r(1): Sat Feb 27 16:19:30 2010     <- 影響を受けてない
asctime(1): Sat Feb 27 16:19:30 2010    <- 影響を受けてない