Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8223773

DateTimeFormatter Fails to throw an Exception on Invalid HOUR_OF_AMPM

    Details

    • Subcomponent:
    • Resolved In Build:
      b24
    • CPU:
      generic
    • OS:
      generic

      Backports

        Description

        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


          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  naoto Naoto Sato
                  Reporter:
                  webbuggrp Webbug Group
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  5 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: