--- old/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java 2016-04-26 10:14:09.388151242 +0300 +++ new/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java 2016-04-26 10:14:09.118151242 +0300 @@ -1479,9 +1479,7 @@ * W 1 append special localized WeekFields element for numeric week-of-month * 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) - * DDD 3 appendValue(ChronoField.DAY_OF_YEAR, 3) + * D..D 1..3 appendValue(ChronoField.DAY_OF_YEAR, n, 19, SignStyle.NORMAL) * F 1 appendValue(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH) * g..g 1..n appendValue(JulianFields.MODIFIED_JULIAN_DAY, n, 19, SignStyle.NORMAL) * E 1 appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT) @@ -1831,12 +1829,10 @@ } break; case 'D': - if (count == 1) { - appendValue(field); - } else if (count <= 3) { - appendValue(field, count); - } else { + if (count > 3) { throw new IllegalArgumentException("Too many pattern letters: " + cur); + } else { + appendValue(field, count, 19, SignStyle.NORMAL); } break; case 'g': --- old/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java 2016-04-26 10:14:10.057151242 +0300 +++ new/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java 2016-04-26 10:14:09.791151242 +0300 @@ -793,7 +793,43 @@ assertEquals(LocalDate.of(y, m, d).format(df), expected); } + //----------------------------------------------------------------------- + @DataProvider(name="dayOfYearFieldPattern") + Object[][] data_dayOfYearFieldPattern() { + return new Object[][] { + {"D", "1"}, + {"D", "123"}, + {"DD", "12"}, + {"DD", "123"}, + {"DDD", "123"}, + {"DDD", "12345"}, + }; + } + + @Test(dataProvider="dayOfYearFieldPattern") + public void test_dayOfYearFieldPattern(String pattern, String input) throws Exception { + DateTimeFormatter.ofPattern(pattern).parse(input); + } + @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); + } //----------------------------------------------------------------------- @Test public void test_adjacent_strict_firstFixedWidth() throws Exception { --- old/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java 2016-04-26 10:14:10.693151242 +0300 +++ new/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java 2016-04-26 10:14:10.404151242 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -684,8 +684,8 @@ {"LLLLL", "Text(MonthOfYear,NARROW_STANDALONE)"}, {"D", "Value(DayOfYear)"}, - {"DD", "Value(DayOfYear,2)"}, - {"DDD", "Value(DayOfYear,3)"}, + {"DD", "Value(DayOfYear,2,19,NORMAL)"}, + {"DDD", "Value(DayOfYear,3,19,NORMAL)"}, {"d", "Value(DayOfMonth)"}, {"dd", "Value(DayOfMonth,2)"}, @@ -782,7 +782,7 @@ {"xxxxx", "Offset(+HH:MM:ss,'+00:00')"}, // LDML {"ppH", "Pad(Value(HourOfDay),2)"}, - {"pppDD", "Pad(Value(DayOfYear,2),3)"}, + {"pppDD", "Pad(Value(DayOfYear,2,19,NORMAL),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)]]"},