Java:无法从 TemporalAccessor 获取 LocalDate
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45320971/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: Unable to obtain LocalDate from TemporalAccessor
提问by
I am trying to change the format of a String
date from EEEE MMMM d
to MM/d/yyyy
by, first, converting it into a LocalDate
and then applying a formatter of a different pattern to the LocalDate
before parsing it into String
again.
我试图将String
日期的格式从更改EEEE MMMM d
为MM/d/yyyy
by,首先将其转换为 a LocalDate
,然后LocalDate
在String
再次解析之前将不同模式的格式化程序应用于。
Here's my code:
这是我的代码:
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;
}
However, I get this exception message that I don't really understand:
但是,我收到了这个我不太理解的异常消息:
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)
采纳答案by jwenting
As the other answers already said, to create a LocalDate
you need the year, which is not in the input String
. It has only day, monthand day of the week.
正如其他答案已经说过的那样,要创建一个LocalDate
您需要year,它不在 input 中String
。它只有日、月和星期几。
To get the full LocalDate
, you need to parse the dayand monthand find a yearin which this day/monthcombination matches the day of the week.
要获得完整的LocalDate
,你需要解析日和月,并找到一个每年在此日/月组合的匹配星期几。
Of course you could ignore the day of the weekand assume that the date is always in the current year; in this case, the other answers already provided the solution. But if you want to find the yearthat exactly matches the day of the week, you must loop until you find it.
当然,您可以忽略星期几,并假设日期总是在当前年份;在这种情况下,其他答案已经提供了解决方案。但是如果你想找到与星期几完全匹配的年份,你必须循环直到找到它。
I'm also creating a formatter with a java.util.Locale
, to make it explicit that I want monthand day of weeknames in English. If you don't specify a locale, it uses the system's default, and it's not guaranteed to always be English (and it can be changed without notice, even at runtime).
我还创建了一个带有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;
}
}
In this example, I started at year 2017 and tried to find a date until back to 1970, but you can adapt to the values that fits your use cases.
在此示例中,我从 2017 年开始并尝试查找可以追溯到 1970 年的日期,但您可以调整适合您用例的值。
You can also get the current year (instead of some fixed arbitrary value) by using Year.now().getValue()
.
您还可以使用Year.now().getValue()
.
回答by Pallavi Sonal
The documentation for LocalDate
says, that
的文档LocalDate
说,
LocalDate is an immutable date-time object that represents a date, often viewed as year-month-day. For example, the value "2nd October 2007" can be stored in a LocalDate.
LocalDate 是表示日期的不可变日期-时间对象,通常被视为年-月-日。例如,值“2nd October 2007”可以存储在 LocalDate 中。
In your case, the input String
is missing an important component of LocalDate
, i.e the year. What you have basically is month and day. So, you can use a class suited to that MonthDay
. Using that your code can be modified to :
在您的情况下,输入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
回答by KayV
Here is the minor change which you need to implement:
这是您需要实施的小改动:
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;
}
Add the default chronological year in the formatter using
.parseDefaulting(ChronoField.YEAR, 2017)
Call the method using the argument
"Tuesday July 25"
like thisconvertDate("Tuesday July 25");
使用在格式化程序中添加默认的时间顺序年份
.parseDefaulting(ChronoField.YEAR, 2017)
调用使用参数的方法
"Tuesday July 25"
是这样convertDate("Tuesday July 25");
回答by jwenting
Another option is to do the following (just like the other answers a bit hacky), assuming of course you want the date to fall in the current year:
另一种选择是执行以下操作(就像其他答案有点老套),当然假设您希望日期落在当年:
LocalDate localDate = LocalDate.parse(stringDate + " " +LocalDate.now().getYear(), DateTimeFormatter.ofPattern("EEEE MMMM d");