我正在进行以下编程练习:不幸的日子。声明如下:
星期五13号或黑色星期五被认为是不吉利的一天。计算出一年中有多少不幸的日子。 找出给定年份的星期五13号的号码。 输入:年份为整数。 输出:一年中黑色星期五的数目为整数。 示例: unluckyDays(2015年) == 3 unluckyDays(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)因此,正如我们所看到的,用于LocalDate.parse(String.format("%d/%d/13",year,i));的字符串中的“/”在索引4中是错误的。
然后,我决定将格式改为“-”而不是“/”。
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,我不明白。
此外,我还读到:
我们如何知道,为什么LocalDate解析抛出异常‽
发布于 2019-12-28 09:58:04
你离成功很近。你在这里有两个选择:
DateTimeFormatter并将其传递给您的LocalDate.parse:LocalDate date = LocalDate.parse("13/01/2019", new DateTimeFormatter("dd/MM/yyyy");
有关更多信息,请访问此网站:https://www.baeldung.com/java-string-to-dateLocalDate.of(year, month, day);方法:在您的示例中,这将是LocalDate date = LocalDate.of(year, i, 13);。如果您检查javadoc,您将看到,对于月份参数,1是一月,12是12月。基本上,你很适合这样做。你不需要DateTimeFormatter或者String.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")时,您的字符串不匹配默认格式,因此出现异常。
发布于 2019-12-28 09:44:17
必须将格式化程序作为第二个参数传递。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-M-yyyy");
LocalDate date = LocalDate.parse("01-1-2019", formatter);发布于 2019-12-29 00:29:36
溪流与羔羊
其他答案是正确的。为了好玩,这里有几种使用lambda语法、流和谓词的方法。
月流
在Ole V.V.的评论。中,该解决方案使用从枚举类中通过Arrays实用工具类(1月至12月)获取的一个Month对象流。对于每个月,我们可以问,某一年的第13天是否是星期五。
我们正在动态地实例化一个LocalDate,这是一个日期唯一的值,没有一天的时间,也没有时区。
int year = 2020 ;
long count =
Arrays // Utility class, `java.util.Arrays`.
.stream( // Generate a stream from an array.
Month.values() // Generate an array from all the objects defined on this enum `Month`: An object for January, and February, and so on.
) // Returns a `Stream` object.
.filter( // Applies a `Predicate` to test each object produced by the stream. Those that pass the test are fed into a new second stream.
( Month month ) -> // For each `Month` enum object.
LocalDate // Represent a date-only value, a year-month-day.
.of( year , month , 13 ) // Instantiate a `LocalDate` from inputs for year number, `Month` enum object, and day number.
.getDayOfWeek() // Interrogate for the `DayOfWeek` enum object that represents the day-of-week for that particular date.
.equals( DayOfWeek.FRIDAY ) // Ask if the day-of-week for this date is a Friday.
) // Returns a new 2nd `Stream` object.
.count() // Returns the number of Friday-the-13th dates are being produced by this second stream. The year 2020 has two such dates.
;日期流
在另一个解决方案中,我们得到一个Stream of LocalDate对象,用于开始和停止之间的每个日期。请注意,日期范围为半打开,其中开始包含在包含,而结束是排他性的。所以一年从一年的第一天开始,一直持续到第二年的第一年,但不包括第一年。
对于流中的每个日期,我们使用Predicate检查是否(a)月日为13,(b) DayOfWeek为周五。所有通过测试的LocalDate对象都被放入一个新生成的List中。
int input = 2020;
Year year = Year.of( input );
LocalDate start = year.atDay( 1 );
LocalDate stop = year.plusYears( 1 ).atDay( 1 );
List < LocalDate > fridayThe13ths =
start
.datesUntil( stop )
.filter(
( LocalDate localDate ) ->
( localDate.getDayOfMonth() == 13 )
&&
localDate.getDayOfWeek().equals( DayOfWeek.FRIDAY )
)
.collect( Collectors.toList() )
;转储到控制台。生成标准ISO 8601格式的文本。
System.out.println( "fridayThe13ths = " + fridayThe13ths );fridayThe13ths = 2020-03-13,2020年-11-13
为了验证这些结果确实是星期五-13号,让我们生成表示它们的值的字符串。我们定义了一个格式化程序,用于自动本地化输出,其中包括每周一天。
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( Locale.US );
fridayThe13ths.forEach( ( LocalDate localDate ) -> System.out.println( localDate.format( f ) ) );二00二年三月十三日(星期五) 二00二年十一月十三日(星期五)
https://stackoverflow.com/questions/59509685
复制相似问题