具有可选模式的Java DateTimeFormatterBuilder导致DateTimeParse
目标
为LocalDate实例提供灵活的解析器,可以使用以下格式之一处理输入: > yyyy 实施尝试 以下类尝试处理第一个和第二个模式.解析工作年份输入,但年月导致下面列出的例外情况. import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.temporal.ChronoField; public class DateTest { public static void main(String[] args) { DateTimeFormatter parser = new DateTimeFormatterBuilder() .parseDefaulting(ChronoField.MONTH_OF_YEAR,1) .parseDefaulting(ChronoField.DAY_OF_MONTH,1) .appendPattern("yyyy") .optionalStart().appendPattern("MM").optionalEnd().toFormatter(); System.out.println(parser.parse("2014",LocalDate::from)); // Works System.out.println(parser.parse("201411",LocalDate::from)); // Fails } } 第二次parse()尝试导致以下异常: Exception in thread "main" java.time.format.DateTimeParseException: Text '201411' could not be parsed at index 0 at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949) at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851) 我认为我对可选部分模式如何工作的理解是缺乏的.我的目标是一个灵活格式的解析器甚至可以实现,还是我需要检查输入长度并从解析器列表中选择?一如既往,感谢帮助. 解决方法
问题的真正原因是签名处理.您的输入没有任何符号,但解析器元素“yyyy”贪婪地解析尽可能多的数字并期望正号,因为找到了超过四位数.
我的分析以两种不同的方式完成: >调试(以查看不明确的错误消息背后的真实情况) ChronoFormatter<LocalDate> cf = ChronoFormatter .ofPattern( "yyyy[MM]",PatternType.THREETEN,Locale.ROOT,PlainDate.axis(TemporalType.LOCAL_DATE) ) .withDefault(PlainDate.MONTH_AS_NUMBER,1) .withDefault(PlainDate.DAY_OF_MONTH,1) .with(Leniency.STRICT); System.out.println(cf.parse("201411")); // java.text.ParseException: Positive sign must be present for big number. 您可以通过指示构建器始终仅使用年份的四位数来规避问题: DateTimeFormatter parser = new DateTimeFormatterBuilder() .appendValue(ChronoField.YEAR,4) .optionalStart() .appendPattern("MM[dd]") .optionalEnd() .parseDefaulting(ChronoField.MONTH_OF_YEAR,1) .toFormatter(); System.out.println(parser.parse("2014",LocalDate::from)); // 2014-01-01 System.out.println(parser.parse("201411",LocalDate::from)); // 2014-11-01 System.out.println(parser.parse("20141130",LocalDate::from)); // 2014-11-30 注意构建器中默认元素的位置.它们不是在开始时调用,而是在最后调用,因为不幸的是,在java.time中对默认元素的处理是位置敏感的.我还在第一个可选部分的内部添加了一个额外的可选部分.这个解决方案对我来说似乎更干净,而不是像Danila Zharenkov建议的那样使用3个可选部分的序列,因为后者也可以用更多的数字来解析相当不同的输入(可能滥用可选部分作为替换or-patterns特别是在宽松中解析). 关于默认元素的位置敏感行为,这里引用了API-documentation:
顺便说一句:在我的lib Time4J中,我还可以使用符号“|”定义真实或模式然后创建此格式化程序: ChronoFormatter<LocalDate> cf = ChronoFormatter .ofPattern( "yyyyMMdd|yyyyMM|yyyy",PatternType.CLDR,PlainDate.axis(TemporalType.LOCAL_DATE) ) .withDefault(PlainDate.MONTH_AS_NUMBER,1) .withDefault(PlainDate.DAY_OF_MONTH,1) .with(Leniency.STRICT); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- java – maven clean删除目标.这会搞砸正常构建
- java – Apache Hadoop setXIncludeAware UnsupportedOpera
- java – 在JNI中,是否有比jlong??更便携的方法来封装指针?
- 为什么java使用合并排序来排序大于元素7的数组
- java – 如何在JTextPane中将每个字符设置为不同的颜色/背景
- java – 将一个Object数组转换为我想要的类的数组
- java – 使用密钥的一部分获取HashMap的值
- java – 文件结尾NullPointerException
- 使用lambda的Java流中的参数调用构造函数
- java – createDatabaseIfNotExist = true在maven项目的.