web-dev-qa-db-ja.com

java dateformat不正なパターン文字 'y'

最近、本番環境で奇妙なエラーが発生し始めました(テスト環境は正常に機能します)。

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に存在しないことは明らかです。 fromformatData.getLocalPatternChars()からフェッチされます。これは、サーバー上のロケールから初期化されたDateFormatSymbolsです。

'y'のないフォーマットを持つことができる利用可能なロケールさえありますか?このエラーはコードを変更せずに発生し始めました。私の知る限り、サーバー構成は変更されていません。

13
Rasmus Franke

SimpleDateFormat javadocから:

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

あなたの場合、ローカルはDEであるため、ローカライズされたパターンはjjjj-MM-ttになります。 JはJahrを表し、TはTageを表します。

ローカライズされたパターンを処理したくない場合は、 SimpleDateFormat.applyPattern( "yyyy-MM-dd") を使用してください。

11
obourgain

理想的には、パターンのロケールを適用する必要があります。そうしないと、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クラスのファクトリメソッドを使用します。

パラメーター:

パターン:日付と時刻の形式を説明するパターン

ロケール:日付形式の記号を使用するロケール

このようにして、ランタイムロケールに選択するローカル文字列を気にする必要がなく、特定のロケールを一度適用する必要がありません。

8
harsh