我正在尝试将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)
答案 0 :(得分:8)
LocalDate
的文档说明了
LocalDate是一个表示日期的不可变日期时间对象, 通常被视为年月日。例如,值" 10月2日 2007"可以存储在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
答案 1 :(得分:2)
以下是您需要实施的细微更改:
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");
答案 2 :(得分:2)
正如其他答案已经说过,要创建LocalDate
,您需要年,这不在输入String
中。它只有天,月和星期几。
要获得完整的LocalDate
,您需要解析天和月并找到年,其中< strong>日/月组合与星期几匹配。
当然,您可以忽略星期几,并假设日期始终位于当前年;在这种情况下,其他答案已经提供了解决方案。但是,如果您想找到与一周完全匹配的年,则必须循环直至找到它。
我还创建了一个带有java.util.Locale
的格式化程序,以明确表示我希望月和星期几的英文名称。如果您没有指定区域设置,它将使用系统的默认设置,并且不保证始终为英语(即使在运行时也可以在不事先通知的情况下进行更改)。
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()
获取当前年份(而不是某些固定的任意值)。
答案 3 :(得分:0)
另一个选择是执行以下操作(就像其他答案有点hacky),假设您当然希望日期在当前年份下降:
LocalDate localDate = LocalDate.parse(stringDate + " " +LocalDate.now().getYear(), DateTimeFormatter.ofPattern("EEEE MMMM d");