現在時刻(エポックからの経過時間)の取得
▹(curent-time) エポック(1970-01-01 00:00:00 UTC)から手続き実行時点までの経過時間(秒数)を返します.返り値に閏秒(うるう秒)は含まれません.以下に実行例を示します.$ guile GNU Guile 3.0.5 ..... 起動メッセージ ...... guile> (current-time) $1 = 1645621292 guile>この手続きは,システムコールの time 関数を使って経過時間を求めています. このシステムコールに関して,[glibc:21.5.1 Getting the Time] は次のように述べています.
It uses the same clock as 'clock_gettime (CLOCK_REALTIME_COARSE)', when the clock is available or 'clock_gettime (CLOCK_REALTIME)' otherwise.さらに,Debian の [Manpages:CLOCK_GETRES(2)] に
CLOCK_REALTIME_COARSE (since Linux 2.6.32; Linux-specific)とあるので,おそらく clock_gettime (CLOCK_REALTIME_COARSE) を使って経過時間を求めているものと思います. ▹(gettimeofday) エポック(1970-01-01 00:00:00 UTC)から手続き実行時点までの経過時間(マイクロ秒単位)を,秒単位の部分(整数)と残りのマイクロ秒単位の部分(整数)のペアとして返します.返り値に閏秒(うるう秒)は含まれません. なお,マイクロ秒単位の精度が得られるかどうかはシステムに依存します. 以下に実行例を示します.下記($1)の第1要素が秒単位の部分,第2要素が残りのマイクロ秒単位の部分です.
guile> (gettimeofday) $2 = (1645621495 . 17717) guile>この手続きは,システムコールの gettimeofday 関数を使って経過時間を求めています. このシステムコールに対して,それぞれの仕様書は次のように述べています.
[POSIX:gettimeofday,APPLICATION USAGE]
Applications should use the clock_gettime() function instead of the obsolescent gettimeofday() function.
[glibc:21.5.1 Getting the Time]
As of the 2008 revision of POSIX, this function is considered obsolete. The GNU C Library will continue to provide this function indefinitely, but new programs should use clock_gettime instead.
[Manpages:GETTIMEOFDAY(2),NOTES]残念なことに,現在のGuileは clock_gettime 関数を使って現在時刻を求める手続きを用意していません.get-internal-real-time という手続きが clock_gettime 関数を使っているのですが,それはプロセス開始時刻からの経過時間(つまり,エポックから見たときのプロセス開始時刻と現在時刻の差分)を求めています. ただし,これは,マイクロ秒単位の精度で現在時刻を求めたい場合の話です. 秒単位の精度でよければ time 手続きを使えばよいと思います.
The time returned by gettimeofday() is affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the system time). If you need a monotonically increasing clock, see clock_gettime(2).
成分別時刻
UTCの成分別時刻への変換
▹(gmtime time) time が表す時刻をエポック(970-01-01 00:00:00 UTC)からの経過時間と見なして,UTC の broken-down time を表すベクタに変換して返します.time は,秒単位の整数です.通常,current-time 手続きや gettimeofday 手続きによって取得した経過時間を指定します.簡単な実行例を示します.
guile> (gmtime (current-time))
$1 = #(23 7 13 23 1 122 3 53 0 0 "GMT")
guile>
Guileにおける broken-down time(以下,成分別時刻)は,秒・分・時・日・月・年などの成分に分解した時刻のことです.Guileは成分別時刻をベクタによって表現しています.成分の種類については次節(成分を抽出する手続き)を参照して下さい.
ローカルな成分別時刻への変換
▹(localtime time)(localtime time zone)
[POSIX:localtime]
[POSIX: 8.3 Other Environment Variables,TZ]
[glibc:21.5.3 Broken-down Time] [glibc:21.5.6 Specifying the Time Zone with TZ]
[Manpages:CTIME(3)]
time が表す時刻をエポック(970-01-01 00:00:00 UTC)からの経過時間と見なして,zone が表すタイムゾーンの broken-down time を表すベクタに変換して返します.zone を省略した場合,環境変数の TZ に設定されたタイムゾーンかまたはシステム標準のタイムゾーン(/etc/localtime)を使用します.
time は秒単位の整数です.通常,current-time 手続きや gettimeofday 手続きによって取得した経過時間を指定します.
zone は次のような形式の文字列を指定します.
[glibc:21.5.3 Broken-down Time] [glibc:21.5.6 Specifying the Time Zone with TZ]
[Manpages:CTIME(3)]
":path"
ここで,path はタイムゾーンのデータファイルのパスです.そのパスの先頭がスラッシュ(/)だった場合,データファイルの絶対パスが指定されたものと解釈します.一方,パスの先頭がスラッシュ(/)でなかった場合,/usr/share/zoneinfo ディレクトリに保存されているデータファイルが指定されたものと解釈します.
例えば,アメリカのニューヨークのタイムゾーンは,
":/usr/share/zoneinfo/America/New_York"
または
":America/New_York"
と指定します.
なお,タイムゾーンのデータファイルであれば path には何でも(例えば,シンボリックリンクでも)指定できます.
▹実行例
guile> (define ctm (current-time)) guile> (localtime ctm) $1 = #(58 11 22 23 1 122 3 53 0 -32400 "JST") guile> (localtime ctm ":Asia/Tokyo") $2 = #(58 11 22 23 1 122 3 53 0 -32400 "JST") guile> (localtime ctm ":America/New_York") $3 = #(58 11 8 23 1 122 3 53 0 18000 "EST") guile> (localtime ctm ":/etc/localtime") $4 = #(58 11 22 23 1 122 3 53 0 -32400 "JST") guile>最後の実行例は, システム標準のタイムゾーンのデータファイル(/etc/localtime)を指定しています. ちなみに,/etc/localtime は /usr/share/zoneinfo/Asia/Tokyo へのシンボリックリンクです. ▹(記録) タイムゾーンの文字列について,Guileのマニュアル[Guile:7.2.5 Time] は [glibc:21.5.6 Specifying the Time Zone with TZ] を参照せよ,と述べています.glibcのマニュアルは,おおよそ次のことを述べています.
- 文字列の指定形式は3種類あります.上で述べた形式(コロンから始まる文字列形式)はそのうちの1つで,glibc では the most common format だそうです. ちなみに,他の2つの形式は more cumbersome and less precise とのことです.
- [POSIX: 8.3 Other Environment Variables,TZ] は,他の2つの形式を詳細に定義していて,コロンのあとに文字列を指定する形式の解釈は実装依存としています. 従って,上で述べた形式の解釈,すなわちコロンのうしろにタイムゾーンのデータファイル名を指定するという解釈は,glibc に固有の方式として理解しておいたほうがよいでしょう.
- タイムゾーンのデータファイルは, 通常,Time Zone Database に基づいて作成されているとのことです.
成分別時刻から経過時間への逆変換
▹(mktime sbd-time)(mktime sbd-time zone) 成分別時刻と同じ形式のベクタ sbd-time を, 「エポック(970-01-01 00:00:00 UTC)からの経過時間(秒数)」と 「正規化された成分別時刻」のペアに変換して返します. 別の言い方をすると(あくまで意味論的に言い換えると), sbd-time をエポックからの経過時間に変換して, その経過時間に localtime を適用することによって成分別時刻を求めて, それらをペアにして返すと言うことができます. タイムゾーン zone を指定した場合,sbd-time と正規化された成分別時刻をそのタイムゾーンの時刻として処理します.zone を省略した場合,TZ 環境変数かまたはシステム標準のタイムゾーン(/etc/localtime)を使用します. なお,zoneの指定方法については localtime の説明を参照して下さい. 正規化された成分別時刻とは,各成分に対する常識的な条件(例えば,秒や分は0以上59以下の整数であり,時は0以上23以下の整数であるといった条件)を満たす成分別時刻のことです.sbd-time は成分別時刻のベクタと同じ形式をしていれば,正規化されている必要はありません.例えば,秒の成分として -120 や 120 といった値を指定することができます.このような場合,mktime は秒の成分を0に変更して,代わりに分の成分から2を引いたり加えたりして,成分別時刻を正規化します. ▹実行例
guile> (current-time) $1 = 1645652617 guile> (localtime $1) $2 = #(37 43 6 24 1 122 4 54 0 -32400 "JST") guile> (mktime $2) $3 = (1645652617 . #(37 43 6 24 1 122 4 54 0 -32400 "JST")) guile> (mktime #(-120 43 6 24 1 122 4 54 0 -32400 "JST")) $4 = (1645652460 . #(0 41 6 24 1 122 4 54 0 -32400 "JST")) guile> (mktime #(120 43 6 24 1 122 4 54 0 -32400 "JST")) $5 = (1645652700 . #(0 45 6 24 1 122 4 54 0 -32400 "JST")) guile>current-time によって現在時刻($1)を取得して, それを localtime によって成分別時刻($2)に変換して, それに mktime を適用して現在時刻と成分別時刻のペア($3)を作っています. 4番目の実行例は,成分別時刻の第1成分(秒の成分)を負の整数にして mktime を適用しています. その結果($4;正規化された成分別時刻)を見ると, 第1成分は0に変化し,第2成分(分の成分)が43分から41分に変化しています. 5番目の実行例は,第1成分(秒)を120にして mktime を適用しています. その結果($5;正規化された成分別時刻)を見ると, 第1成分は0に変化し,第2成分(分の成分)が43分から45分に変化しています.
時刻成分の抽出
gmtime 手続きや localtime 手続きによって得た成分別時刻から各成分を抽出するために, 以下に示すような手続きが用意されています.以下の tm は成分別時刻を表すベクタです. ▹(tm:sec tm)秒(0〜59)を返します. ▹(tm:min tm)
分(0〜59)を返します. ▹(tm:hour tm)
時(0〜23)を返します. ▹(tm:mday tm)
月内の日付(1〜31)を返します. ▹(tm:mon tm)
月(0〜11)を返します.これは,月の数から1を引いた値を表します. ▹(tm:year tm)
年(西暦年から1900を引いた値)を返します. ▹(tm:wday tm)
曜日を返します.これは0〜6の整数で,0から順に日曜,月曜,... を表します. ▹(tm:yday tm)
年内の通算日(0〜365)を返します. ▹(tm:isdst tm)
夏時間が有効か否かのフラグ(整数)を返します.0は無効,正整数は有効,負の整数は不明を表します. ▹(tm:gmtoff tm)
UTCからの時差(zone time offset)の秒数(-46800〜43200)を返します. 一般的には,時差の値は,UTCの基準点から見て東方向を正の値(+1〜+12), 西方向を負の値(-12〜-1)にするようです(east of UTC). でも,Guileの成分別時刻における時差(この手続きの返り値)は, 西方向を正の値,東方向を負の値としています(west of UTC). 例えば,日本(Asia/Tokyo)の zone time offset は, 一般的には+9時間(日本のほうが9時間進んでいる)ですが, この手続きの返り値は -32400 秒(-9時間)です. ▹(tm:zone tm)
タイムゾーンを表す記号(文字列)を返します. ▹実行例
guile> (localtime (current-time)) $1 = #(49 5 7 24 1 122 4 54 0 -32400 "JST") guile> (tm:sec $1) $2 = 49 guile> (tm:min $1) $3 = 5 guile> (tm:hour $1) $4 = 7 guile> (tm:mday $1) $5 = 24 guile> (tm:mon $1) $6 = 1 guile> (tm:year $1) $7 = 122 guile> (tm:wday $1) $8 = 4 guile> (tm:yday $1) $9 = 54 guile> (tm:isdst $1) $10 = 0 guile> (tm:gmtoff $1) $11 = -32400 guile> (tm:zone $1) $12 = "JST" guile>
成分別時刻の書式整形
整形文字列への変換
▹(strftime format tm)成分別時刻 tm を format で指定された書式に沿って整形した文字列を返します.format は書式を指定した文字列です. 簡単な実行例を示します.書式指定文字列については後述する説明を参照して下さい.
guile> (define tm (localtime (current-time))) guile> tm $1 = #(16 50 12 24 1 122 4 54 0 -32400 "JST") guile> (strftime "%F" tm) $2 = "2022-02-24" guile> (strftime "%F %T" tm) $3 = "2022-02-24 12:50:16" guile> (strftime "%c" tm) $4 = "2022年02月24日 12時50分16秒" guile> (strftime "%Ec" tm) $5 = "令和04年02月24日 12時50分16秒" guile> (strftime "%EC%_Ey年%_m月%e日 %l時%_M分%_S秒" tm) $6 = "令和04年 2月24日 12時50分16秒" guile>最後の実行例は, 年月日などの各数字列を空白を付加して表示するような書式を指定しています. 残念ながら,和暦の年(Ey)には空白の詰め込み(下線 _)は機能しないようです. ロケールに依存する変換については,変換処理がライブラリ関数とは独立している可能性があるので,glibc-修正子は機能しないのかも知れません. ▹(記録) この手続きは,Gnulibが提供する nstrftime 関数を使って実現しています. 残念ながら, そのマニュアルは見当たりません(少なくとも筆者には見つけることができません).Gnulibのサイトと見ると,「The manual is still minimal and sketchy」とあるので,nstrftime のマニュアルはないのかも知れません.ソースコードは公開されているので,それを読めば詳しいことを知ることができるでしょう.
書式指定
▹書式指定文字列(上記の format)は, 変換指定と通常の文字から構成された文字列です. 変換指定(conversion specification)は, もっとも一般的には,次のような形式をしています.
%[glibc-修正子][幅][ロケール修正子]変換指定子
ここで,角括弧は省略可能であることを示しています.例えば,
"%_10S"
という書式指定は,glibc-修正子の下線(_)と,幅の 10 と,変換指定子の S からなり,それぞれ,
数字以外の部分は空白を詰め込むこと,半角10文字分の幅で表示すること,秒数を表示することを示しています.
上記の形式を見ても分かるように,省略不可の変換指定子が基本的な書式整形を行います.各修正子や幅はその結果を修正するためのものです.そこで,まず変換指定子について説明して,そのあとで各修正子と幅について説明します.
▹
変換指定子(conversion specifier)は,
成分別時刻から各成分を適当な書式で表示したり,
複数の成分を合成して表示するためのもので,以下に示す文字を指定します.
なお,変換指定子は,おおまかに,
ロケール非依存のものとロケール依存のものに分類できるので,
以下ではその分類に沿って示しています.
また,E から始まる2文字のものは,
分かりやすさを意図して,変換指定子にロケール修正子を付加したものを示しています.文字 E がロケール修正子で,それに続く文字(C, Y, yなど)が変換指定子です.
・単一の時刻成分を抽出する変換指定子(ロケール非依存).
変換指定子 | 意味 |
---|---|
C | 西暦年の上2桁(世紀から1を引いた値).「19」や「20」など. |
Y | 西暦年(4桁).「2022」年など.紀元以前の年は0や負数で表示される. |
y | 西暦年の下2桁.「00」〜「99」.1桁の場合,0を付加する. |
G,g | 西暦年(The ISO 8601 week-based year).Y や y とほぼ同じです. 年末・年始のぎりぎりの日時を処理したときに違いが生じます. 後述する V 変換指定子のところで説明する週番号(ISO週番号)に応じて年を決めます.例えば,大晦日の適当な時刻を処理した際に,大晦日を含む週がISO週番号では翌年の最初の週だったとき,G や g 変換指定子の結果は翌年になります.逆の場合(年始の日時を処理したときに,その結果が前年になる場合)もあります.これをどういった場面で使うのかは不明です, |
m | 月.「01」〜「12」.1桁の場合,0を付加する. |
d | 日(月内の通算日).「01」〜「31」.1桁の場合,0を付加する. |
e | 日(月内の通算日).「 1」〜「31」.1桁の場合,空白を付加する. |
j | 日(年内の通算日).「001」〜「366」.3桁未満の場合,0を付加する. |
H | 時(24時間表記).「00」〜「23」.1桁の場合,0を付加する. |
k | 時(24時間表記).「 0」〜「23」.1桁の場合,空白を付加する. |
I | 時(12時間表記).「01」〜「12」.1桁の場合,0を付加する. |
l | 時(12時間表記).「 1」〜「12」.1桁の場合,空白を付加する. |
M | 分.「00」〜「59」.1桁の場合,0を付加する. |
S | 秒.「00」〜「60」(注:60は閏秒を含むとき).1桁の場合,0を付加する. |
s | 秒.エポック(1970-01-01 00:00:00 UTC)からの秒数. |
u | 曜日の番号.「1」〜「7」.月曜日を1とする. |
w | 曜日の番号.「0」〜「6」.月曜日を0とする. |
U | 週の番号(年内の通算番号).その年の最初の日曜日を含む週を0番とする. 「00」〜「53」.1桁の場合,0を付加する. |
V | 週の番号(ISO 8601 が定める週番号).新たな年の日を4日以上含む最初の週(つまり,1月4日を含む週)を0番とする.「01」〜「53」.1桁の場合,0を付加する. |
W | 週の番号(年内の通算番号).その年の最初の月曜日を含む週を0番とする. 「00」〜「53」.1桁の場合,0を付加する. |
z |
・RFC 822/ISO 8601:1988 style numeric time zone.Asia/Tokyoの場合,「+0900」. ・gmtime や localtime によって得られるタイムゾーンは west of UTC(UTCの基準点から見て西回りは正,東回りは負)の値ですが, ここでは east of UTC(東周りは正,西回りは負)の値になるようです.まぎらわしい. |
Z | タイムゾーンの省略名.Asia/Tokyoの場合,「JST」. |
変換指定子 | 意味 |
---|---|
D | "%m/%d/%y"(月/日/年)と等価.年は2桁. |
F | "%Y-%m-%d"(年-月-日)と等価.年は4桁. |
R | 時刻(24時間表記)."%H:%M"(時:分)と等価.秒は表示しない.「13:08」など. |
T | 時刻(24時間表記)."%H:%M:%S"(時:分:秒)と等価.「13:08:14」など. |
変換指定子 | 意味 |
---|---|
EC | 和暦の元号(ja_JPロケールの場合).「令和」など. |
EY | 和暦の年(ja_JPロケールの場合).「令和04年」など. |
Ey | 和暦の年の数字部分(ja_JPロケールの場合).「04」など. |
b | 月の省略名.ja_JPロケールの場合,「 1月」〜「12月」.1桁の場合,空白を付加する. |
h | 上記の b と等価. |
B | 月の完全な名前.ja_JPロケールの場合,「1月」〜「12月」.1桁の場合,空白を付加しない. |
a | 曜日の省略名.ja_JPロケールの場合,「日」曜日〜「土」曜日. |
A | 曜日の完全な名前.ja_JPロケールの場合,「日曜日」〜「土曜日」. |
p,P | 午前・午後の表示.ja_JPロケールの場合,p と P に違いはなく,「午前」と「午後」.ちなみに,ja_JP以外のロケールの場合,pは大文字(AM,PMなど)で表示し,Pは小文字(am,pmなど)で表示するらしい. |
c | 日付と時刻の表示.年を西暦で表示する.ja_JPロケールの場合,「2022年02月23日 13時08分14秒」など. |
Ec | 日付と時刻の表示.ja_JPロケールの場合,年を和暦で表示する.「令和04年02月23日 13時08分14秒」など. |
x | 日付の表示(時刻を含まない).年を西暦で表示する.ja_JPロケールの場合,「2022年02月23日」など. |
Ex | 日付の表示(時刻を含まない).ja_JPロケールの場合,年を和暦で表示する.「令和04年02月23日」など. |
r | 時刻の表示.ja_JPロケールの場合,「午前」・「午後」を含む12時間形式.「午後01時08分14秒」など. |
X | 時刻の表示.24時間形式.ja_JPロケールの場合,「13時08分14秒」など. |
変換指定子 | 意味 |
---|---|
n | 改行する. |
t | タブ文字. |
% | パーセント記号(%)を表示する. |
ロケール修正子 | 意味 |
---|---|
E |
・EC(元号) や EY(和暦の年)のように,
ロケールに依存した別書式があるときに,
その別書式を使って表示します. ・この修正子は,変換指定子の c, C, x, X, y, Y に対して適用できます. その他の変換指定子に適用した場合(例えば,"%Em"などと指定した場合),その動作は不明です(一般的には,単なる文字列として処理されるようです). ・単独では使用できません."%E"のように単独で指定すると, 単なる文字列として処理されるようです. |
O |
・ロケールに応じた数字表記がある場合,数字をその数字表記に変換します.
ja_JPロケールの場合,漢数字に変換します.
例えば,「53」を「五十三」に変換します. ・この修正子は,変換指定子の C, y, m, d, e, j, H, k, I, l, M, S, u, w, U, V, W, g に対して適用できます.別の言い方をすると,Y(4桁の西暦年)とs(エポックからの秒数)を除く,数字列を結果とする変換指定子に適用できます. その他の変換指定子に適用した場合(例えば,"%OY"や"%OD"などと指定した場合),その動作は不明です(一般的には,単なる文字列として処理されるようです). ・単独では使用できません."%O"のように単独で指定すると, 単なる文字列として処理されるようです. |
glibc-修正子 | 意味 |
---|---|
_(下線) |
・数字列を結果とする変換指定子に適用した場合,
数字以外の部分に空白を詰め込みます. ・変換指定子がその結果に0を詰め込む場合であっても,その0も空白に変更してしまいます. 例えば,"%_S"(空白付加&秒数)を指定した場合,1桁の秒数は本来ならば0が詰め込まれますが,下線(_)によってその0は空白に変更されてしまいます.例えば, 「00」秒や「01」秒は「 0」秒や「 1」秒のように表示されます. ・常識的には,年内の通算日(j)や秒(S)などの0付加の変換指定子しかないものに適用して使うものだと思います. ・数字列以外を結果とする変換指定子に指定した場合, その動作は不明です. |
-(ダッシュ) |
・数字列を結果とする変換指定子に適用した場合,
数字以外の部分には何も詰めずに短縮します. ・0付加の変換指定子が詰め込む0も短縮してしまいます.例えば,"%-S"(短縮&秒数)を指定した場合,1桁の秒数は本来ならば0が詰め込まれますが,ダッシュ(-)によってその0は短縮されてしまいます.例えば, 「00」秒や「01」秒は「0」秒や「1」秒のように表示されます. ・数字列以外を結果とする変換指定子に指定した場合, その動作は不明です. |
0 |
・数字列を結果とする変換指定子に適用した場合,
結果としての数字(有効な数字とでも言える部分)以外の部分に 0 を詰め込みます. ・空白付加の変換指定子が詰め込む空白も0に変更してしまいます. ただ,数字列だけを結果とする空白付加の変換指定子については, それに対応する0付加の変換指定子があるので, これを使用することがあるのかどうかやや不明です. 1つの可能性としては,幅を指定した場合に,結果以外の部分に0を詰め込みたいときに使う,といったことが考えられます. ・数字列以外を結果とする変換指定子に指定した場合, その動作は不明です. |
^(ハット) |
・変換指定子の結果に含まれるアルファベット文字を大文字にします.
・ja_JPロケールでは,変換指定子の Z に対してのみ機能します. その他の変換指定子に適用しても無視されるようです(アルファベット文字を含まないので). |
# |
・変換指定子の結果に含まれるアルファベットの大文字と小文字を交換します. ・なお,これは[Manpage:STRFTIME(3)] には(glibcの拡張機能として)説明がありますが,[glibc:21.5.4 Formatting Calendar Time] には説明がありません. ・guileでは機能するようです. ・ja_JPロケールでは,変換指定子の Z に対してのみ機能します. その他の変換指定子に適用しても無視されるようです(アルファベット文字を含まないので). |
整形文字列から成分別時刻への逆変換
▹以下では, 整形文字列への変換・逆変換の手続きの説明と合わせて, せっかくの機会なので,書式指定についても記録しておきます.逆変換の手続き
▹(strptime format str)strftime 手続きと逆の変換を行います. つまり,format で指定された書式に沿って 文字列 str を解析して,成分別時刻に変換します. ただし,変換後の成分別時刻と str の中で変換に使用した文字の個数のペアを返します.
逆変換の書式指定
▹srtftime 手続きとほとんど同じ変換指定子を利用できます. 次の点が異なります.- glib-修正子 の下線(_),ダッシュ(-),ハット(^)は使えません.0は使えます.
- %n と %t は「Matches any white space」だそうです(これを素直に信じるならば,改行やタブ文字にマッチするのではないことになります).
- %Z については, 「Note: Currently, this is not fully implemented. The format is recognized, input is consumed but no field in tm is set. 」とのことです.
guile> (strptime "%Ec %z %Z" "令和04年02月24日 12時52分10秒 +0900 JST") $1 = (#(10 52 12 24 1 122 4 54 -1 -32400 #f) . 27) guile>書式指定 %z と文字列中の +0900 はタイムゾーンの時差を設定しています. 残念ながら,夏時間の有効・無効のフラグ(上記の -1)は設定できません. 上記の -1 はstrptime が勝手に設定したものです.それから, 上で述べたように,%Z を使ってタイムゾーンの略称(JST)を設定しようとしても無視されます.