-
Bug
-
Resolution: Fixed
-
P4
-
8, 11, 17, 18, 19
-
b13
-
generic
-
generic
-
Verified
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 inJDK-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).
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
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).
- csr for
-
JDK-8282377 java.time.DateTimeFormatter: wrong definition of symbol F
-
- Closed
-
- relates to
-
JDK-8169482 java.time.DateTimeFormatter javadoc: F is not week-of-month
-
- Resolved
-