みなさんご存じのとおり、 Android API と Java API は微妙に違います。
java.text.SimpleDateFormat
も、違っているものの1つです。
タームゾーンや曜日などを指定するパターンが違います。
使えるパターンを使わないと例外が発生します。
Java6とJava7との間にも違いがあるので、抽出しておきました。*
|項目名|Java6|Java7|Android API**/***|
|:---|:---|:---|:---|:---|:---|
|タイムゾーン(-0800)(RFC 822)|Z|Z|Z, ZZ, ZZZ|
|タイムゾーン(-08, -0800, -08:00)(ISO 8601)|なし|X|ZZZZZ****|
|タイムゾーン(上記以外色々まとめて)|z|z|z, zz, zzz, zzzz, ZZZZ|
|曜日の番号(1 = 月曜、...、7 = 日曜)|なし|u|なし|
|曜日の名前(Tuesday)|E|E|EEEE|
|曜日の名前(Tue)|E|E|E, EE, EEE|
|曜日の名前(T)|なし|なし|EEEEE|
|月の名前(January)|M|M|MMMM|
|月の名前(Jan)|M|M|MMM|
|月の名前(J)|なし|なし|MMMMM|
|年(2015)|y|y|y, yyy, yyyy|
|年(15)|y|y|yy|
|暦週の基準年***** (2015, 15)|なし|Y|なし|
* ちなみにJava8ではjava.timeパッケージが追加されて日時の計算とか夏時間とかを扱うのが便利らしいので、ZonedDateTimeやLocalDateTimeのparseメソッドにDateTimeFormatterを渡すことになって、SimpleDateFormat
は徐々に使われなくなるかもしれません
** Android API level 9 以上にはL
やc
というパターンが導入されています。たとえばロシア語のように、「N月M日」という日付が続いている場合の「N月」と、「N月」だけで独立して書かれる「N月」で表記が異なる言語への対応のためだそうです。L
は月、c
は曜日です
*** Android API level 18 以上にはMMMMM
というように同じ文字が5文字連続しているパターンが導入されたそうです。逆に言えばAPI level 18 未満ではそれらは使えなさそうです
**** ZZZZZ
では厳密にはISO8601のすべてのパターンには対応していない模様です。たとえばタイムゾーンがプラスマイナス0、つまりUTCのときは2015-01-02 03:04:05Z
というようにタイムゾーンとしてZ
が末尾につくことになりますが、これをパースすることができません
***** 「暦週の基準年」についての説明はここ(たぶん一生使わないだろうな……)
- Java6 のSimpleDateFormatのjavadocはここ
- Java7 のSimpleDateFormatのjavadocはここ
- Android のSimpleDateFormatのjavadocはここ
です
上記の違いのせいで、Java API を参考にAndroidアプリを実装すると、パースに失敗することがあります。