2011年05月22日

ScalaのStringLike.formatで日付フォーマット

お決まりのyyyymmddに変換する的なコードを書く時に、何を使ってやろうかなぁと少し迷った。

普通にDateFormatでやっても良いのだけど、StringLikeのformatを使った方が短くて良い気もした。ちとフォーマット文字列が読みづらいのと、パースする方では使えないのがアレだけど。



formatはこんなふうに使う、Cのprintfみたいな機能。
scala> "%d-%d-%d" format (2011, 5, 21)
String = 2011-5-21

1つの「%d」に対して、1つの変数を指定するのが基本。但し「%<d」のように「<」を加えると1つの変数を使いまわせる。
scala> "%d-%<d-%<d" format (12)
String = 12-12-12

これには日付フォーマット用の機能も用意されている。

利用できるフォーマット文字列は、java.util.Formatterを参照。
http://java.sun.com/javase/ja/6/docs/ja/api/java/util/Formatter.html

まずは今日日付を、yyyymmdd形式の文字列で取得してみる。%tYが年、%tmが月、%tdが日。
scala> import java.util.Date
scala> "%tY%<tm%<td" format new Date
String = 20110521

スラッシュ付きのyyyy/mm/dd形式にする。
scala> import java.util.Date
scala> "%tY/%<tm/%<td" format new Date
String = 2011/05/21

%tFを指定するとyyyy-mm-dd形式。短く書けて便利。
scala> "%tF" format new Date
String = 2011-05-21

yyyy/mm/dd hh:mm:ss形式の文字列で取得する。%tHが時、%tMが分、%tSが秒。
scala> "%tY/%<tm/%<td %<tH:%<tM:%<tS" format new Date
String = 2011/05/21 00:55:35

hh:mmは%tRとも書けるので、yyyy/mm/dd hh:mmはこう書く方が短くて済む。
scala> "%tY/%<tm/%<td %<tR" format new Date
String = 2011/05/21 00:56

hh:mm:ssは%tTとも書けるので、yyyy-mm-dd hh:mm:ssならこんな感じで短く書ける。
scala> "%tF %<tT" format new Date
String = 2011-05-22 01:19:08

%tDを使うと、mm/dd/yyになる。日本ではあまり使わない形式なので残念。
scala> "%tD" format new Date
String = 05/22/11

%tcも日本人的にはあまり使わない形式。
scala> "%tc" formatLocal( Locale.US, new Date )
String = Sun May 22 02:09:30 JST 2011

0埋めしたくない場合は、%teが日、%tkが時らしいのだけど、月と秒はどれだろう。見当たらない。
scala> "%te日 %<tk時" format new Date
String = 3日 1時

張り切ってミリ秒まで出してみる。%tLがミリ秒。
scala> "%tF %<tT.%<tL" format new Date
String = 2011-05-22 01:41:24.703

さらに張り切ってナノ秒まで取ろうとしたけど、うまく取れなかった。なんでだろう。とりあえず%tNがナノ秒のはず。
scala> "%tF %<tT.%<tN" format new Date
String = 2011-05-22 01:42:41.697000000

午前○時とか言ってみる。午前/午後は%tp。出力される文字はLocaleによって変わる。
scala> "%tp%<tl時%<tM分" format new Date
String = 午前1時44分

LocaleをUSにして%tpを出すと、AM/PMが出力される。Localeを指定したい場合は、formatLocalを使う。
scala> import java.util.Locale
scala> "%tp %<tl:%<tM" formatLocal (Locale.US, new Date)
String = am 1:46

曜日まで出してみる。%taが曜日の省略形。
scala> "%tY/%<tm/%<td(%<ta)" format new Date
String = 2011/05/21(土)

LocaleがUSの場合は、こんな曜日。
scala> "%tY/%<tm/%<td(%<ta)" formatLocal( Locale.US, new Date )
String = 2011/05/22(Sun)

%tAは曜日の完全形。「日曜日」とか出たりします。
scala> "%tY/%<tm/%<td(%<tA)" format new Date
String = 2011/05/22(日曜日)

%tAのUS版。余談だけど、Locale絡む子はテスト漏れしやすいから使う時少し怖い印象がある。
scala> "%tY/%<tm/%<td(%<tA)" formatLocal( Locale.US, new Date )
String = 2011/05/22(Sunday)

%tBは月の短縮版。こんな風に「5月」とか出されても日本人的には使い辛い。
scala> "%tB" format new Date
String = 5月

%tBのアメリカ語版。向こうでは風習的にこれをよく使うのだろうな。%tBにすると月が省略されずに出ます。Mayだと変わらないけど。
scala> "%tB" formatLocal( Locale.US, new Date )
String = May

%tZはタイムゾーンを表す文字列。%tzはタイムゾーンのオフセット。
scala> "%tZ %<tz" format new Date
String = JST +0900

RFC2822だと多分こんな感じ(未検証)。TimeZoneとかはさすがに設定できないっぽい。
scala> "%ta, %<td %<tb %<tY %<tT %<tz" formatLocal( Locale.ENGLISH, new Date )
String = Mon, 23 May 2011 22:49:28 +0900