名前
strftime - 日付および時刻の文字列への変換
書式
#include <time.h>
size_t strftime(char *s, size_t max, const char *format,
const struct tm *tm);
説明
strftime() 関数 は、要素別の時刻 tm の内容を format で指定された書式指定にしたがって変換し、 長さ max の文字列 s に書き込む。
書式文字列に含まれる通常の文字は変換されずそのまま文字列 s にコピーされる。「変換指定」は % 文字で始まり、 「変換指定文字」で終端される。 以下のように変換されて s に格納される:
%a | 現在のロケールにおける曜日の省略名。 |
%A | 現在のロケールにおける曜日の完全な名前。 |
%b | 現在のロケールにおける月の省略名。 |
%B | 現在のロケールにおける月の完全な名前。 |
%c | 現在のロケールにおいて一般的な日付・時刻の表記。 |
%C | 世紀 (西暦年の上 2 桁)。 (SU) |
%d | 月内通算日 (10 進数表記) (01-31)。 |
%D | %m/%d/%y と等価。(うえっ、アメリカ専用だ。アメリカ以外の国では %d/%m/%y の方が一般的だ。つまり、日付によってはどちらか判断できない ので国際化された文脈では使用しないほうがいい。) (SU) |
%e | %d と同様に月内通算日を 10 進数で表現するが、 1 桁の場合 10 の位にゼロを置かずスペースを置く。(SU) |
%E | 別形式を使用する際の修飾子。下記参照。 (SU) |
%F | %Y-%m-%d と等価 (ISO 8601 形式の日付フォーマット)。 (C99) |
%G | ISO 8601 形式の年 (世紀も 10 進数で表す)。 ISO 週数 (%V を参照) に対応した 4 桁の西暦年。 これは基本的には %y と同じ形式だが、ISO 週数が前年や翌年になる 場合にはその年が使用される。(TZ) |
%g | %G と同様。但し、世紀を含まず下 2 桁のみを表示 (00-99)。 (TZ) |
%h | %b と等価 (SU) |
%H | 24 時間表記での時 (hour)。 (00-23) |
%I | 12 時間表記での時 (hour)。 (01-12) |
%j | 年の初めから通算の日数。 (001-366) |
%k | 24 時間表記での時 (0-23)。 1 桁の場合には前にゼロでなくスペースが置かれる。(%H も参照) (TZ) |
%l | 12 時間表記での時 (0-12)。 1 桁の場合には前にゼロでなくスペースが置かれる。(%I も参照) (TZ) |
%m | 月 (10 進数表記)。 (01-12) |
%M | 分 (10 進数表記) (00-59) |
%n | 改行。 (SU) |
%O | 別形式を使用する際の修飾子。以下を参照。(SU) |
%p | 現在のロケールにおける「午前」「午後」に相当する文字列。 英語の場合には AM または PM となる。 正午は午後、真夜中は午前として扱われる。 |
%P | %p と同様であるが小文字が使用される。 英語の場合には am や pm となる。(GNU) |
%r | 午前・午後形式での時刻。 POSIX ロケールでは %I:%M:%S %p と等価である。(SU) |
%R | 24 時間表記での時刻、秒は表示しない (%H:%M)。(SU) 秒を含んだものは以下の %T を参照すること。 |
%s | 紀元 (1970年 1 月 1 日 00:00:00 UTC) からの秒数。 (TZ) |
%S | 秒 (10 進数表記) (00-60) (時々ある閏秒に対応するため、値の範囲は 60 までとなっている) |
%t | タブ文字 (SU) |
%T | 24 時間表記の時間 (%H:%M:%S) (SU) |
%u | 週の何番目の日 (10 進数表記) か。月曜日を 1 とする (1-7)。 %w も参照。(SU) |
%U | 年の初めからの通算の週数 (10 進数表記) (00-53)。 その年の最初の日曜日を、第 1 週の始まりとして計算する。 %V と %W も参照すること。 |
%V | ISO 8601:1988 形式での年の始めからの週数 (10 進数表記) (00-53)。 その年に少なくとも 4 日以上含まれる最初の週を 1 として計算する。 週の始まりは月曜日とする。%U と %W も参照すること。 |
%w | 週の何番目の日 (10 進数表記) か。日曜日を 0 とする。(0-6)。 %u も参照。(SU) |
%W | 年の初めからの通算の週数 (10 進数表記) (00-53)。 その年の最初の月曜日を、第 1 週の始まりとして計算する。 |
%x | 現在のロケールで一般的な日付表記。時刻は含まない。 |
%X | 現在のロケールで一般的な時刻表記。日付は含まない。 |
%y | 西暦の下2桁 (世紀部分を含まない年) (00-99)。 |
%Y | 世紀部分を含めた ( 4 桁の) 西暦年。 |
%z | タイムゾーンの GMT へのオフセット時間。 RFC 822 形式の日時に必要である。 ("%a, %d %b %Y %H:%M:%S %z" として使用する)。(GNU) |
%Z | タイムゾーンまたはゾーン名または省略名。 |
%+ | date(1) 形式での日時。(TZ) (glibc2 ではサポートされていない) |
%% | % 文字。 |
要素別の時刻構造体 tm の詳細は <time.h> に定義されている。 ctime(3) も参照すること。
返り値
strftime() 関数は文字列 s に格納された文字数を返す。 この文字数に終端の NULL バイトは含まない。 終端の NULL バイトを格納できるだけの大きさを持った文字列を渡すこと。 それ以外の場合は 0 を返し、文字列の内容は修正されない。 (これは少なくとも libc 4.4.4 以降では正しい。非常に古いバージョンの libc、 例えば libc 4.4.1 では文字列が短か過ぎた場合には max が返される。)
返り値 0 は必ずしもエラーを意味している訳ではないので注意すること。 例えば、多くのロケールでは %p は空文字列を返す。
環境変数
環境変数 TZ と LC_TIME が使用される。 (訳注: LC_ALL が設定されている場合には LC_TIME よりもそちらが優先される。 LC_TIME も LC_ALL も設定されていない場合には LANG が使用される。)
準拠
SVr4, C89, C99. 個々の変換が厳密にどの規格に含まれるかは、 ANSI C (印なし)、統一 UNIX 規格 (SU印)、Olson の timezone パッケージ (TZ印)、 glibc 独自 (GNU印) で示している。glibc2 では %+ はサポートされていないが、 いくつかの拡張が行われている。POSIX.1 では ANSI C のみを参照している。 POSIX.2 の date(1) のところに記述されている幾つかの拡張は strftime() にも適用できるだろう。 %F 変換は C99 と POSIX.1-2001 にある。
SUSv2 では、%S は 00 から 61 の範囲をとると規定されている。 これは、1分間のうち閏秒が 2つ入る可能性が理論的にはあることを 考慮してのものである (実際には、このような状況はこれまで一度も 起こっていない)。
注意
glibc での注意
glibc では変換指定にいくつか拡張を行っている (これらの拡張は POSIX.1-2001 には規定されていないが、 他のいくつかのシステムで同様の機能が提供されている)。 % 文字と変換指定文字の間に、オプションとして flag とフィールドの 幅 を指定できる (これらを指定する場合には E や O 修飾子の前に置く)。
以下のフラグ文字が使用できる:
_ | (下線) 数値の結果文字列のパディング (穴埋め) をスペース (空白文字) で行う。 |
- | (ダッシュ) 数値の結果文字列に対するパディングを行わない。 |
0 | 変換指定文字がデフォルトではスペースでパディングを行う場合でも、 数値の結果文字列へのパディングを 0 で行う。 |
^ | 結果文字列中のアルファベット文字を大文字に変換する。 |
# | 結果文字列の大文字・小文字を入れ替える (このフラグは特定の変換指定文字でしか機能しない。その中でも 本当に有用なのは %Z の場合だけである)。 |
バグ
gcc のいくつかのバージョンにはおかしなところがあり、
%c の使用法について以下のような警告を出す:
warning: %c yields only last 2 digits of year in some locales (警告:いくつかのロケールでは%cは年の下2桁しか出力しない)。 もちろんプログラマが %c を使うのはお薦めできることである。
%c を使うと適切な日付と時刻の表記を得ることができるからである。
gcc のこの問題を回避しようとすると、何かすっきりしない気分になるだろう。
比較的きれいな解決方法は以下のような中間関数を追加することである。
size_t
my_strftime(char *s, size_t max, const char *fmt,
const struct tm *tm)
{
return strftime(s, max, fmt, tm);
}
例
以下のプログラムを使うと
strftime() の実験ができる。
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
char outstr[200];
time_t t;
struct tm *tmp;
t = time(NULL);
tmp = localtime(&t);
if (tmp == NULL) {
perror("localtime");
exit(EXIT_FAILURE);
}
if (strftime(outstr, sizeof(outstr), argv[1], tmp) == 0) {
fprintf(stderr, "strftime returned 0");
exit(EXIT_FAILURE);
}
printf("Result string is \"%s\"\n", outstr);
exit(EXIT_SUCCESS);
} /* main */
以下に、
strftime() の glibc 実装が生成する結果の例をいくつか示す:
$ ./a.out "%m"
Result string is "11"
$ ./a.out "%5m"
Result string is "00011"
$ ./a.out "%_5m"
Result string is " 11"
関連項目
date(1), time(2), ctime(3), setlocale(3), sprintf(3), strptime(3)