ADDITIONAL SYSTEM INFORMATION :
macOS Sierra 10.12.6
openjdk 20-ea 2023-03-21
OpenJDK Runtime Environment (build 20-ea+12-790)
OpenJDK 64-Bit Server VM (build 20-ea+12-790, mixed mode, sharing)
SHELL=/bin/bash
HOSTTYPE=x86_64
OSTYPE=darwin16
MACHTYPE=x86_64-apple-darwin16
The same undesired and unexpected behaviour has also been observed on Java 8, Java 11 and Java 17.
A DESCRIPTION OF THE PROBLEM :
We are using a DateTimeFormatter for parsing week-based-year and week number. Using resolver style ResolverStyle.STRICT. Trying to parse week number 53 in a week-based year having only 52 weeks.
Expected and desired behaviour: Since the week number is invalid, Java should throw a DateTimeParseException.
Observed behaviour: Java parses as though the string had said week 52.
The undesired behaviour is observed both with ISO and non-ISO week schemes, in fact with all available locales in Java 17.
This bug report comes out of the following Stack Overflow question: https://stackoverflow.com/questions/73498610/java-week-to-date-conversion-for-us-calendar-non-iso8601
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the included Java program.
Also online here: https://rextester.com/NIDEB77126
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
DateTimeParseException from the line LocalDate date = LocalDate.parse(weekDateString, localizedWeekDateFormatter);
ACTUAL -
Locale: it_CH
Week fields: WeekFields[MONDAY,4]
String: 2022.53.1
Parsed: 2022-12-26
Formatted back: 2022.52.1
Locale: en_SL
Week fields: WeekFields[MONDAY,1]
String: 2022.53.1
Parsed: 2022-12-19
Formatted back: 2022.52.1
Locale: teo_KE
Week fields: WeekFields[SUNDAY,1]
String: 2021.53.1
Parsed: 2021-12-19
Formatted back: 2021.52.1
As expected: java.time.format.DateTimeParseException: Text '2021-W53-1' could not be parsed: Invalid value for WeekOfWeekBasedYear (valid values 1 - 52): 53
---------- BEGIN SOURCE ----------
import java.util.Locale;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.format.ResolverStyle;
import java.time.temporal.WeekFields;
class Rextester
{
public static void main(String args[])
{
// ISO weeks locale
Locale iso = Locale.forLanguageTag("it-CH");
testAndPrint(iso, "2022.53.1");
// Non-ISO weeks locale
Locale nonIso = Locale.forLanguageTag("en-SL");
testAndPrint(nonIso, "2022.53.1");
// Another non-ISO weeks locale
Locale anotherNonIso = Locale.forLanguageTag("teo-KE");
testAndPrint(anotherNonIso, "2021.53.1");
try {
// The following line gives the expected exception
// java.time.format.DateTimeParseException: Text '2021-W53-1' could not be parsed: Invalid value for WeekOfWeekBasedYear (valid values 1 - 52): 53
LocalDate.parse("2021-W53-1", DateTimeFormatter.ISO_WEEK_DATE);
} catch (DateTimeParseException dtpe) {
System.out.println("As expected: " + dtpe);
}
}
private static void testAndPrint(Locale localeInQuestion, String weekDateString) {
DateTimeFormatter localizedWeekDateFormatter
= DateTimeFormatter.ofPattern("YYYY.ww.e", localeInQuestion)
.withResolverStyle(ResolverStyle.STRICT);
// We are expecting a DateTimeParseException from the following line but not getting any.
LocalDate date = LocalDate.parse(weekDateString, localizedWeekDateFormatter);
System.out.format("Locale: %s%n", localeInQuestion);
System.out.format("Week fields: %s%n", WeekFields.of(localeInQuestion));
System.out.format("String: %s%n", weekDateString);
System.out.format("Parsed: %s%n", date);
System.out.format("Formatted back: %s%n", date.format(localizedWeekDateFormatter));
System.out.println();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
One may format the obtained date back into a string and compare with the string originally parsed. If they differ, the string did not represent the date parsed. Then throw the desired exception (or take other desired action).
FREQUENCY : always
macOS Sierra 10.12.6
openjdk 20-ea 2023-03-21
OpenJDK Runtime Environment (build 20-ea+12-790)
OpenJDK 64-Bit Server VM (build 20-ea+12-790, mixed mode, sharing)
SHELL=/bin/bash
HOSTTYPE=x86_64
OSTYPE=darwin16
MACHTYPE=x86_64-apple-darwin16
The same undesired and unexpected behaviour has also been observed on Java 8, Java 11 and Java 17.
A DESCRIPTION OF THE PROBLEM :
We are using a DateTimeFormatter for parsing week-based-year and week number. Using resolver style ResolverStyle.STRICT. Trying to parse week number 53 in a week-based year having only 52 weeks.
Expected and desired behaviour: Since the week number is invalid, Java should throw a DateTimeParseException.
Observed behaviour: Java parses as though the string had said week 52.
The undesired behaviour is observed both with ISO and non-ISO week schemes, in fact with all available locales in Java 17.
This bug report comes out of the following Stack Overflow question: https://stackoverflow.com/questions/73498610/java-week-to-date-conversion-for-us-calendar-non-iso8601
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the included Java program.
Also online here: https://rextester.com/NIDEB77126
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
DateTimeParseException from the line LocalDate date = LocalDate.parse(weekDateString, localizedWeekDateFormatter);
ACTUAL -
Locale: it_CH
Week fields: WeekFields[MONDAY,4]
String: 2022.53.1
Parsed: 2022-12-26
Formatted back: 2022.52.1
Locale: en_SL
Week fields: WeekFields[MONDAY,1]
String: 2022.53.1
Parsed: 2022-12-19
Formatted back: 2022.52.1
Locale: teo_KE
Week fields: WeekFields[SUNDAY,1]
String: 2021.53.1
Parsed: 2021-12-19
Formatted back: 2021.52.1
As expected: java.time.format.DateTimeParseException: Text '2021-W53-1' could not be parsed: Invalid value for WeekOfWeekBasedYear (valid values 1 - 52): 53
---------- BEGIN SOURCE ----------
import java.util.Locale;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.format.ResolverStyle;
import java.time.temporal.WeekFields;
class Rextester
{
public static void main(String args[])
{
// ISO weeks locale
Locale iso = Locale.forLanguageTag("it-CH");
testAndPrint(iso, "2022.53.1");
// Non-ISO weeks locale
Locale nonIso = Locale.forLanguageTag("en-SL");
testAndPrint(nonIso, "2022.53.1");
// Another non-ISO weeks locale
Locale anotherNonIso = Locale.forLanguageTag("teo-KE");
testAndPrint(anotherNonIso, "2021.53.1");
try {
// The following line gives the expected exception
// java.time.format.DateTimeParseException: Text '2021-W53-1' could not be parsed: Invalid value for WeekOfWeekBasedYear (valid values 1 - 52): 53
LocalDate.parse("2021-W53-1", DateTimeFormatter.ISO_WEEK_DATE);
} catch (DateTimeParseException dtpe) {
System.out.println("As expected: " + dtpe);
}
}
private static void testAndPrint(Locale localeInQuestion, String weekDateString) {
DateTimeFormatter localizedWeekDateFormatter
= DateTimeFormatter.ofPattern("YYYY.ww.e", localeInQuestion)
.withResolverStyle(ResolverStyle.STRICT);
// We are expecting a DateTimeParseException from the following line but not getting any.
LocalDate date = LocalDate.parse(weekDateString, localizedWeekDateFormatter);
System.out.format("Locale: %s%n", localeInQuestion);
System.out.format("Week fields: %s%n", WeekFields.of(localeInQuestion));
System.out.format("String: %s%n", weekDateString);
System.out.format("Parsed: %s%n", date);
System.out.format("Formatted back: %s%n", date.format(localizedWeekDateFormatter));
System.out.println();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
One may format the obtained date back into a string and compare with the string originally parsed. If they differ, the string did not represent the date parsed. Then throw the desired exception (or take other desired action).
FREQUENCY : always