java - LocalDate 解析抛出异常‽
问题描述
我正在做以下编程练习:Unlucky Days。声明是:
13 日星期五或黑色星期五被认为是不吉利的日子。计算给定年份有多少不吉利的日子。
查找给定年份中 13 日星期五的数字。
输入:年份为整数。
输出:一年中黑色星期五的数量,以整数表示。
例子:
不幸的日子(2015) == 3 不幸的日子(1986) == 1
首先我尝试了以下代码:
import java.time.*;
import java.time.format.*;
import java.util.Locale;
public class Kata {
public static int unluckyDays/**/(int year) {
System.out.println("\nyear: "+year);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/M/dd");
for(int i = 1; i <= 12; i++){
LocalDate date = LocalDate.parse(String.format("%d/%d/13",year,i));
DayOfWeek dow = date.getDayOfWeek();
String output = dow.getDisplayName(TextStyle.FULL, Locale.US);
System.out.println("\noutput: "+output);
}
return 0;
}
}
我们得到以下异常的地方:
java.time.format.DateTimeParseException: Text '2015/1/13' could not be parsed at index 4
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.LocalDate.parse(LocalDate.java:428)
at java.base/java.time.LocalDate.parse(LocalDate.java:413)
at Kata.unluckyDays(Kata.java:10)
如我们所见,用于 for 的字符串中索引 4 处的“/”LocalDate.parse(String.format("%d/%d/13",year,i));
是错误的。
然后我决定将格式更改为使用'-'而不是'/'
import java.time.*;
import java.time.format.*;
import java.util.Locale;
public class Kata {
public static int unluckyDays/**/(int year) {
System.out.println("\nyear: "+year);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-dd");
for(int i = 1; i <= 12; i++){
LocalDate date = LocalDate.parse(String.format("%d-%d-13",year,i));
DayOfWeek dow = date.getDayOfWeek();
String output = dow.getDisplayName(TextStyle.FULL, Locale.US);
System.out.println("\noutput: "+output);
}
return 0;
}
}
使用前面的代码,抛出的异常是:
java.time.format.DateTimeParseException: Text '2015-1-13' could not be parsed at index 5
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.LocalDate.parse(LocalDate.java:428)
at java.base/java.time.LocalDate.parse(LocalDate.java:413)
at Kata.unluckyDays(Kata.java:10)
因此,正如我们所见,一位数的月份“1”存在困难。
为了继续,我将条件用 0 填充那些只有一位数字的月份:
import java.time.*;
import java.time.format.*;
import java.util.Locale;
public class Kata {
public static int unluckyDays/**/(int year) {
System.out.println("\nyear: "+year);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-dd");
int count = 0;
for(int i = 1; i <= 12; i++){
LocalDate date = LocalDate.parse(String.format("%d-%s-13",year,String.valueOf(i).length() < 2 ? "0"+i : i));
DayOfWeek dow = date.getDayOfWeek();
String output = dow.getDisplayName(TextStyle.FULL, Locale.US);
System.out.println("\noutput: "+output);
if(output.equals("Friday")){
count++;
}
}
return count;
}
}
在这种情况下,它可以工作。但是,我们怎么能指出DateTimeFormatter.ofPattern("yyyy-M-dd");
那几个月只能有一位数字。
另外,我们应该怎么做才能使用不同的日期格式,例如:DateTimeFormatter.ofPattern("dd-M-yyyy");
因为我试过:
import java.time.*;
import java.time.format.*;
import java.util.Locale;
public class Kata {
public static int unluckyDays/**/(int year) {
System.out.println("\nyear: "+year);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-M-yyyy");
int count = 0;
for(int i = 1; i <= 12; i++){
LocalDate date = LocalDate.parse(String.format("13-%s-%d",String.valueOf(i).length() < 2 ? "0"+i : i,year));
DayOfWeek dow = date.getDayOfWeek();
String output = dow.getDisplayName(TextStyle.FULL, Locale.US);
System.out.println("\noutput: "+output);
if(output.equals("Friday")){
count++;
}
}
return count;
}
}
作为输出非常有趣:
java.time.format.DateTimeParseException: Text '13-01-2015' could not be parsed at index 0
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.LocalDate.parse(LocalDate.java:428)
at java.base/java.time.LocalDate.parse(LocalDate.java:413)
at Kata.unluckyDays(Kata.java:11)
正如我们观察到的'13'几天导致异常,在索引0,我不明白。
另外我读过:
- 如何通过特定日期确定星期几?
- 计算 13 日星期五的未来事件
- https://www.geeksforgeeks.org/localdate-parse-method-in-java-with-examples/
我们怎么知道,为什么 LocalDate 解析会抛出异常‽</p>
解决方案
你离成功很近。您在这里有两个选择:
- 使用 a
DateTimeFormatter
并将其传递给您的LocalDate.parse
:LocalDate date = LocalDate.parse("13/01/2019", new DateTimeFormatter("dd/MM/yyyy");
查看此网站以获取更多信息: https ://www.baeldung.com/java-string-to-date - 或者,您可以使用方法
LocalDate.of(year, month, day);
:在您的情况下,这将是LocalDate date = LocalDate.of(year, i, 13);
. 如果您检查 javadoc,您会看到对于月份参数,1 是一月,12 是十二月。基本上,你很好。你不需要 aDateTimeFormatter
或 aString.format...
我试过你的代码,两种方法都可以。
编辑:
我想回答你的最后一个问题。每次调用时LocalDate.parse("anyStringRepresentingADate")
,幕后发生的事情LocalDate
是使用默认值DateTimeFormatter
:
public static LocalDate parse(CharSequence text) {
return parse(text, DateTimeFormatter.ISO_LOCAL_DATE);
}
并且DateTimeFormatter.ISO_LOCAL_DATE
是'yyyy-MM-dd'
。
当您这样做时LocalDate.parse("13/1/2020")
,您的字符串与默认格式不匹配,因此出现异常。
推荐阅读
- go - 在 Golang 中为 gRPC 服务器添加处理程序
- dompdf - Dompdf 在 Symfony 中不起作用并显示字符
- selenium - java.lang.NoSuchMethodError: org.jsoup.nodes.Document.wholeText()Ljava/lang/String;
- ruby-on-rails - 从最终结果栏删除 group_by 字段
- java - UI 自动化 - 自愈代理
- algorithm - 使用动态规划的最小旅行路径成本
- excel - 在文本来自另一列的 excel 范围内计算具有特定文本和特定颜色的单元格数
- asp.net-mvc - Google 登录返回访问被拒绝
- javascript - 为什么这不会输出任何东西?
- system-design - 需要调度程序设计帮助