-
Bug
-
Resolution: Fixed
-
P4
-
8, 11, 12, 13
-
b24
-
generic
-
generic
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8225890 | 14 | Naoto Sato | P4 | Resolved | Fixed | team |
ADDITIONAL SYSTEM INFORMATION :
Tested on
JDK1.8.0_181 on Windows 10
Java 11.0.3-ojdkbuild on Ubuntu Windows Subsystem for Linux
A DESCRIPTION OF THE PROBLEM :
When parsing using a DateTimeFormmatterBuilder and including both CLOCK_HOUR_OF_AMPM or HOUR_OF_AMPM and providing a date outside of their respective ranges, the parser will fail to throw an exception. According to the spec, both of these should throw a parse exception when the input is out of bounds.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Parse "2007-10-22 12:00 PM" with HOUR_OF_AMPM
2. Parse "2007-10-22 12:00 PM" with CLOCK_HOUR_OF_AMPM
1. Parse "2007-10-22 00:00 PM" with HOUR_OF_AMPM
2. Parse "2007-10-22 00:00 PM" with CLOCK_HOUR_OF_AMPM
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
1. DateTimeParseException
2. Noon
3. Noon
4. DateTimeParseException
ACTUAL -
1. Midnight of the Next Day
2. Noon
3. Noon
4. Noon
---------- BEGIN SOURCE ----------
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Expected DateTimeParse Error - Got Midnight of Next Day
String input = "2007-10-22 12:00 PM";
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
.parseStrict()
.appendValue(ChronoField.YEAR_OF_ERA)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH)
.appendLiteral(' ')
.appendValue(ChronoField.HOUR_OF_AMPM,2)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR,2)
.appendLiteral(' ')
.appendText(ChronoField.AMPM_OF_DAY);
DateTimeFormatter formatter = builder.toFormatter(Locale.US);
TemporalAccessor accessor = formatter.parse(input);
LocalDateTime localDateTime = LocalDateTime.from(accessor);
System.out.println(localDateTime.toString());
// Expected Noon - Got Noon
input = "2007-10-22 12:00 PM";
builder = new DateTimeFormatterBuilder()
.parseStrict()
.appendValue(ChronoField.YEAR_OF_ERA)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH)
.appendLiteral(' ')
.appendValue(ChronoField.CLOCK_HOUR_OF_AMPM,2)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR,2)
.appendLiteral(' ')
.appendText(ChronoField.AMPM_OF_DAY);
formatter = builder.toFormatter(Locale.US);
accessor = formatter.parse(input);
localDateTime = LocalDateTime.from(accessor);
System.out.println(localDateTime.toString());
// Expected Noon - Got Noon
input = "2007-10-22 00:00 PM";
builder = new DateTimeFormatterBuilder()
.parseStrict()
.appendValue(ChronoField.YEAR_OF_ERA)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH)
.appendLiteral(' ')
.appendValue(ChronoField.HOUR_OF_AMPM)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR)
.appendLiteral(' ')
.appendText(ChronoField.AMPM_OF_DAY);
formatter = builder.toFormatter(Locale.US);
accessor = formatter.parse(input);
localDateTime = LocalDateTime.from(accessor);
System.out.println(localDateTime.toString());
// Expected DateTimeParse Error - Got Noon
input = "2007-10-22 00:00 PM";
builder = new DateTimeFormatterBuilder()
.parseStrict()
.appendValue(ChronoField.YEAR_OF_ERA)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH)
.appendLiteral(' ')
.appendValue(ChronoField.CLOCK_HOUR_OF_AMPM)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR)
.appendLiteral(' ')
.appendText(ChronoField.AMPM_OF_DAY);
formatter = builder.toFormatter(Locale.US);
accessor = formatter.parse(input);
localDateTime = LocalDateTime.from(accessor);
System.out.println(localDateTime.toString());
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Use HOUR_OF_AMPM in place of both HOUR_OF_AMPM and CLOCK_HOUR_OF_AMPM for parsing.
FREQUENCY : always
Tested on
JDK1.8.0_181 on Windows 10
Java 11.0.3-ojdkbuild on Ubuntu Windows Subsystem for Linux
A DESCRIPTION OF THE PROBLEM :
When parsing using a DateTimeFormmatterBuilder and including both CLOCK_HOUR_OF_AMPM or HOUR_OF_AMPM and providing a date outside of their respective ranges, the parser will fail to throw an exception. According to the spec, both of these should throw a parse exception when the input is out of bounds.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Parse "2007-10-22 12:00 PM" with HOUR_OF_AMPM
2. Parse "2007-10-22 12:00 PM" with CLOCK_HOUR_OF_AMPM
1. Parse "2007-10-22 00:00 PM" with HOUR_OF_AMPM
2. Parse "2007-10-22 00:00 PM" with CLOCK_HOUR_OF_AMPM
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
1. DateTimeParseException
2. Noon
3. Noon
4. DateTimeParseException
ACTUAL -
1. Midnight of the Next Day
2. Noon
3. Noon
4. Noon
---------- BEGIN SOURCE ----------
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Expected DateTimeParse Error - Got Midnight of Next Day
String input = "2007-10-22 12:00 PM";
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
.parseStrict()
.appendValue(ChronoField.YEAR_OF_ERA)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH)
.appendLiteral(' ')
.appendValue(ChronoField.HOUR_OF_AMPM,2)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR,2)
.appendLiteral(' ')
.appendText(ChronoField.AMPM_OF_DAY);
DateTimeFormatter formatter = builder.toFormatter(Locale.US);
TemporalAccessor accessor = formatter.parse(input);
LocalDateTime localDateTime = LocalDateTime.from(accessor);
System.out.println(localDateTime.toString());
// Expected Noon - Got Noon
input = "2007-10-22 12:00 PM";
builder = new DateTimeFormatterBuilder()
.parseStrict()
.appendValue(ChronoField.YEAR_OF_ERA)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH)
.appendLiteral(' ')
.appendValue(ChronoField.CLOCK_HOUR_OF_AMPM,2)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR,2)
.appendLiteral(' ')
.appendText(ChronoField.AMPM_OF_DAY);
formatter = builder.toFormatter(Locale.US);
accessor = formatter.parse(input);
localDateTime = LocalDateTime.from(accessor);
System.out.println(localDateTime.toString());
// Expected Noon - Got Noon
input = "2007-10-22 00:00 PM";
builder = new DateTimeFormatterBuilder()
.parseStrict()
.appendValue(ChronoField.YEAR_OF_ERA)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH)
.appendLiteral(' ')
.appendValue(ChronoField.HOUR_OF_AMPM)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR)
.appendLiteral(' ')
.appendText(ChronoField.AMPM_OF_DAY);
formatter = builder.toFormatter(Locale.US);
accessor = formatter.parse(input);
localDateTime = LocalDateTime.from(accessor);
System.out.println(localDateTime.toString());
// Expected DateTimeParse Error - Got Noon
input = "2007-10-22 00:00 PM";
builder = new DateTimeFormatterBuilder()
.parseStrict()
.appendValue(ChronoField.YEAR_OF_ERA)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH)
.appendLiteral(' ')
.appendValue(ChronoField.CLOCK_HOUR_OF_AMPM)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR)
.appendLiteral(' ')
.appendText(ChronoField.AMPM_OF_DAY);
formatter = builder.toFormatter(Locale.US);
accessor = formatter.parse(input);
localDateTime = LocalDateTime.from(accessor);
System.out.println(localDateTime.toString());
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Use HOUR_OF_AMPM in place of both HOUR_OF_AMPM and CLOCK_HOUR_OF_AMPM for parsing.
FREQUENCY : always
- backported by
-
JDK-8225890 DateTimeFormatter Fails to throw an Exception on Invalid HOUR_OF_AMPM
- Resolved
- csr for
-
JDK-8225026 DateTimeFormatter Fails to throw an Exception on Invalid HOUR_OF_AMPM
- Closed