2016-06-20 28 views
6

いくつかのSimpleDateFormatコードを理解しようとしています。特に、私はSimpleDateFormatでローカライズされたパターン文字列を使用しようとしています。 javadocSimpleDateFormatローカライズされたパターンで不正なパターン文字エラー

SimpleDateFormatは、ローカライズされた日付と時刻のパターン文字列もサポートしています。これらの文字列では、上記のパターン文字を他のロケール依存のパターン文字に置き換えることができます。

またSimpleDateFormat(String pattern, DateFormatSymbols formatSymbols)コンストラクタを指定:

は、指定されたパターンと日付フォーマット記号を使ってSimpleDateFormatを構築します。 getLocalPatternChars()インスタンスが期待されるパターン文字を提示しているが

しかし、SimpleDateFormatののコンストラクタは、これらの文字を含むパターンを拒否されています

public void run() { 
    Locale loc = new Locale("de", "de"); 
    DateFormatSymbols dfs = new DateFormatSymbols(loc); 
    String sym = dfs.getLocalPatternChars(); 
    System.out.println(sym); 
    SimpleDateFormat datefmt = new SimpleDateFormat("tt.MM.uuuu", dfs); 
} 

は出力を生成します。

GuMtkHmsSEDFwWahKzZ 
Exception in thread "main" java.lang.IllegalArgumentException: Illegal pattern character 't' 
    at java.text.SimpleDateFormat.compile(SimpleDateFormat.java:845) 
    ... 

私があれば、同じ出力を得ます私は最後の行を "... new SimpleDateFormat("tt.MM.uuuu", loc);"に置き換えます。

一方、Anglicizedパターン文字列を使用してSimpleDateFormatインスタンスを作成し、 "applyLocalizedPattern("tt.MM.uuuu")"を呼び出すと、ローカライズされたパターンが受け入れられます。

したがって、SimpleDateFormatのコンストラクタではローカライズされたパターン文字列を使用できないため、この2段階の初期化が必要です。これは意図的な行動ですか?

+2

コンストラクタは 'translatePattern'(' applyLocalizedPattern')を呼び出さないので、これはバグかコンストラクタの使用法を明確に説明していない悪いJavaDocです。 – Tom

+0

@Tomが正しいです。コンストラクターのpatternパラメーターは、非ローカライズされた日時パターン文字のみを参照します。 –

+0

も参照してくださいhttp://stackoverflow.com/a/24128930/2491410 –

答えて

3

残念ながら、ローカライズされたパターンを処理する方法のドキュメントは恐ろしいです。だから私はソースコードを研究し、私自身の調査をしました。結果:

パターン文字列を受け入れるSimpleDateFormatのコンストラクタは、ローカライズされていないパターン文字のみを参照し、その定義はクラスSimpleDateFormatのjavadocヘッダーに記載されています。これらのローカライズされていないパターン文字もDateTimeFormatSymbolsで定数として定義されています。

/** 
* Unlocalized date-time pattern characters. For example: 'y', 'd', etc. 
* All locales use the same these unlocalized pattern characters. 
*/ 
static final String patternChars = "GyMdkHmsSEDFwWahKzZYuXL"; 

3つのステップは、あなたがドイツ語であると信じるものを「tt.MM.uuuu」などのローカライズされたパターンを(使用するために必要である - しかし、ではありませんドイツ、それはむしろ「TT.MM.JJJJ」でなければなりません - 間違ったJDKリソースの例):

  1. DateFormatSymbols.setLocalPatternChars(...)を経由してローカライズされたパターン文字を定義します。
  2. SimpleDateFormatオブジェクトでカスタマイズした日付形式の記号を使用してください。
  3. その後、ローカライズされたパターンは、内部および公式のパターン文字の定義に変換されますSimpleDateFormat.applyLocalizedPattern(...)

を経由してローカライズされた日付・時間・パターンを適用します。

使用例(ドイツ語の正しいパターンTT.MMを使用します。JJJJ):

SimpleDateFormat sdf = new SimpleDateFormat(); // uses default locale (here for Germany) 
System.out.println(sdf.toPattern()); // dd.MM.yy HH:mm 
System.out.println(sdf.toLocalizedPattern()); // tt.MM.uu HH:mm 

DateFormatSymbols dfs = DateFormatSymbols.getInstance(Locale.GERMANY); 
dfs.setLocalPatternChars("GJMTkHmsSEDFwWahKzZYuXL"); 
sdf.setDateFormatSymbols(dfs); 
sdf.applyLocalizedPattern("TT.MM.JJJJ"); 

System.out.println(sdf.toPattern()); // dd.MM.yyyy 
System.out.println(sdf.toLocalizedPattern()); // TT.MM.JJJJ 
System.out.println(sdf.format(new Date())); // 20.06.2016 

サイドノート:私は、適切なパターンがローカライズされた定義を作るために、文字列「GyMdkHmsSEDFwWahKzZYuXL」でJとTへのyとDの文字が変更されました。

残念ながら、JDKのリソースは明らかに信頼できないため、私の個人的な見解では、機能全体が厄介な方法でしか使用できず、実際にはあまり役に立ちません。

+0

"GyMdkHmsSEDFwWahKzZYuXL"のようなローカライズされた日時パターン文字についてはCLDRデータ内で検索しましたが、まだ見つかりませんでした。したがって、Sun/Oracleがこれらのデータをどのように取得するのかは明らかではありません。それは彼ら自身の推測仕事ですか?おそらく誰かがローカライズされたデータのソースについてもっと知っているでしょうか? –

+0

ああ、古いバージョンのCLDRデータはという要素を知っています。廃止され、もはや埋められなくなりました(CLDR v29)。したがって、JDKは古いデータを使用しているようです。この[ICUチケット](https://sourceforge.net/p/icu/mailman/message/10846249/)も参照してください。 –

関連する問題