I am doing the following programming exercise: Unlucky Days. The statement is:
Friday 13th or Black Friday is considered as unlucky day. Calculate how many unlucky days are in the given year.
Find the number of Friday 13th in the given year.
Input: Year as an integer.
Output: Number of Black Fridays in the year as an integer.
Examples:
unluckyDays(2015) == 3 unluckyDays(1986) == 1
First I tried the following code:
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;
}
}
Where we get the following exception:
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)
So as we see, the '/' at index 4 in the string used for LocalDate.parse(String.format("%d/%d/13",year,i));
is wrong.
Then I decided to change the format to use '-' instead of '/'
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;
}
}
And with the previous code, the exception being thrown is:
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)
So as we see there is a difficulty with the one digit month '1'.
To continue I put the condition to pad with a 0 those months which only have one digit:
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;
}
}
With this condition it works. However how could we indicate in the DateTimeFormatter.ofPattern("yyyy-M-dd");
that months can have only one digit.
In addition, what should we do to use a different date format, for example: DateTimeFormatter.ofPattern("dd-M-yyyy");
Because of I have tried:
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;
}
}
Being the output quite interesting:
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)
As we observe the '13' for days is causing an exception, at index 0, which I do not understand.
In addition I have read:
- How to determine day of week by passing specific date?
- Calculating future occurrences of Friday the 13th
- https://www.geeksforgeeks.org/localdate-parse-method-in-java-with-examples/
How could we know, why LocalDate parse throws exceptions‽