8148947: DateTimeFormatter pattern letter 'g'
Summary: Handled 'g' in the required places
Reviewed-by: rriggs, scolebourne
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java Fri Apr 22 13:01:41 2016 +0800
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java Fri Apr 22 05:46:54 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, 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
@@ -284,6 +284,7 @@
* D day-of-year number 189
* M/L month-of-year number/text 7; 07; Jul; July; J
* d day-of-month number 10
+ * g modified-julian-day number 2451334
*
* Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
* Y week-based-year year 1996; 96
@@ -308,10 +309,10 @@
*
* V time-zone ID zone-id America/Los_Angeles; Z; -08:30
* z time-zone name zone-name Pacific Standard Time; PST
- * O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
- * X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
- * x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
- * Z zone-offset offset-Z +0000; -0800; -08:00;
+ * O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00
+ * X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15
+ * x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15
+ * Z zone-offset offset-Z +0000; -0800; -08:00
*
* p pad next pad modifier 1
*
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Fri Apr 22 13:01:41 2016 +0800
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Fri Apr 22 05:46:54 2016 +0000
@@ -90,6 +90,7 @@
import java.time.format.DateTimeTextProvider.LocaleStore;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
+import java.time.temporal.JulianFields;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalQueries;
@@ -1383,6 +1384,7 @@
* D day-of-year number 189
* M/L month-of-year number/text 7; 07; Jul; July; J
* d day-of-month number 10
+ * g modified-julian-day number 2451334
*
* Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
* Y week-based-year year 1996; 96
@@ -1408,9 +1410,9 @@
* V time-zone ID zone-id America/Los_Angeles; Z; -08:30
* z time-zone name zone-name Pacific Standard Time; PST
* O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
- * X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
- * x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
- * Z zone-offset offset-Z +0000; -0800; -08:00;
+ * X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15
+ * x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15
+ * Z zone-offset offset-Z +0000; -0800; -08:00
*
* p pad next pad modifier 1
*
@@ -1437,37 +1439,37 @@
* GGGG 4 appendText(ChronoField.ERA, TextStyle.FULL)
* GGGGG 5 appendText(ChronoField.ERA, TextStyle.NARROW)
*
- * u 1 appendValue(ChronoField.YEAR, 1, 19, SignStyle.NORMAL);
- * uu 2 appendValueReduced(ChronoField.YEAR, 2, 2000);
- * uuu 3 appendValue(ChronoField.YEAR, 3, 19, SignStyle.NORMAL);
- * u..u 4..n appendValue(ChronoField.YEAR, n, 19, SignStyle.EXCEEDS_PAD);
- * y 1 appendValue(ChronoField.YEAR_OF_ERA, 1, 19, SignStyle.NORMAL);
- * yy 2 appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000);
- * yyy 3 appendValue(ChronoField.YEAR_OF_ERA, 3, 19, SignStyle.NORMAL);
- * y..y 4..n appendValue(ChronoField.YEAR_OF_ERA, n, 19, SignStyle.EXCEEDS_PAD);
+ * u 1 appendValue(ChronoField.YEAR, 1, 19, SignStyle.NORMAL)
+ * uu 2 appendValueReduced(ChronoField.YEAR, 2, 2000)
+ * uuu 3 appendValue(ChronoField.YEAR, 3, 19, SignStyle.NORMAL)
+ * u..u 4..n appendValue(ChronoField.YEAR, n, 19, SignStyle.EXCEEDS_PAD)
+ * y 1 appendValue(ChronoField.YEAR_OF_ERA, 1, 19, SignStyle.NORMAL)
+ * yy 2 appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000)
+ * yyy 3 appendValue(ChronoField.YEAR_OF_ERA, 3, 19, SignStyle.NORMAL)
+ * y..y 4..n appendValue(ChronoField.YEAR_OF_ERA, n, 19, SignStyle.EXCEEDS_PAD)
* Y 1 append special localized WeekFields element for numeric week-based-year
- * YY 2 append special localized WeekFields element for reduced numeric week-based-year 2 digits;
- * YYY 3 append special localized WeekFields element for numeric week-based-year (3, 19, SignStyle.NORMAL);
- * Y..Y 4..n append special localized WeekFields element for numeric week-based-year (n, 19, SignStyle.EXCEEDS_PAD);
+ * YY 2 append special localized WeekFields element for reduced numeric week-based-year 2 digits
+ * YYY 3 append special localized WeekFields element for numeric week-based-year (3, 19, SignStyle.NORMAL)
+ * Y..Y 4..n append special localized WeekFields element for numeric week-based-year (n, 19, SignStyle.EXCEEDS_PAD)
*
- * Q 1 appendValue(IsoFields.QUARTER_OF_YEAR);
- * QQ 2 appendValue(IsoFields.QUARTER_OF_YEAR, 2);
+ * Q 1 appendValue(IsoFields.QUARTER_OF_YEAR)
+ * QQ 2 appendValue(IsoFields.QUARTER_OF_YEAR, 2)
* QQQ 3 appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.SHORT)
* QQQQ 4 appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.FULL)
* QQQQQ 5 appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.NARROW)
- * q 1 appendValue(IsoFields.QUARTER_OF_YEAR);
- * qq 2 appendValue(IsoFields.QUARTER_OF_YEAR, 2);
+ * q 1 appendValue(IsoFields.QUARTER_OF_YEAR)
+ * qq 2 appendValue(IsoFields.QUARTER_OF_YEAR, 2)
* qqq 3 appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.SHORT_STANDALONE)
* qqqq 4 appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.FULL_STANDALONE)
* qqqqq 5 appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.NARROW_STANDALONE)
*
- * M 1 appendValue(ChronoField.MONTH_OF_YEAR);
- * MM 2 appendValue(ChronoField.MONTH_OF_YEAR, 2);
+ * M 1 appendValue(ChronoField.MONTH_OF_YEAR)
+ * MM 2 appendValue(ChronoField.MONTH_OF_YEAR, 2)
* MMM 3 appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT)
* MMMM 4 appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL)
* MMMMM 5 appendText(ChronoField.MONTH_OF_YEAR, TextStyle.NARROW)
- * L 1 appendValue(ChronoField.MONTH_OF_YEAR);
- * LL 2 appendValue(ChronoField.MONTH_OF_YEAR, 2);
+ * L 1 appendValue(ChronoField.MONTH_OF_YEAR)
+ * LL 2 appendValue(ChronoField.MONTH_OF_YEAR, 2)
* LLL 3 appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE)
* LLLL 4 appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL_STANDALONE)
* LLLLL 5 appendText(ChronoField.MONTH_OF_YEAR, TextStyle.NARROW_STANDALONE)
@@ -1481,6 +1483,7 @@
* DD 2 appendValue(ChronoField.DAY_OF_YEAR, 2)
* 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)
* E 1 appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
* EE 2 appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
* EEE 3 appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
@@ -1539,8 +1542,8 @@
* <pre>
* Pattern Count Equivalent builder methods
* ------- ----- --------------------------
- * O 1 appendLocalizedOffset(TextStyle.SHORT);
- * OOOO 4 appendLocalizedOffset(TextStyle.FULL);
+ * O 1 appendLocalizedOffset(TextStyle.SHORT)
+ * OOOO 4 appendLocalizedOffset(TextStyle.FULL)
* X 1 appendOffset("+HHmm","Z")
* XX 2 appendOffset("+HHMM","Z")
* XXX 3 appendOffset("+HH:MM","Z")
@@ -1554,7 +1557,7 @@
* Z 1 appendOffset("+HHMM","+0000")
* ZZ 2 appendOffset("+HHMM","+0000")
* ZZZ 3 appendOffset("+HHMM","+0000")
- * ZZZZ 4 appendLocalizedOffset(TextStyle.FULL);
+ * ZZZZ 4 appendLocalizedOffset(TextStyle.FULL)
* ZZZZZ 5 appendOffset("+HH:MM:ss","Z")
* </pre>
* <p>
@@ -1836,6 +1839,9 @@
throw new IllegalArgumentException("Too many pattern letters: " + cur);
}
break;
+ case 'g':
+ appendValue(field, count, 19, SignStyle.NORMAL);
+ break;
default:
if (count == 1) {
appendValue(field);
@@ -1874,6 +1880,7 @@
FIELD_MAP.put('A', ChronoField.MILLI_OF_DAY); // LDML
FIELD_MAP.put('n', ChronoField.NANO_OF_SECOND); // 310 (proposed for LDML)
FIELD_MAP.put('N', ChronoField.NANO_OF_DAY); // 310 (proposed for LDML)
+ FIELD_MAP.put('g', JulianFields.MODIFIED_JULIAN_DAY);
// 310 - z - time-zone names, matches LDML and SimpleDateFormat 1 to 4
// 310 - Z - matches SimpleDateFormat and LDML
// 310 - V - time-zone id, matches LDML
@@ -1884,7 +1891,6 @@
// LDML - U - cycle year name, not supported by 310 yet
// LDML - l - deprecated
// LDML - j - not relevant
- // LDML - g - modified-julian-day
// LDML - v,V - extended time-zone names
}
--- a/jdk/src/java.base/share/classes/java/time/temporal/JulianFields.java Fri Apr 22 13:01:41 2016 +0800
+++ b/jdk/src/java.base/share/classes/java/time/temporal/JulianFields.java Fri Apr 22 05:46:54 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
@@ -117,7 +117,13 @@
*
* <h3>Astronomical and Scientific Notes</h3>
* The standard astronomical definition uses a fraction to indicate the time-of-day,
- * thus 3.25 would represent the time 18:00, since days start at midday.
+ * where each day is counted from midday to midday. For example,
+ * a fraction of 0 represents midday, a fraction of 0.25
+ * represents 18:00, a fraction of 0.5 represents midnight and a fraction
+ * of 0.75 represents 06:00.
+ * <p>
+ * By contrast, this implementation has no fractional part, and counts
+ * days from midnight to midnight.
* This implementation uses an integer and days starting at midnight.
* The integer value for the Julian Day Number is the astronomical Julian Day value at midday
* of the date in question.
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java Fri Apr 22 13:01:41 2016 +0800
+++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java Fri Apr 22 05:46:54 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
@@ -661,6 +661,8 @@
{"W"},
{"W"},
+ {"g"},
+ {"ggggg"},
};
}
@@ -762,6 +764,37 @@
}
//-----------------------------------------------------------------------
+ @DataProvider(name="modJulianFieldPattern")
+ Object[][] data_modJuilanFieldPattern() {
+ return new Object[][] {
+ {"g", "1"},
+ {"g", "123456"},
+ {"gggggg", "123456"},
+ };
+ }
+
+ @Test(dataProvider="modJulianFieldPattern")
+ public void test_modJulianFieldPattern(String pattern, String input) throws Exception {
+ DateTimeFormatter.ofPattern(pattern).parse(input);
+ }
+
+ @DataProvider(name="modJulianFieldValues")
+ Object[][] data_modJuilanFieldValues() {
+ return new Object[][] {
+ {1970, 1, 1, "40587"},
+ {1858, 11, 17, "0"},
+ {1858, 11, 16, "-1"},
+ };
+ }
+
+ @Test(dataProvider="modJulianFieldValues")
+ public void test_modJulianFieldValues(int y, int m, int d, String expected) throws Exception {
+ DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern("g").toFormatter();
+ assertEquals(LocalDate.of(y, m, d).format(df), expected);
+ }
+
+
+ //-----------------------------------------------------------------------
@Test
public void test_adjacent_strict_firstFixedWidth() throws Exception {
// succeeds because both number elements are fixed width