最近、本番環境で奇妙なエラーが発生し始めました(テスト環境は正常に機能します)。
Java.lang.IllegalArgumentException:不正なパターン文字 'y'
これは次のコードが原因です
_SimpleDateFormat dateFormat = (SimpleDateFormat)DateFormat.getDateInstance();
dateFormat.applyLocalizedPattern("yyyy-MM-dd");
_
このエラーは通常、たとえば年に「y」の代わりに「Y」を使用した場合にスローされます。上記のように、これはここでは当てはまりません。サーバーに設定されているロケールが100%わからない。 Linux env LANGは「de_DE.UTF_8」に設定されているため、おそらくこれが使用されます。
SimpleDateFormat.Javaのソースコードを入力すると、メソッドtranslatePattern(String pattern, String from, String to)
が見つかりました。これは、pattern
の文字がfromに存在しない場合に言及された例外をスローします。別のコンピューターでローカルにデバッグする場合、値は次のようになります。
パターン= "yyyy-MM-dd"
from = "GyMdkHmsSEDFwWahKzZ"
サーバーの例外から、最初の「y」がfrom
に存在しないことは明らかです。 from
はformatData.getLocalPatternChars()
からフェッチされます。これは、サーバー上のロケールから初期化されたDateFormatSymbols
です。
'y'のないフォーマットを持つことができる利用可能なロケールさえありますか?このエラーはコードを変更せずに発生し始めました。私の知る限り、サーバー構成は変更されていません。
SimpleDateFormat javadocから:
SimpleDateFormatは、ローカライズされた日付と時刻のパターン文字列もサポートします。これらの文字列では、上記のパターン文字を他のロケール依存のパターン文字に置き換えることができます。
あなたの場合、ローカルはDEであるため、ローカライズされたパターンはjjjj-MM-tt
になります。 J
はJahrを表し、T
はTageを表します。
ローカライズされたパターンを処理したくない場合は、 SimpleDateFormat.applyPattern( "yyyy-MM-dd") を使用してください。
理想的には、パターンのロケールを適用する必要があります。そうしないと、yyyyはen_USで、jjjjはde_DEなどで機能するため、パターンをロケールごとに変更する必要があります。代わりに、マシンのロケールに関係なく、yyyyとlocaleのみをen_USとして指定します。
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
System.out.println(format.format(new Java.util.Date()));
Javadocが言うように:
指定されたパターンと指定されたロケールのデフォルトの日付形式記号を使用してSimpleDateFormatを構築します。注:このコンストラクターは、すべてのロケールをサポートしているわけではありません。完全にカバーするには、DateFormatクラスのファクトリメソッドを使用します。
パラメーター:
パターン:日付と時刻の形式を説明するパターン
ロケール:日付形式の記号を使用するロケール
このようにして、ランタイムロケールに選択するローカル文字列を気にする必要がなく、特定のロケールを一度適用する必要がありません。