8148949: DateTimeFormatter pattern letters 'A','n','N'
Summary: Changed the definition of pattern letters 'A','n','N' because it does not match the definition of CLDR
Reviewed-by: rriggs, scolebourne
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Fri May 06 11:23:49 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Fri May 06 12:48:19 2016 +0000
@@ -1527,12 +1527,9 @@
* ss 2 appendValue(ChronoField.SECOND_OF_MINUTE, 2)
*
* S..S 1..n appendFraction(ChronoField.NANO_OF_SECOND, n, n, false)
- * A 1 appendValue(ChronoField.MILLI_OF_DAY)
- * A..A 2..n appendValue(ChronoField.MILLI_OF_DAY, n)
- * n 1 appendValue(ChronoField.NANO_OF_SECOND)
- * n..n 2..n appendValue(ChronoField.NANO_OF_SECOND, n)
- * N 1 appendValue(ChronoField.NANO_OF_DAY)
- * N..N 2..n appendValue(ChronoField.NANO_OF_DAY, n)
+ * A..A 1..n appendValue(ChronoField.MILLI_OF_DAY, n, 19, SignStyle.NOT_NEGATIVE)
+ * n..n 1..n appendValue(ChronoField.NANO_OF_SECOND, n, 19, SignStyle.NOT_NEGATIVE)
+ * N..N 1..n appendValue(ChronoField.NANO_OF_DAY, n, 19, SignStyle.NOT_NEGATIVE)
* </pre>
* <p>
* <b>Zone ID</b>: Pattern letters to output {@code ZoneId}.
@@ -1850,6 +1847,11 @@
case 'g':
appendValue(field, count, 19, SignStyle.NORMAL);
break;
+ case 'A':
+ case 'n':
+ case 'N':
+ appendValue(field, count, 19, SignStyle.NOT_NEGATIVE);
+ break;
default:
if (count == 1) {
appendValue(field);
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java Fri May 06 11:23:49 2016 +0000
+++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java Fri May 06 12:48:19 2016 +0000
@@ -72,6 +72,7 @@
import java.text.ParsePosition;
import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.time.YearMonth;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
@@ -794,6 +795,54 @@
assertEquals(LocalDate.of(y, m, d).format(df), expected);
}
+ //-----------------------------------------------------------------------
+ @DataProvider(name="secondsPattern")
+ Object[][] data_secondsPattern() {
+ return new Object[][] {
+ {"A", "1", LocalTime.ofNanoOfDay(1_000_000)},
+ {"A", "100000", LocalTime.ofSecondOfDay(100)},
+ {"AA", "01", LocalTime.ofNanoOfDay(1_000_000)},
+ {"AA", "100000", LocalTime.ofSecondOfDay(100)},
+ {"AAAAAA", "100000", LocalTime.ofSecondOfDay(100)},
+ {"HHmmssn", "0000001", LocalTime.ofNanoOfDay(1)},
+ {"HHmmssn", "000000111", LocalTime.ofNanoOfDay(111)},
+ {"HHmmssnn", "00000001", LocalTime.ofNanoOfDay(1)},
+ {"HHmmssnn", "0000001111", LocalTime.ofNanoOfDay(1111)},
+ {"HHmmssnnnnnn", "000000111111", LocalTime.ofNanoOfDay(111_111)},
+ {"N", "1", LocalTime.ofNanoOfDay(1)},
+ {"N", "100000", LocalTime.ofNanoOfDay(100_000)},
+ {"NN", "01", LocalTime.ofNanoOfDay(1)},
+ {"NN", "100000", LocalTime.ofNanoOfDay(100_000)},
+ {"NNNNNN", "100000", LocalTime.ofNanoOfDay(100_000)},
+ };
+ }
+
+ @Test(dataProvider="secondsPattern")
+ public void test_secondsPattern(String pattern, String input, LocalTime expected) throws Exception {
+ DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter();
+ assertEquals(LocalTime.parse(input, df), expected);
+ }
+
+ @DataProvider(name="secondsValues")
+ Object[][] data_secondsValues() {
+ return new Object[][] {
+ {"A", 1, "1000"},
+ {"n", 1, "0"},
+ {"N", 1, "1000000000"},
+ };
+ }
+
+ @Test(dataProvider="secondsValues")
+ public void test_secondsValues(String pattern, int seconds , String expected) throws Exception {
+ DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter();
+ assertEquals(LocalTime.ofSecondOfDay(seconds).format(df), expected);
+ }
+
+ @Test(expectedExceptions = DateTimeParseException.class)
+ public void test_secondsPatternInvalidAdacentValueParsingPattern() {
+ // patterns A*, N*, n* will not take part in adjacent value parsing
+ DateTimeFormatter.ofPattern("yyyyAA").parse("201610");
+ }
//-----------------------------------------------------------------------
@Test
--- a/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java Fri May 06 11:23:49 2016 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java Fri May 06 12:48:19 2016 +0000
@@ -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
@@ -746,17 +746,17 @@
{"SSS", "Fraction(NanoOfSecond,3,3)"},
{"SSSSSSSSS", "Fraction(NanoOfSecond,9,9)"},
- {"A", "Value(MilliOfDay)"},
- {"AA", "Value(MilliOfDay,2)"},
- {"AAA", "Value(MilliOfDay,3)"},
+ {"A", "Value(MilliOfDay,1,19,NOT_NEGATIVE)"},
+ {"AA", "Value(MilliOfDay,2,19,NOT_NEGATIVE)"},
+ {"AAA", "Value(MilliOfDay,3,19,NOT_NEGATIVE)"},
- {"n", "Value(NanoOfSecond)"},
- {"nn", "Value(NanoOfSecond,2)"},
- {"nnn", "Value(NanoOfSecond,3)"},
+ {"n", "Value(NanoOfSecond,1,19,NOT_NEGATIVE)"},
+ {"nn", "Value(NanoOfSecond,2,19,NOT_NEGATIVE)"},
+ {"nnn", "Value(NanoOfSecond,3,19,NOT_NEGATIVE)"},
- {"N", "Value(NanoOfDay)"},
- {"NN", "Value(NanoOfDay,2)"},
- {"NNN", "Value(NanoOfDay,3)"},
+ {"N", "Value(NanoOfDay,1,19,NOT_NEGATIVE)"},
+ {"NN", "Value(NanoOfDay,2,19,NOT_NEGATIVE)"},
+ {"NNN", "Value(NanoOfDay,3,19,NOT_NEGATIVE)"},
{"z", "ZoneText(SHORT)"},
{"zz", "ZoneText(SHORT)"},