String
日付の形式をEEEE MMMM d
からMM/d/yyyy
に変更しようとしています。最初にLocalDate
に変換してから、別のフォーマッターを適用しますLocalDate
を再度解析する前に、String
にパターン化します。
ここに私のコードがあります:
private String convertDate(String stringDate)
{
//from EEEE MMMM d -> MM/dd/yyyy
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ofPattern("EEEE MMMM d"))
.toFormatter();
LocalDate parsedDate = LocalDate.parse(stringDate, formatter);
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/d/yyyy");
String formattedStringDate = parsedDate.format(formatter2);
return formattedStringDate;
}
しかし、私は本当に理解していないこの例外メッセージを受け取ります:
Exception in thread "main" Java.time.format.DateTimeParseException: Text 'TUESDAY JULY 25' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {DayOfWeek=2, MonthOfYear=7, DayOfMonth=25},ISO of type Java.time.format.Parsed
at Java.time.format.DateTimeFormatter.createError(DateTimeFormatter.Java:1920)
他の回答ですでに述べたように、LocalDate
を作成するには、入力String
にないyearが必要です。 day、month、およびdaydayのみがあります。
完全なLocalDate
を取得するには、dayおよびmonthを解析し、yearこのday/monthの組み合わせは、曜日と一致します。
もちろん、曜日を無視して、日付が常に現在の年であると仮定することもできます。この場合、他の回答はすでに解決策を提供しています。しかし、dayと完全に一致するyearを見つけたい場合は、それが見つかるまでループする必要があります。
また、_Java.util.Locale
_を使用してフォーマッタを作成し、monthおよびday of week英語の名前。ロケールを指定しない場合、システムのデフォルトが使用され、常に英語であるとは限りません(実行時にも予告なく変更される可能性があります)。
_DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ofPattern("EEEE MMMM d"))
// use English Locale to correctly parse month and day of week
.toFormatter(Locale.ENGLISH);
// parse input
TemporalAccessor parsed = formatter.parse("TUESDAY JULY 25");
// get month and day
MonthDay md = MonthDay.from(parsed);
// get day of week
DayOfWeek dow = DayOfWeek.from(parsed);
LocalDate date;
// start with some arbitrary year, stop at some arbitrary value
for(int year = 2017; year > 1970; year--) {
// get day and month at the year
date = md.atYear(year);
// check if the day of week is the same
if (date.getDayOfWeek() == dow) {
// found: 'date' is the correct LocalDate
break;
}
}
_
この例では、2017年に開始し、1970年までさかのぼって日付を見つけようとしましたが、ユースケースに適合する値に適応できます。
Year.now().getValue()
を使用して、(固定された任意の値の代わりに)現在の年を取得することもできます。
LocalDate
のドキュメントには、
LocalDateは日付を表す不変の日時オブジェクトであり、多くの場合年月日として表示されます。たとえば、「2007年10月2日」という値はLocalDateに格納できます。
あなたの場合、入力String
にはLocalDate
の重要なコンポーネント、つまり年がありません。基本的には月と日です。そのため、それに適したクラスを使用できます MonthDay
。それを使用して、コードを次のように変更できます。
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ofPattern("EEEE MMMM d"))
.toFormatter();
MonthDay monthDay = MonthDay.parse(stringDate, formatter);
LocalDate parsedDate = monthDay.atYear(2017); // or whatever year you want it at
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/d/yyyy");
String formattedStringDate = parsedDate.format(formatter2);
System.out.println(formattedStringDate); //For "TUESDAY JULY 25" input, it gives the output 07/25/2017
実装する必要がある小さな変更は次のとおりです。
_private static String convertDate(String stringDate)
{
//from EEEE MMMM d -> MM/dd/yyyy
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("EEEE MMMM dd")
.parseDefaulting(ChronoField.YEAR, 2017)
.toFormatter();
LocalDate parsedDate = LocalDate.parse(stringDate, formatter);
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/d/yyyy");
String formattedStringDate = parsedDate.format(formatter2);
return formattedStringDate;
}
_
.parseDefaulting(ChronoField.YEAR, 2017)
を使用して、フォーマッターにデフォルトの年を追加します
次のように引数_"Tuesday July 25"
_を使用してメソッドを呼び出しますconvertDate("Tuesday July 25");
別のオプションは、次のことを行うことです(他の回答と同じように、ちょっとハッキーです)。もちろん、日付を現在の年にしたい場合は:
LocalDate localDate = LocalDate.parse(stringDate + " " +LocalDate.now().getYear(), DateTimeFormatter.ofPattern("EEEE MMMM d");