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

DateTimeFormatter fails on parsing "yyyyMMddHHmmssSSS"

    Details

    • Subcomponent:
    • CPU:
      generic
    • OS:
      generic

      Description

      A DESCRIPTION OF THE PROBLEM :
      DateTimeFormatter fails on parsing "yyyyMMddHHmmssSSS" for given String "20180215062445678", because `subsequentWidth` is calculated wrong which brings `effMaxWidth` for year parsing to numbers greater than 4 and it fails immediately there. However, "yyyyMMddHHmmss SSS" for "20180215062445 678", or any other delimiter between seconds and a fraction part of a second works absolutely fine.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. try to execute:
       `ZonedDateTime.parse("20180215062445 678 Europe/Vienna", DateTimeFormatter.ofPattern("yyyyMMddHHmmss SSS z"));`
      to see that it doesn't fail;
      2. try to execute:
       `ZonedDateTime.parse("20180215062445678 Europe/Vienna", DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS z"));`
      to see that it fails;

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Second step shouldn't fail. It doesn't violate any description of the format from Java Docs.
      ACTUAL -
      An exception is thrown:
      java.time.format.DateTimeParseException: Text '20180215062445678 Europe/Vienna' could not be parsed at index 0

      ---------- BEGIN SOURCE ----------
      @Test
      void itShouldNotFail() {
          ZonedDateTime.parse("20180215062445678 Europe/Vienna", DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS z"));
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Joda time works fine with this pattern. So the workaround (in Kotlin) is:
      ```
      fun parseDateTime(input: String, format: String): ZonedDateTime {
      return try {
      ZonedDateTime.parse(input, DateTimeFormatter.ofPattern(format))
      } catch (e: DateTimeParseException) {
      val dt = DateTimeFormat.forPattern(format).parseDateTime(input)
      dt.toZonedDateTime()
      }
      }

      private fun DateTime.toZonedDateTime(): ZonedDateTime =
      ZonedDateTime.ofLocal(
      LocalDateTime.of(
      year,
      monthOfYear,
      dayOfMonth,
      hourOfDay,
      minuteOfHour,
      secondOfMinute,
      millisOfSecond * 1_000_000
      ),
      ZoneId.of(zone.id, ZoneId.SHORT_IDS),
      ZoneOffset.ofTotalSeconds(zone.getOffset(this) / 1000)
      )
      ```

      FREQUENCY : always


        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                psonal Pallavi Sonal
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: