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

java.time.DateTimeFormatter: wrong definition of symbol F

    XMLWordPrintable

Details

    • b13
    • generic
    • generic
    • Verified

    Description

      A DESCRIPTION OF THE PROBLEM :
      As a result, java.time.format.DateTimeFormatterBuilder#FIELD_MAP should put java.time.temporal.ChronoField#ALIGNED_WEEK_OF_MONTH to 'F' instead of java.time.temporal.ChronoField#ALIGNED_DAY_OF_WEEK_IN_MONTH.

      Symbol F in java.time.DateTimeFormatter should have the same meaning with F in java.text.SimpleDateFormatter, which means the ordinal number of *day of week* in current month defined by java.text.DateFormat#DAY_OF_WEEK_IN_MONTH_FIELD. It should equals "Math.ceil(day / 7)" which "day" means the day of month.
      But in java.time.DateTimeFormatter, it means the ordinal number of day of *aligned week in month* defined by java.time.temporal.ChronoField#ALIGNED_DAY_OF_WEEK_IN_MONTH, which equips "(day + 1) % 7".

      It may be a mistake caused by similar name of "DAY_OF_WEEK_IN_MONTH_FIELD" and "ALIGNED_DAY_OF_WEEK_IN_MONTH" but with different meaning.
      I found that in JDK-8169482 it changed javadoc's "week in month" to "day of week in month" from JDK 9. But "ALIGNED_DAY_OF_WEEK_IN_MONTH" does not have the same meaning with "DAY_OF_WEEK_IN_MONTH_FIELD" in java.text.DateFormat.

      Still, the symbol F in java.time.DateTimeFormatter is no use in any pattern. It just may cause an exception.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the test case below.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      It should print "Sun May 08 00:00:00 UTC 2022" and "2022-05-08".
      ACTUAL -
      It prints "Sun May 08 00:00:00 UTC 2022" with SimpleDateFormat, but throws exception with DateTimeFormatter:


      ---------- BEGIN SOURCE ----------
      import java.time.format.DateTimeFormatter;
      import java.time.format.DateTimeFormatterBuilder;
      import java.time.LocalDate;
      import java.time.temporal.ChronoField;
      import java.text.SimpleDateFormat;
      import java.text.ParseException;
      import java.util.Locale;
      import java.util.Date;

      public class TestCase {
          public static void main(String []args) {
              String pattern = "yyyy-MM F EEE";
      String definition = "2022-05 2 Sun";
      SimpleDateFormat sdf = new SimpleDateFormat(pattern);
      try {
      System.out.println(sdf.parse(definition));
      } catch (ParseException e) {
      System.out.println(e);
      }

      /* correct formatter
      DateTimeFormatter correctFormatter = new DateTimeFormatterBuilder()
      .appendPattern("yyyy-MM ")
      .appendValue(ChronoField.ALIGNED_WEEK_OF_MONTH)
      .appendPattern(" EEE")
      .toFormatter(Locale.ENGLISH);
      System.out.println(correctFormatter.parse(definition, LocalDate::from));
      */

      DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern, Locale.ENGLISH);
      System.out.println(formatter.parse(definition, LocalDate::from));
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Use DateTimeFormatterBuilder to build a correct DateTimeFormatter with DateTimeFormatterBuilder#appendValue(ChronoField.ALIGNED_WEEK_OF_MONTH).

      Attachments

        Issue Links

          Activity

            People

              naoto Naoto Sato
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: