0xb*_*7ed 12 java datetime parsing date java-8
我有一个简单的问题:我想"yyyyMMdd"严格地解析格式化的Java字符串,因此这"19800229"是一个有效的日期,但事实"19820229"并非如此.假设这些是正常公历的AD日期.
我正在尝试使用java.timeJDK 8中的新软件包来解决这个问题,但事实证明它比希望的更复杂.我目前的代码是:
private static final DateTimeFormatter FORMAT = DateTimeFormatter
.ofPattern("yyyyMMdd").withChronology(IsoChronology.INSTANCE)
.withResolverStyle(STRICT);
public static LocalDate parse(String yyyyMMdd) {
return LocalDate.parse(yyyyMMdd, FORMAT);
}
Run Code Online (Sandbox Code Playgroud)
但是,解析诸如"19800228"之类的有效日期对我来说产生了一个难以理解的错误:
java.time.format.DateTimeParseException:无法解析文本'19820228':无法从TemporalAccessor获取LocalDate:{MonthOfYear = 2,DayOfMonth = 28,YearOfEra = 1982},ISO类型为java.time.format.Parsed
我如何使用java.time.format.DateTimeFormatter来解决我的简单用例?
Jan*_*tis 21
Java 8 uuuu用于年份,而不是yyyy.在Java 8中,yyyy意思是"年代"(BC或AD),并且错误消息抱怨MonthOfYear,DayOfMonth和YearOfEra不足以构建日期,因为时代未知.
要解决这个问题,请使用uuuu格式字符串,例如DateTimeFormatter.ofPattern("uuuuMMdd")
或者,如果您想继续使用yyyy,可以设置默认时代,例如
private static final DateTimeFormatter FORMAT = new DateTimeFormatterBuilder()
.appendPattern("yyyyMMdd")
.parseDefaulting(ChronoField.ERA, 1 /* era is AD */)
.toFormatter()
.withChronology(IsoChronology.INSTANCE)
.withResolverStyle(ResolverStyle.STRICT);
Run Code Online (Sandbox Code Playgroud)
我正在编辑以通过使用使用 DateTimeFormatterBuilder 创建的自定义格式化程序来限制哪种类型的字符串将被视为有效。
public class DateFormmaterTest {
static DateTimeFormatter CUSTOM_BASIC_ISO_DATE = new DateTimeFormatterBuilder()
.parseCaseInsensitive().appendValue(YEAR, 4)
.appendValue(MONTH_OF_YEAR, 2).appendValue(DAY_OF_MONTH, 2)
.optionalStart().toFormatter()
.withResolverStyle(ResolverStyle.STRICT)
.withChronology(IsoChronology.INSTANCE);
public static void main(String[] args) {
LocalDate date1 = LocalDate.parse("19800228-5000",
CUSTOM_BASIC_ISO_DATE);
System.out.println(date1);
}
}
Run Code Online (Sandbox Code Playgroud)
2/29/1982 无效,会抛出以下错误:
Caused by: java.time.DateTimeException: Invalid date 'February 29' as '1982' is not a leap year
at java.time.LocalDate.create(LocalDate.java:429)
Run Code Online (Sandbox Code Playgroud)
日期 19800228-5000 将与 BASIC_ISO_DATE 一起使用,因为它允许您不希望允许的可选偏移量。我的 CUSTOM_BASIC_ISO_DATE 格式化程序不允许这样做并抛出以下内容:
Exception in thread "main" java.time.format.DateTimeParseException: Text '19800228-5000' could not be parsed, unparsed text found at index 8.
Run Code Online (Sandbox Code Playgroud)
请注意,如果您确定字符串长度 yyyyMMdd,那么您始终可以使用前 8 个字符的子字符串来消除对解析器的需要。然而,这是两件不同的事情。解析器将标记输入上的无效日期格式,并且子字符串当然只会删除多余的字符。