我的日期格式如下:
四位数的年份,然后两位的星期号。
例如,2018年的第四周将是 201804 。
我在使用Java 8的 LocalDate 和 DateTimeFormatterBuilder 解析这些日期时遇到麻烦。
这是我尝试解析日期的方式:
LocalDate.parse(
"201804",
new DateTimeFormatterBuilder().appendPattern("YYYYww").parseDefaulting(WeekFields.ISO.dayOfWeek(), 1).toFormatter()
);
执行将引发以下异常:
java.time.format.DateTimeParseException:无法在索引0处解析文本'201804'
奇怪的行为是,当我在日期部分之间添加分隔符时,不再抛出异常:
LocalDate.parse(
"2018 04",
new DateTimeFormatterBuilder().appendPattern("YYYY ww").parseDefaulting(WeekFields.ISO.dayOfWeek(), 1).toFormatter()
);
结果:
2018-01-22
格式化程序是否缺少我的东西?
答案 0 :(得分:5)
您可以使用appendValue
此方法支持一种特殊的解析技术,称为“相邻值解析”。此技术解决了以下问题:可变或固定宽度的值后面跟随一个或多个固定长度值。标准解析器是贪婪的,因此它通常会窃取跟随可变宽度1的固定宽度值解析器所需的数字。
无需采取任何措施即可启动“相邻值解析”。调用appendValue时,构建器将进入相邻值解析设置模式。
这可行:
LocalDate.parse(
"201804",
new DateTimeFormatterBuilder()
.appendValue(YEAR, 4)
.appendValue(ALIGNED_WEEK_OF_YEAR, 2)
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1).toFormatter()
);
答案 1 :(得分:2)
尝试显式定义计时字段:
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
DateTimeFormatter formatter =
builder.appendValue(ChronoField.YEAR, 4)
.appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2)
.parseDefaulting(ChronoField.DAY_OF_WEEK, 1)
.toFormatter();
LocalDate.parse("201804", formatter);
答案 2 :(得分:0)
不是简单地做这项工作吗?
LocalDate.parse("2018041", DateTimeFormatter.ofPattern("YYYYwwe"));
本质上,您需要告诉它您想要该周Monday
的日期,而不仅仅是一周。
答案 3 :(得分:0)
是的,这也使我从国外获得的数据丧生了很多次。...
根据所获得的内容,您需要不同的解析器。对于Date,您需要LocalDate;对于有时间的东西,您需要LocalTimedate.parse。
意思是如果您不知道要获取什么数据(通常当天没有日期但有时间,而过去的日期没有时间但有日期-因此您不知道),则有首先要对自己进行粗略的解析以检测特定的格式,然后才让Java对其进行解析。...Javas的日期处理有点困难。
解决方案是:使用LocalDate而不是LocalTimeDate。