Jon Skeetの答えは正解であり、2013年に書かれたときは良い答えでした。
ただし、質問で使用するクラスSimpleDateFormat
はDate
現在古くなっているため、今日誰かが同様の問題を抱えている場合、IMHOの最善の答えは、最新のJava date& timeAPIを使用するように変更することです。
申し訳ありませんが、Scalaコードを記述できないため、Javaを使用する必要があります。使ってます
private static DateTimeFormatter parseFormatter
= DateTimeFormatter.ofPattern("MM/dd/yyyy");
フォーマットパターンの文字は質問と同じですが、意味は少し異なります。DateTimeFormatter
後で説明するように、文字通りパターン文字の数を取ります。今、私たちは試してみます:
System.out.println(LocalDate.parse(date, parseFormatter));
結果:
"03/11/2013"
期待どおりに解析さ2013-03-11
れます。私は現代のLocalDate
クラスを使用しました。これは、時刻なしで日付を表すクラスであり、まさにここで必要なものです。
- 渡すと、メッセージが表示され
"03/88/2013 hjhkjhk"
ます。かなり正確ですね。ただし、最新のAPIには、文字列の一部のみを解析するメソッドがあります。DateTimeParseException
Text '03/88/2013 hjhkjhk' could not be parsed, unparsed text found at index 10
"03/88/201309"
与えるText '03/88/201309' could not be parsed at index 6
。私たちは4桁の年を求め、それに6桁を与えましたが、これは反対意見につながります。どうやら、88を月の日として解釈しようとする前に、このエラーを検出して報告しているようです。
- ただし、88の月の日にも反対し
"03/88/2013"
ますText '03/88/2013' could not be parsed: Invalid value for DayOfMonth (valid values 1 - 28/31): 88
。繰り返しになりますが、メッセージがいかに有益であるかをお楽しみください。
"03-08-2013"
(スラッシュの代わりにハイフンを使用)はText '03-08-2013' could not be parsed at index 2
、それほど驚くことではありません。インデックス2は、最初のハイフンがどこにあるかです。
Jon Skeetは、時代遅れのSimpleDateFormat
人は寛大な場合もあれば、寛大でない場合もあると説明しました。これは同様に当てはまりますDateTimeFormatter
。実際、「lenient」、「smart」、「strict」と呼ばれる2つのリゾルバースタイルではなく3つのリゾルバースタイルがあります。しかし、多くのプログラマーはこれに気付いていないので、「寛大な」をデフォルトにしないという良い選択をしたと思います(「スマート」はそうです)。
フォーマッターを寛大にしたい場合はどうなりますか?
private static DateTimeFormatter parseFormatter
= DateTimeFormatter.ofPattern("MM/dd/yyyy")
.withResolverStyle(ResolverStyle.LENIENT);
これで、も解析"03/88/2013"
されて。になり2013-05-27
ます。これは古いクラスでも行われていたことだと思います。3月の初めから88日を数えると、5月27日になります。他のエラーメッセージは同じです。言い換えれば、それはまだ解析されていないテキスト、6桁の年、およびハイフンに反対します。
質問:Javaバージョンで最新のAPIを使用できますか?
少なくともJava6を使用している場合は、可能です。
- Java 8以降では、新しいAPIが組み込まれています。
- Java 6および7では、新しいクラスのバックポートであるThreeTenバックポートを取得します(これは、最新のAPIが最初に定義されたJSR-310のThreeTenです)。
- Androidでは、Android版のThreeTenBackportを使用します。これはThreeTenABPと呼ばれ、この質問にはすばらしい説明があると思います。AndroidプロジェクトでThreeTenABPを使用する方法です。