8079628: java.time: DateTimeFormatter containing "DD" fails on 3-digit day-of-year value`

Change the definition of 'DD' to match with CLDR

Reviewed-by: rriggs, scolebourne
This commit is contained in:
Nadeesh TV 2016-05-08 07:46:19 +00:00
parent 9ef9b485e3
commit 4900a83203
3 changed files with 51 additions and 5 deletions

View File

@ -1488,7 +1488,7 @@ public final class DateTimeFormatterBuilder {
* d 1 appendValue(ChronoField.DAY_OF_MONTH)
* dd 2 appendValue(ChronoField.DAY_OF_MONTH, 2)
* D 1 appendValue(ChronoField.DAY_OF_YEAR)
* DD 2 appendValue(ChronoField.DAY_OF_YEAR, 2)
* DD 2 appendValue(ChronoField.DAY_OF_YEAR, 2, 3, SignStyle.NOT_NEGATIVE)
* DDD 3 appendValue(ChronoField.DAY_OF_YEAR, 3)
* F 1 appendValue(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH)
* g..g 1..n appendValue(JulianFields.MODIFIED_JULIAN_DAY, n, 19, SignStyle.NORMAL)
@ -1838,8 +1838,8 @@ public final class DateTimeFormatterBuilder {
case 'D':
if (count == 1) {
appendValue(field);
} else if (count <= 3) {
appendValue(field, count);
} else if (count == 2 || count == 3) {
appendValue(field, count, 3, SignStyle.NOT_NEGATIVE);
} else {
throw new IllegalArgumentException("Too many pattern letters: " + cur);
}

View File

@ -794,6 +794,52 @@ public class TCKDateTimeFormatterBuilder {
DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern("g").toFormatter();
assertEquals(LocalDate.of(y, m, d).format(df), expected);
}
//----------------------------------------------------------------------
@DataProvider(name="dayOfYearFieldValues")
Object[][] data_dayOfYearFieldValues() {
return new Object[][] {
{2016, 1, 1, "D", "1"},
{2016, 1, 31, "D", "31"},
{2016, 1, 1, "DD", "01"},
{2016, 1, 31, "DD", "31"},
{2016, 4, 9, "DD", "100"},
{2016, 1, 1, "DDD", "001"},
{2016, 1, 31, "DDD", "031"},
{2016, 4, 9, "DDD", "100"},
};
}
@Test(dataProvider="dayOfYearFieldValues")
public void test_dayOfYearFieldValues(int y, int m, int d, String pattern, String expected) throws Exception {
DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter();
assertEquals(LocalDate.of(y, m, d).format(df), expected);
}
@DataProvider(name="dayOfYearFieldAdjacentParsingValues")
Object[][] data_dayOfYearFieldAdjacentParsingValues() {
return new Object[][] {
{"20160281015", LocalDateTime.of(2016, 1, 28, 10, 15)},
{"20161001015", LocalDateTime.of(2016, 4, 9, 10, 15)},
};
}
@Test(dataProvider="dayOfYearFieldAdjacentParsingValues")
public void test_dayOfYearFieldAdjacentValueParsing(String input, LocalDateTime expected) {
DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern("yyyyDDDHHmm").toFormatter();
LocalDateTime actual = LocalDateTime.parse(input, df);
assertEquals(actual, expected);
}
@Test(expectedExceptions = DateTimeParseException.class)
public void test_dayOfYearFieldInvalidValue() {
DateTimeFormatter.ofPattern("DDD").parse("1234");
}
@Test(expectedExceptions = DateTimeParseException.class)
public void test_dayOfYearFieldInvalidAdacentValueParsingPattern() {
// patterns D and DD will not take part in adjacent value parsing
DateTimeFormatter.ofPattern("yyyyDDHHmmss").parse("201610123456");
}
//-----------------------------------------------------------------------
@DataProvider(name="secondsPattern")

View File

@ -684,7 +684,7 @@ public class TestDateTimeFormatterBuilder {
{"LLLLL", "Text(MonthOfYear,NARROW_STANDALONE)"},
{"D", "Value(DayOfYear)"},
{"DD", "Value(DayOfYear,2)"},
{"DD", "Value(DayOfYear,2,3,NOT_NEGATIVE)"},
{"DDD", "Value(DayOfYear,3)"},
{"d", "Value(DayOfMonth)"},
@ -782,7 +782,7 @@ public class TestDateTimeFormatterBuilder {
{"xxxxx", "Offset(+HH:MM:ss,'+00:00')"}, // LDML
{"ppH", "Pad(Value(HourOfDay),2)"},
{"pppDD", "Pad(Value(DayOfYear,2),3)"},
{"pppDD", "Pad(Value(DayOfYear,2,3,NOT_NEGATIVE),3)"},
{"yyyy[-MM[-dd", "Value(YearOfEra,4,19,EXCEEDS_PAD)['-'Value(MonthOfYear,2)['-'Value(DayOfMonth,2)]]"},
{"yyyy[-MM[-dd]]", "Value(YearOfEra,4,19,EXCEEDS_PAD)['-'Value(MonthOfYear,2)['-'Value(DayOfMonth,2)]]"},