Android Studio中使用DatePicker选择日期后触发java.time.format.DateTimeParseException异常的排查求助
问题排查与解决方案
为什么会触发DateTimeParseException?
你遇到的异常核心原因是日期字符串格式不匹配LocalDate默认的解析规则:
LocalDate.parse()默认遵循ISO 8601标准的日期格式(yyyy-MM-dd),要求月份和日期必须是两位数字(例如9日必须写成09,而不是9)。但你的日历对话框生成的日期字符串是2021-11-9这种格式——单数字的日期,导致解析器在索引8的位置(也就是-9的9前面)无法识别不符合格式的内容,从而抛出异常。
具体修复方案
这里提供两种可行的解决思路,你可以根据需求选择:
方案1:生成符合ISO标准的日期字符串(推荐)
修改日历对话框中生成日期文本的逻辑,确保月份和日期始终是两位数字(不足时补0):
calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() { @Override public void onSelectedDayChange(@NonNull CalendarView view, int year, int month, int dayOfMonth) { // CalendarView的month参数是0起始的(0代表1月),所以要+1转为常规的1起始月份 int adjustedMonth = month + 1; // 使用String.format格式化,%02d表示不足两位补0 String txtDate = String.format("%d-%02d-%02d", year, adjustedMonth, dayOfMonth); ((activity_invoice)getActivity()).date.setText(txtDate); getDialog().dismiss(); } });
这样生成的日期字符串会是2021-11-09这种完全符合LocalDate默认解析要求的格式,后续LocalDate.parse(data.getText())就能正常工作了。
方案2:自定义解析器兼容单/双位日期
如果不想修改生成的日期字符串格式,可以在解析时指定一个兼容单双位月份和日期的格式化器:
// 在保存按钮的点击事件中修改解析逻辑 @RequiresApi(api = Build.VERSION_CODES.O) @Override public void onClick(View v) { invoice = new Invoice(); // 定义兼容yyyy-M-d格式的解析器(M和d可以是1或2位) DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d"); LocalDate date = LocalDate.parse(data.getText(), formatter); invoice.setDate(date); // 这里注意原代码的invoice(date)应该是设置日期的方法,比如setDate }
这个方法可以同时兼容2021-11-9和2021-11-09两种格式。
额外的代码问题提醒
除了日期格式的问题,你的代码里还有几个容易导致bug的细节需要修复:
- 变量名冲突:你同时定义了
private LocalDate date;和public TextView date;,两个变量同名会导致代码歧义,建议把TextView的变量名改成dateTextView或者dateTv。 - CalendarView月份处理错误:原代码里虽然写了
int month = Month+1;但并没有使用这个变量,直接拼接了参数里的Month(0起始),会导致月份显示错误(比如选11月会显示10),上面的方案1已经修复了这个问题。 - 拼写错误:
data.setOnClickListener应该是date.setOnClickListener(因为你的TextView变量是date);另外invoice(date);看起来是错误的调用,应该是设置发票日期的方法,比如invoice.setDate(date);。
内容的提问来源于stack exchange,提问作者Catalin Petraru
相关产品推荐
相关产品推荐

