" +
+ out + "; want \"" + DATA[i+1+j] + '"');
+ }
+ String pat = cf.toPattern();
+ String pat2 = new ChoiceFormat(pat).toPattern();
+ if (!pat.equals(pat2))
+ errln("Fail: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"');
+ else
+ logln("Ok: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"');
+ }
+ catch (IllegalArgumentException e) {
+ errln("Fail: Pattern \"" + DATA[i] + "\" -> " + e);
+ }
+ }
+ }
+
+ /**
+ * @bug 4112104
+ * MessageFormat.equals(null) throws a NullPointerException. The JLS states
+ * that it should return false.
+ */
+ public void Test4112104() {
+ MessageFormat format = new MessageFormat("");
+ try {
+ // This should NOT throw an exception
+ if (format.equals(null)) {
+ // It also should return false
+ errln("MessageFormat.equals(null) returns false");
+ }
+ }
+ catch (NullPointerException e) {
+ errln("MessageFormat.equals(null) throws " + e);
+ }
+ }
+
+ /**
+ * @bug 4169959
+ * MessageFormat does not format null objects. CANNOT REPRODUCE THIS BUG.
+ */
+ public void Test4169959() {
+ // This works
+ logln(MessageFormat.format( "This will {0}",
+ new String[]{"work"} ) );
+
+ // This fails
+ logln(MessageFormat.format( "This will {0}",
+ new Object[]{ null } ) );
+ }
+
+ public void test4232154() {
+ boolean gotException = false;
+ try {
+ MessageFormat format = new MessageFormat("The date is {0:date}");
+ } catch (Exception e) {
+ gotException = true;
+ if (!(e instanceof IllegalArgumentException)) {
+ throw new RuntimeException("got wrong exception type");
+ }
+ if ("argument number too large at ".equals(e.getMessage())) {
+ throw new RuntimeException("got wrong exception message");
+ }
+ }
+ if (!gotException) {
+ throw new RuntimeException("didn't get exception for invalid input");
+ }
+ }
+
+ public void test4293229() {
+ MessageFormat format = new MessageFormat("'''{'0}'' '''{0}'''");
+ Object[] args = { null };
+ String expected = "'{0}' '{0}'";
+ String result = format.format(args);
+ if (!result.equals(expected)) {
+ throw new RuntimeException("wrong format result - expected \"" +
+ expected + "\", got \"" + result + "\"");
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/MessageFormat/MessageTest.java b/jdk/test/java/text/Format/MessageFormat/MessageTest.java
new file mode 100644
index 00000000000..9234ae90c9f
--- /dev/null
+++ b/jdk/test/java/text/Format/MessageFormat/MessageTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1997 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /java/text/testlib
+ * @summary test MessageFormat
+ */
+/*
+(C) Copyright Taligent, Inc. 1996 - All Rights Reserved
+(C) Copyright IBM Corp. 1996 - All Rights Reserved
+
+ The original version of this source code and documentation is copyrighted and
+owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
+provided under terms of a License Agreement between Taligent and Sun. This
+technology is protected by multiple US and International patents. This notice and
+attribution to Taligent may not be removed.
+ Taligent is a registered trademark of Taligent, Inc.
+*/
+
+
+import java.util.*;
+import java.io.*;
+import java.text.*;
+
+public class MessageTest extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new MessageTest().run(args);
+ }
+
+
+ public void TestMSGPatternTest() {
+ Object[] testArgs = {
+ new Double (1), new Double(3456),
+ "Disk", new Date(10000000000L)};
+
+ String[] testCases = {
+ "Quotes '', '{', 'a' {0} '{0}'",
+ "Quotes '', '{', 'a' {0,number} '{0}'",
+ "'{'1,number,'#',##} {1,number,'#',##}",
+ "There are {1} files on {2} at {3}",
+ "On {2}, there are {1} files, with {0,number,currency}.",
+ "'{1,number,percent}', {1,number,percent}, ",
+ "'{1,date,full}', {1,date,full}, ",
+ "'{3,date,full}', {3,date,full}, ",
+ "'{1,number,#,##}' {1,number,#,##}",
+ };
+
+ for (int i = 0; i < testCases.length; ++i) {
+ Locale save = Locale.getDefault();
+ try {
+ Locale.setDefault(Locale.US);
+ logln("");
+ logln( i + " Pat in: " + testCases[i]);
+ MessageFormat form = new MessageFormat(testCases[i]);
+ logln( i + " Pat out: " + form.toPattern());
+ String result = form.format(testArgs);
+ logln( i + " Result: " + result);
+ Object[] values = form.parse(result);
+ for (int j = 0; j < testArgs.length; ++j) {
+ Object testArg = testArgs[j];
+ Object value = null;
+ if (j < values.length) {
+ value = values[j];
+ }
+ if ((testArg == null && value != null)
+ || (testArg != null && !testArg.equals(value))) {
+ logln( i + " " + j + " old: " + testArg);
+ logln( i + " " + j + " new: " + value);
+ }
+ }
+ }
+ catch(java.text.ParseException pe ) {
+ throw new RuntimeException("Error: MessageFormat.parse throws ParseException");
+ }
+ finally{
+ Locale.setDefault(save);
+ }
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/MessageFormat/bug4492719.java b/jdk/test/java/text/Format/MessageFormat/bug4492719.java
new file mode 100644
index 00000000000..6a1d2184ffe
--- /dev/null
+++ b/jdk/test/java/text/Format/MessageFormat/bug4492719.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2001, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ *
+ * @bug 4492719
+ * @library /java/text/testlib
+ * @summary Confirm that Message.parse() interprets time zone which uses "GMT+/-" format correctly and doesn't throw ParseException.
+ */
+
+import java.util.*;
+import java.text.*;
+
+public class bug4492719 extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ Locale savedLocale = Locale.getDefault();
+ TimeZone savedTimeZone = TimeZone.getDefault();
+ MessageFormat mf;
+ boolean err =false;
+
+ String[] formats = {
+ "short", "medium", "long", "full"
+ };
+ String[] timezones = {
+ "America/Los_Angeles", "GMT", "GMT+09:00", "GMT-8:00",
+ "GMT+123", "GMT-1234", "GMT+2", "GMT-13"
+ };
+ String text;
+
+ Locale.setDefault(Locale.US);
+
+ try {
+ for (int i = 0; i < timezones.length; i++) {
+ TimeZone.setDefault(TimeZone.getTimeZone(timezones[i]));
+
+ for (int j = 0; j < formats.length; j++) {
+ mf = new MessageFormat("{0,time," + formats[j] + "} - time");
+ text = MessageFormat.format("{0,time," + formats[j] + "} - time",
+ new Object [] { new Date(123456789012L)});
+ Object[] objs = mf.parse(text);
+ }
+ }
+ } catch (ParseException e) {
+ err = true;
+ System.err.println("Invalid ParseException occurred : " +
+ e.getMessage());
+ System.err.println(" TimeZone=" + TimeZone.getDefault());
+ }
+ finally {
+ Locale.setDefault(savedLocale);
+ TimeZone.setDefault(savedTimeZone);
+ if (err) {
+ throw new Exception("MessageFormat.parse(\"GMT format\") failed.");
+ }
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/BigDecimalCompatibilityTest.java b/jdk/test/java/text/Format/NumberFormat/BigDecimalCompatibilityTest.java
new file mode 100644
index 00000000000..1a2e7bf3945
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/BigDecimalCompatibilityTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4018937
+ * @summary Confirm that DecimalFormat.parse() parses BigDecimal and BigInteger as expected.
+ */
+
+import java.math.*;
+import java.text.*;
+import java.util.*;
+
+public class BigDecimalCompatibilityTest {
+
+ static boolean err = false;
+
+ static final String[] input_data = {
+ "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
+ };
+ static final String[] exponents = {
+ "E-100", "E100", "E-900", "E900", ""
+ };
+ static final int[] multipliers = {
+ -1, 1, -100, 100, -9999, 9999
+ };
+
+ public static void main(String[] args) throws Exception {
+ Locale loc = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+
+ testBigDecimal();
+ testBigInteger();
+
+ Locale.setDefault(loc);
+
+ if (err) {
+ throw new RuntimeException("Error: Unexpected value");
+ }
+ }
+
+ static private void testBigDecimal() {
+ DecimalFormat df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+ df.setMaximumFractionDigits(Integer.MAX_VALUE);
+
+ for (int i = 0; i < input_data.length; i++) {
+ for (int j = 0; j < input_data.length; j++) {
+ for (int k = 0; k < input_data.length; k++) {
+ for (int l = 0; l < input_data.length; l++) {
+ for (int m = 0; m < exponents.length; m++) {
+ String s = input_data[i] + input_data[j] + '.' +
+ input_data[k] + input_data[l] +
+ exponents[m];
+ for (int n = 0; n < multipliers.length; n++) {
+ test(df, s, multipliers[n]);
+ test(df, '-'+s, multipliers[n]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ static private void testBigInteger() {
+ DecimalFormat df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+ df.setMaximumFractionDigits(Integer.MAX_VALUE);
+
+ for (int i = 0; i < input_data.length; i++) {
+ for (int j = 0; j < input_data.length; j++) {
+ String s = input_data[i] + input_data[j];
+ for (int k = 0; k < multipliers.length; k++) {
+ test(df, s, multipliers[k]);
+ test(df, '-'+s, multipliers[k]);
+ }
+ }
+ }
+ }
+
+ static void test(DecimalFormat df, String s, int multiplier) {
+ df.setMultiplier(multiplier);
+
+ Number num = null;
+ try {
+ num = df.parse(s);
+ }
+ catch (ParseException e) {
+ err = true;
+ System.err.println("Failed: Exception occurred: " + e.getMessage());
+ return;
+ }
+
+ BigDecimal bd = new BigDecimal(s);
+ try {
+ bd = bd.divide(new BigDecimal(multiplier));
+ }
+ catch (ArithmeticException e) {
+ bd = bd.divide(new BigDecimal(multiplier), BigDecimal.ROUND_HALF_EVEN);
+ }
+ check(num, bd, multiplier);
+ }
+
+ static void check(Number got, BigDecimal expected, int multiplier) {
+ if (!got.equals(expected)) {
+ err = true;
+ System.err.println("Failed: got:" + got +
+ ", expected: " + expected +
+ ", multiplier=" + multiplier);
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/BigDecimalFormat.java b/jdk/test/java/text/Format/NumberFormat/BigDecimalFormat.java
new file mode 100644
index 00000000000..14b3a9fec62
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/BigDecimalFormat.java
@@ -0,0 +1,1044 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4018937 8008577
+ * @summary Confirm that methods which are newly added to support BigDecimal and BigInteger work as expected.
+ * @library /java/text/testlib
+ * @run main/othervm -Djava.locale.providers=COMPAT,SPI BigDecimalFormat
+ */
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.text.*;
+import java.util.*;
+
+public class BigDecimalFormat extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new BigDecimalFormat().run(args);
+ }
+
+ static final String nonsep_int =
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890";
+
+ static final String sep_int =
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890";
+
+ static final String nonsep_zero =
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000";
+
+ static final String sep_zero =
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000";
+
+ static final String fra =
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789";
+
+
+ StringBuffer formatted = new StringBuffer(1000);
+ FieldPosition fp;
+
+ /**
+ * Test for normal big numbers which have the fraction part
+ */
+ void test_Format_in_NumberFormat_BigDecimal() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+
+ // From: 0.000...789
+ // To: 0.000...789 (same as From)
+ formatted.setLength(0);
+ from = "0." + nonsep_zero + "123456789";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, from, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -0.000...789
+ // To: -0.000...789 (same as From)
+ // ~ : FieldPosition(SIGN)
+ fp = new FieldPosition(NumberFormat.Field.SIGN);
+ formatted.setLength(0);
+ from = "-0." + nonsep_zero + "123456789";
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, from, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 0, 1);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 1234...7890.012...789
+ // To: 123,4...7,890.012...789
+ // ~~~~~~~~~~~~~ : FieldPosition(INTEGER_FIELD)
+ fp = new FieldPosition(DecimalFormat.INTEGER_FIELD);
+ formatted.setLength(0);
+ from = nonsep_int + "." + fra;
+ to = sep_int + "." + fra;
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 0, 479);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...7890.012...789
+ // To: -123,4...7,890.012...789
+ // ~~~~~~~~~ : FieldPosition(FRACTION_FIELD)
+ fp = new FieldPosition(DecimalFormat.FRACTION_FIELD);
+ formatted.setLength(0);
+ from = "-" + nonsep_int + "." + fra;
+ to = "-" + sep_int + "." + fra;
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 481, 841);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 1234...78900000...0000.000...789
+ // To: 123,4...7,890,000,0...0,000.000...789
+ formatted.setLength(0);
+ from = nonsep_int + nonsep_zero + "." + nonsep_zero + fra;
+ to = sep_int + "," + sep_zero + "." + nonsep_zero + fra;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...78900000...0000.000...789
+ // To: -123,4...7,890,000,0...0,000.000...789
+ formatted.setLength(0);
+ from = "-" + nonsep_int + nonsep_zero + "." + nonsep_zero + fra;
+ to = "-" + sep_int + "," + sep_zero + "." + nonsep_zero + fra;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 1234...78900000...0000
+ // To: 123,4...7,890,000,0...0,000
+ formatted.setLength(0);
+ from = nonsep_int + nonsep_zero;
+ to = sep_int + "," + sep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...78900000...0000
+ // To: -123,4...7,890,000,0...0,000
+ formatted.setLength(0);
+ from = "-" + nonsep_int + nonsep_zero;
+ to = "-" + sep_int + "," + sep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 1234...78900000...0000.0...0
+ // To: 1,234...7,890,000,0...0,000
+ formatted.setLength(0);
+ from = nonsep_int + nonsep_zero + "." + nonsep_zero;
+ to = sep_int + "," + sep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...78900000...0000.0...0
+ // To: -1,234...7,890,000,0...0,000
+ formatted.setLength(0);
+ from = "-" + nonsep_int + nonsep_zero + "." + nonsep_zero;
+ to = "-" + sep_int + "," + sep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 000...0000
+ // To: 0
+ formatted.setLength(0);
+ from = nonsep_zero;
+ to = "0";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -000...0000
+ // To: 0
+ formatted.setLength(0);
+ from = "-" + nonsep_zero;
+ to = "0";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 000...00001234
+ // To: 1,234
+ formatted.setLength(0);
+ from = nonsep_zero + "1234";
+ to = "1,234";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -000...00001234
+ // To: -1,234
+ // ~ : FieldPosition(GROUPING_SEPARATOR)
+ fp = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR);
+ formatted.setLength(0);
+ from = "-" + nonsep_zero + "1234";
+ to = "-1,234";
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 2, 3);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 000...0000.0...0
+ // To: 0
+ formatted.setLength(0);
+ from = nonsep_zero + "." + nonsep_zero;
+ to = "0";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.0");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 1);
+
+ // From: -000...0000.0...0
+ // To: 0.0
+ formatted.setLength(0);
+ from = "-" + nonsep_zero + "." + nonsep_zero;
+ to = "0.0";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 1234...7890.012...7890...0
+ // To: 1,234...7,890.0123...789
+ formatted.setLength(0);
+ from = nonsep_int + "." + fra + nonsep_zero;
+ to = sep_int + "." + fra;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...7890.012...7890...0
+ // To: -1,234...7,890.0123...789
+ formatted.setLength(0);
+ from = "-" + nonsep_int + "." + fra + nonsep_zero;
+ to = "-" + sep_int + "." + fra;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ setDigits(nf, 1, 1, Integer.MAX_VALUE, 0);
+
+ // From: 1123...890.012...789
+ // To : 1.123...8900123...789E360
+ // ~~~ : FieldPosition(EXPONENT)
+ fp = new FieldPosition(NumberFormat.Field.EXPONENT);
+ formatted.setLength(0);
+ from = "1" + nonsep_int + "." + fra;
+ to = "1." + nonsep_int + fra + "E360";
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 723, 726);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1123...890.012...789
+ // To : -1.123...8900123...789E360
+ formatted.setLength(0);
+ from = "-1" + nonsep_int + "." + fra;
+ to = "-1." + nonsep_int + fra + "E360";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ setDigits(nf, 1, 1, Integer.MAX_VALUE, 0);
+
+ // From: 0.000...0001123...890.012...789
+ // To : 1.123...8900123...789E-360
+ formatted.setLength(0);
+ from = "0." + nonsep_zero + "1" + fra;
+ to = "1." + fra + "E-361";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -0.000...0001123...890.012...789
+ // To : -1.123...8900123...789E-360
+ formatted.setLength(0);
+ from = "-0." + nonsep_zero + "1" + fra;
+ to = "-1." + fra + "E-361";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 1123...890.012...789000...000
+ // To : 1.123...8900123...789E360
+ formatted.setLength(0);
+ from = "1" + nonsep_int + "." + fra + nonsep_zero;
+ to = "1." + nonsep_int + fra + "E360";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1123...890.012...789000...000
+ // To : -1.123...8900123...789E360
+ // ~ : FieldPosition(EXPONENT_SYMBOL)
+ fp = new FieldPosition(NumberFormat.Field.EXPONENT_SYMBOL);
+ formatted.setLength(0);
+ from = "-1" + nonsep_int + "." + fra + nonsep_zero;
+ to = "-1." + nonsep_int + fra + "E360";
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 723, 724);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 0.000...0001123...890.012...789000...000
+ // To : 1.123...8900123...789E-360
+ // ~ : FieldPosition(EXPONENT_SIGN)
+ fp = new FieldPosition(NumberFormat.Field.EXPONENT_SIGN);
+ formatted.setLength(0);
+ from = "0." + nonsep_zero + "1" + fra + nonsep_zero;
+ to = "1." + fra + "E-361";
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 363, 364);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -0.000...0001123...890.012...789000...000
+ // To : -1.123...8900123...789E-360
+ formatted.setLength(0);
+ from = "-0." + nonsep_zero + "1" + fra + nonsep_zero;
+ to = "-1." + fra + "E-361";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: ABC1123...890.012...789
+ // To : ABC1.123...890.0123...789
+ formatted = new StringBuffer("ABC");
+ from = "1" + nonsep_int + "." + fra;
+ to = "ABC1." + nonsep_int + fra + "E360";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: ABC-1123...890.012...789
+ // To : ABC-1.123...890.0123...789
+ // ~ : FieldPosition(DECIMAL_SEPARATOR)
+ fp = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
+ formatted = new StringBuffer("ABC");
+ from = "-1" + nonsep_int + "." + fra;
+ to = "ABC-1." + nonsep_int + fra + "E360";
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 5, 6);
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, 726, 0);
+
+ // From: 0.000...000012...7890123456789
+ // To: 0.000...000012...789012346 (Shorter than From)
+ formatted.setLength(0);
+ from = "0." + nonsep_zero + fra + fra;
+ to = "0." + nonsep_zero + fra + "012346";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, 723, 0);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -0.000...000012...7890123456789
+ // To: -0.000...000012...789012 (Shorter than From)
+ formatted.setLength(0);
+ from = "-0." + nonsep_zero + fra + fra;
+ to = "-0." + nonsep_zero + fra + "012";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("00000.###E0");
+ setDigits(nf, 5, 5, 370, 0);
+
+ // From: 1234567890.012...78901234567890
+ // To: 12345.67890012...789012346E5
+ formatted.setLength(0);
+ from = "1234567890." + fra + "0123456789";
+ to = "12345.67890" + fra + "01235E5";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ setDigits(nf, 1, 1, 364, 0);
+
+ // From: -0.000...0001012...7890123456789
+ // To: -1.012...789012E-361
+ formatted.setLength(0);
+ from = "-0." + nonsep_zero + "1" + fra + "0123456789";
+ to = "-1." + fra + "0123E-361";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ setDigits(nf, 1, 1, 366, 0);
+
+ // From: 1012...78901234567890
+ // To: 1.012...789012346E370
+ formatted.setLength(0);
+ from = "1" + fra + "0123456789";
+ to = "1." + fra + "012346E370";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ setDigits(nf, 1, 1, 363, 0);
+
+ // From: -1012...7890123456789
+ // To: -1.012...789012E370
+ formatted.setLength(0);
+ from = "-1" + fra + "0123456789";
+ to = "-1." + fra + "012E370";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 720);
+
+ // From: 1234...78900000...0000.0...0
+ // To: 1,234...7,890,000,0...0,000.0...0
+ formatted.setLength(0);
+ from = nonsep_int + nonsep_zero + "." + nonsep_zero + nonsep_zero;
+ to = sep_int + "," + sep_zero + "." + nonsep_zero + nonsep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...78900000...0000.0...0
+ // To: -1,234...7,890,000,0...0,000.0...0
+ formatted.setLength(0);
+ from = "-" + nonsep_int + nonsep_zero + "." + nonsep_zero + nonsep_zero;
+ to = "-" + sep_int + "," + sep_zero + "." + nonsep_zero + nonsep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ }
+
+ /**
+ * Test for normal big numbers which have the fraction part with multiplier
+ */
+ void test_Format_in_NumberFormat_BigDecimal_usingMultiplier() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+ ((DecimalFormat)nf).setMultiplier(250000000);
+ ((DecimalFormat)nf).setDecimalSeparatorAlwaysShown(true);
+
+ // From: 1000...0000.000...000
+ // To: 250,0...0,000.
+ formatted.setLength(0);
+ from = "1" + nonsep_zero + "." + nonsep_zero;
+ to = "250,000,000," + sep_zero + ".";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).setDecimalSeparatorAlwaysShown(false);
+
+ // From: -1000...0000.000...000
+ // To: -250,0...0,000
+ formatted.setLength(0);
+ from = "-1" + nonsep_zero + "." + nonsep_zero;
+ to = "-250,000,000," + sep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+ ((DecimalFormat)nf).setMultiplier(-250000000);
+ ((DecimalFormat)nf).setDecimalSeparatorAlwaysShown(true);
+
+ // From: 1000...0000.000...000
+ // To: -250,0...0,000.
+ formatted.setLength(0);
+ from = "1" + nonsep_zero + "." + nonsep_zero;
+ to = "-250,000,000," + sep_zero + ".";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).setDecimalSeparatorAlwaysShown(false);
+
+ // From: -1000...0000.000...000
+ // To: 250,0...0,000
+ formatted.setLength(0);
+ from = "-1" + nonsep_zero + "." + nonsep_zero;
+ to = "250,000,000," + sep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ }
+
+ /**
+ * Test for normal big numbers which don't have the fraction part
+ */
+ void test_Format_in_NumberFormat_BigInteger() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ if (!(nf instanceof DecimalFormat)) {
+ throw new RuntimeException("Couldn't get DecimalFormat instance.");
+ }
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+
+ // From: 1234...7890
+ // To: 123,4...7,890
+ formatted.setLength(0);
+ from = nonsep_int;
+ to = sep_int;
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...7890
+ // To: -123,4...7,890
+ // ~~~~~~~~~~~~~ : FieldPosition(INTEGER_FIELD)
+ fp = new FieldPosition(DecimalFormat.INTEGER_FIELD);
+ formatted.setLength(0);
+ from = "-" + nonsep_int;
+ to = "-" + sep_int;
+ nf.format(new BigInteger(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 1, 480);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 000...0001234...7890
+ // To: 123,4...7,890
+ formatted.setLength(0);
+ from = nonsep_zero + nonsep_int;
+ to = sep_int;
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -000...0001234...7890
+ // To: -123,4...7,890
+ // ~ : FieldPosition(SIGN)
+ fp = new FieldPosition(NumberFormat.Field.SIGN);
+ formatted.setLength(0);
+ from = "-" + nonsep_zero + nonsep_int;
+ to = "-" + sep_int;
+ nf.format(new BigInteger(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 0, 1);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 000...0000
+ // To: 0
+ formatted.setLength(0);
+ from = nonsep_zero;
+ to = "0";
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.0");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 1);
+
+ // From: -000...0000
+ // To: 0.0
+ fp = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
+ formatted.setLength(0);
+ from = "-" + nonsep_zero;
+ to = "0.0";
+ nf.format(new BigInteger(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 1, 2);
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ setDigits(nf, 1, 1, Integer.MAX_VALUE, 0);
+
+ // From: 10123...789
+ // To : 1.0123...789E360
+ // ~~~ : FieldPosition(EXPONENT)
+ fp = new FieldPosition(NumberFormat.Field.EXPONENT);
+ formatted.setLength(0);
+ from = "1" + fra;
+ to = "1." + fra + "E360";
+ nf.format(new BigInteger(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 363, 366);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1012...789
+ // To : -1.012...789E360
+ formatted.setLength(0);
+ from = "-1" + fra;
+ to = "-1." + fra + "E360";
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("00000.###E0");
+ setDigits(nf, 5, 5, Integer.MAX_VALUE, 720);
+
+ // From: 12345012...789000...000
+ // To : 12345.012...789000...000E720
+ // ~~~ : FieldPosition(EXPONENT)
+ fp = new FieldPosition(NumberFormat.Field.EXPONENT);
+ formatted.setLength(0);
+ from = "12345" + fra + nonsep_zero;
+ to = "12345." + fra + nonsep_zero + "E720";
+ nf.format(new BigInteger(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 727, 730);
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("00000.###E0");
+ setDigits(nf, 5, 5, Integer.MAX_VALUE, 365);
+
+ // From: -1234567890012...789000...000
+ // To : -12345.67890012...789E365
+ formatted.setLength(0);
+ from = "-1234567890" + fra;
+ to = "-12345.67890" + fra + "E365";
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ }
+
+ /**
+ * Test for normal big numbers which don't have the fraction part with
+ * multiplier
+ */
+ void test_Format_in_NumberFormat_BigInteger_usingMultiplier() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ ((DecimalFormat)nf).setMultiplier(250000000);
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+
+ // From: 1000...0000
+ // To: 250,0...0,000
+ formatted.setLength(0);
+ from = "1" + nonsep_zero;
+ to = "250,000,000," + sep_zero;
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1000...0000
+ // To: -250,0...0,000
+ formatted.setLength(0);
+ from = "-1" + nonsep_zero;
+ to = "-250,000,000," + sep_zero;
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ ((DecimalFormat)nf).setMultiplier(-250000000);
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+
+ // From: 1000...0000
+ // To: -250,0...0,000
+ formatted.setLength(0);
+ from = "1" + nonsep_zero;
+ to = "-250,000,000," + sep_zero;
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1000...0000
+ // To: 250,0...0,000
+ formatted.setLength(0);
+ from = "-1" + nonsep_zero;
+ to = "250,000,000," + sep_zero;
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ }
+
+ /**
+ * Test for normal Long numbers when maximum and minimum digits are
+ * specified
+ */
+ void test_Format_in_NumberFormat_Long_checkDigits() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ if (!(nf instanceof DecimalFormat)) {
+ throw new RuntimeException("Couldn't get DecimalFormat instance.");
+ }
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 360, Integer.MAX_VALUE, 0);
+
+ // From: 1234567890
+ // To: 000,0...0,000,123,456,789
+ // -------------
+ // 300 zeros
+ formatted.setLength(0);
+ from = "123456789";
+ to = sep_zero.substring(0, 399) + ",123,456,789";
+ nf.format(new Long(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("##0.###");
+ ((DecimalFormat)nf).setMultiplier(-1);
+ setDigits(nf, Integer.MAX_VALUE, 360, Integer.MAX_VALUE, 360);
+
+ // From: 1234567890
+ // To: -0000...0000123456789.000...000
+ // -------------
+ // 300 zeros
+ formatted.setLength(0);
+ from = "123456789";
+ to = "-" + nonsep_zero.substring(0, 300) + "123456789." +
+ nonsep_zero.substring(0, 340);
+ nf.format(new Long(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ ((DecimalFormat)nf).setMultiplier(Integer.MAX_VALUE);
+ setDigits(nf, Integer.MAX_VALUE, 360, Integer.MAX_VALUE, 0);
+
+ // From: Long.MAX_VALUE
+ // To: 000,0...0,000,019,807,040,619,342,712,359,383,728,129
+ // ---------------
+ // 280 zeros
+ formatted.setLength(0);
+ from = Long.toString(Long.MAX_VALUE);
+ to = sep_zero.substring(0, 373) +
+ "19,807,040,619,342,712,359,383,728,129";
+ nf.format(new Long(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ ((DecimalFormat)nf).setMultiplier(Integer.MIN_VALUE);
+ setDigits(nf, 1, 1, Integer.MAX_VALUE, 360);
+
+ // From: Long.MAX_VALUE
+ // To: -1.9807040628566084396238503936000...000E28
+ // ---------
+ // 312 zeros
+ formatted.setLength(0);
+ from = Long.toString(Long.MAX_VALUE);
+ to = "-1.9807040628566084396238503936" +
+ nonsep_zero.substring(0, 312) + "E28";
+ nf.format(new Long(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("##0.###E0");
+ ((DecimalFormat)nf).setMultiplier(Integer.MAX_VALUE);
+ setDigits(nf, Integer.MAX_VALUE, 360, Integer.MAX_VALUE, 360);
+
+ // From: Long.MIN_VALUE
+ // To: -198070406193427123615312117760000...0000.000...000E-280
+ // ----------- ---------
+ // 280 zeros 340 zeros
+ formatted.setLength(0);
+ from = Long.toString(Long.MIN_VALUE);
+ to = "-19807040619342712361531211776" +
+ nonsep_zero.substring(0, 280) + "." +
+ nonsep_zero.substring(0, 340) + "E-280";
+ nf.format(new Long(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ ((DecimalFormat)nf).setMultiplier(Integer.MIN_VALUE);
+ setDigits(nf, Integer.MAX_VALUE, 360, Integer.MAX_VALUE, 360);
+
+ // From: Long.MIN_VALUE
+ // To: 000,0...0,000,019,807,040,628,566,084,398,385,987,584.000...000
+ // --------------- ---------
+ // 280 zeros 340 zeros
+ formatted.setLength(0);
+ from = Long.toString(Long.MIN_VALUE);
+ to = sep_zero.substring(0, 373) +
+ "19,807,040,628,566,084,398,385,987,584." +
+ nonsep_zero.substring(0, 340);
+ nf.format(new Long(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ }
+
+ /**
+ * Test for special numbers
+ * Double.NaN
+ * Double.POSITIVE_INFINITY
+ * Double.NEGATIVE_INFINITY
+ */
+ void test_Format_in_NumberFormat_SpecialNumber() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ if (!(nf instanceof DecimalFormat)) {
+ throw new RuntimeException("Couldn't get DecimalFormat instance.");
+ }
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+
+ double[] numbers = {
+ -0.0, 0.0, Double.NaN,
+ Double.POSITIVE_INFINITY, 5.1, 5.0,
+ Double.NEGATIVE_INFINITY, -5.1, -5.0,
+ };
+ int multipliers[] = {0, 5, -5};
+ String[][] expected = {
+ {"-0", "0", "\ufffd", "\ufffd", "0", "0", "\ufffd", "-0", "-0"},
+ {"-0", "0", "\ufffd", "\u221e", "25.5", "25", "-\u221e", "-25.5",
+ "-25"},
+ {"0", "-0", "\ufffd", "-\u221e", "-25.5", "-25", "\u221e", "25.5",
+ "25"},
+ };
+
+ for (int i = 0; i < multipliers.length; i++) {
+ ((DecimalFormat)nf).setMultiplier(multipliers[i]);
+ for (int j = 0; j < numbers.length; j++) {
+ formatted.setLength(0);
+ from = String.valueOf(numbers[j]);
+ nf.format(numbers[j], formatted, new FieldPosition(0));
+ checkFormat(from, formatted, expected[i][j],
+ ((DecimalFormat)nf).getMultiplier());
+ }
+ }
+ }
+
+ /**
+ * Test for Long.MIN_VALUE
+ * (Formatting Long.MIN_VALUE w/ multiplier=-1 used to return a wrong
+ * number.)
+ */
+ void test_Format_in_NumberFormat_Other() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ if (!(nf instanceof DecimalFormat)) {
+ throw new RuntimeException("Couldn't get DecimalFormat instance.");
+ }
+
+ long[] numbers = {
+ Long.MIN_VALUE,
+ };
+ int multipliers[] = {1, -1};
+ String[][] expected = {
+ {"-9,223,372,036,854,775,808"}, // Long.MIN_VALUE
+ {"9,223,372,036,854,775,808"}, // Long.MIN_VALUE * (-1)
+ };
+
+ for (int i = 0; i < multipliers.length; i++) {
+ ((DecimalFormat)nf).setMultiplier(multipliers[i]);
+ for (int j = 0; j < numbers.length; j++) {
+ formatted.setLength(0);
+ from = String.valueOf(numbers[j]);
+ nf.format(numbers[j], formatted, new FieldPosition(0));
+ checkFormat(from, formatted, expected[i][j],
+ ((DecimalFormat)nf).getMultiplier());
+ }
+ }
+ }
+
+ /**
+ * Test for MessageFormat
+ */
+ void test_Format_in_MessageFormat() {
+ MessageFormat mf = new MessageFormat(
+ " {0, number}\n" +
+ " {0, number, integer}\n" +
+ " {0, number, currency}\n" +
+ " {0, number, percent}\n" +
+ " {0, number,0.###########E0}\n" +
+
+ " {1, number}\n" +
+ " {1, number, integer}\n" +
+ " {1, number, currency}\n" +
+ " {1, number, percent}\n" +
+ " {1, number,0.#######E0}\n",
+ Locale.US
+ );
+ Object[] testArgs = {
+ new BigInteger("9876543210987654321098765432109876543210"),
+ new BigDecimal("-12345678901234567890.98765432109876543210987654321"),
+ };
+ String expected =
+ " 9,876,543,210,987,654,321,098,765,432,109,876,543,210\n" +
+ " 9,876,543,210,987,654,321,098,765,432,109,876,543,210\n" +
+ " $9,876,543,210,987,654,321,098,765,432,109,876,543,210.00\n" +
+ " 987,654,321,098,765,432,109,876,543,210,987,654,321,000%\n" +
+ " 9.87654321099E39\n" +
+
+ " -12,345,678,901,234,567,890.988\n" +
+ " -12,345,678,901,234,567,891\n" +
+ " ($12,345,678,901,234,567,890.99)\n" +
+ " -1,234,567,890,123,456,789,099%\n" +
+ " -1.2345679E19\n"
+ ;
+
+ if (!expected.equals(mf.format(testArgs))) {
+ errln("Wrong format.\n got:\n" + mf.format(testArgs) +
+ " expected:\n" + expected);
+ }
+ }
+
+ private void setDigits(NumberFormat nf,
+ int i_max, int i_min, int f_max, int f_min) {
+ nf.setMaximumIntegerDigits(i_max);
+ nf.setMinimumIntegerDigits(i_min);
+ nf.setMaximumFractionDigits(f_max);
+ nf.setMinimumFractionDigits(f_min);
+ }
+
+ private void checkFormat(String orig, StringBuffer got, String expected,
+ int multiplier) {
+ if (!expected.equals(new String(got))) {
+ errln("Formatting... failed." +
+ "\n original: " + orig +
+ "\n multiplier: " + multiplier +
+ "\n formatted: " + got +
+ "\n expected: " + expected + "\n");
+ }
+ }
+
+ private void checkFieldPosition(String orig, FieldPosition fp, int begin,
+ int end) {
+ int position;
+
+ if ((position = fp.getBeginIndex()) != begin) {
+ errln("Formatting... wrong Begin index returned for " +
+ fp.getFieldAttribute() + "." +
+ "\n original: " + orig +
+ "\n got: " + position +
+ "\n expected: " + begin + "\n");
+ }
+ if ((position = fp.getEndIndex()) != end) {
+ errln("Formatting... wrong End index returned for " +
+ fp.getFieldAttribute() + "." +
+ "\n original: " + orig +
+ "\n got: " + position +
+ "\n expected: " + end + "\n");
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/BigDecimalParse.java b/jdk/test/java/text/Format/NumberFormat/BigDecimalParse.java
new file mode 100644
index 00000000000..be206052d06
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/BigDecimalParse.java
@@ -0,0 +1,709 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4018937 8008577
+ * @summary Confirm that methods which are newly added to support BigDecimal and BigInteger work as expected.
+ * @library /java/text/testlib
+ * @run main/othervm -Djava.locale.providers=COMPAT,SPI BigDecimalParse
+ */
+
+import java.math.BigDecimal;
+import java.text.*;
+import java.util.*;
+
+public class BigDecimalParse extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ Locale loc = Locale.getDefault();
+ try {
+ Locale.setDefault(Locale.US);
+ new BigDecimalParse().run(args);
+ } finally {
+ // restore the reserved locale
+ Locale.setDefault(loc);
+ }
+ }
+
+ static final String nonsep_int =
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890";
+
+ static final String sep_int =
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890";
+
+ static final String nonsep_zero =
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000";
+
+ static final String sep_zero =
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000";
+
+ static final String fra =
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789";
+
+
+ Number parsed = null;
+ ParsePosition pp;
+ boolean exceptionOccurred;
+ String msg;
+ DecimalFormat df;
+
+ /**
+ * Test for normal big numbers which have the fraction part
+ */
+ void test_Parse_in_DecimalFormat_BigDecimal() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+
+ // From: 1234...7890.012...789
+ // To: BigDecimal 1234...7890.012...789
+ check(nonsep_int + "." + fra, new BigDecimal(nonsep_int + "." + fra));
+
+ // From: -1,234...7,890.012...789
+ // To: BigDecimal -1234...7890.012...789
+ check("-" + sep_int + "." + fra,
+ new BigDecimal("-" + nonsep_int + "." + fra));
+
+ // From: 000...0000.0...0
+ // To: BigDecimal 0E-360
+ check(nonsep_zero + "." + nonsep_zero,
+ new BigDecimal(nonsep_zero + "." + nonsep_zero));
+
+ // From: 0.000...0000123...789E370
+ // To: BigDecimal 0.0123...789
+ check("0.0000000000" + nonsep_zero + fra + "E370",
+ new BigDecimal("0.0000000000" + nonsep_zero + fra + "E370"));
+
+ // From: 0.1123...890E-360
+ // To: BigDecimal 1.123...890E-361
+ check("0.1" + nonsep_int + "E-360",
+ new BigDecimal("0.1" + nonsep_int + "E-360"));
+
+ // From: 000...0000.0...0123...7890
+ // To: BigDecimal 1.234...890E-361
+ check(nonsep_zero + "." + nonsep_zero + nonsep_int,
+ new BigDecimal(nonsep_zero + "." + nonsep_zero + nonsep_int));
+
+ // From: 0.123...890E360
+ // To: BigDecimal 123...890
+ check("0." + nonsep_int + "E360",
+ new BigDecimal("0." + nonsep_int + "E360"));
+ }
+
+ /**
+ * Test for normal big numbers which have the fraction part with multiplier
+ */
+ void test_Parse_in_DecimalFormat_BigDecimal_usingMultiplier() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+
+ // From: 250,0...0,000.000...000
+ // To: 1000...0000.000...000
+ df.setMultiplier(250000000);
+ check("250,000,000," + sep_zero + "." + nonsep_zero,
+ new BigDecimal("1" + nonsep_zero + "." + nonsep_zero));
+
+ // From: -250,0...0,000.000...000
+ // To: -1000...0000.000...000
+ check("-250,000,000," + sep_zero + "." + nonsep_zero,
+ new BigDecimal("-1" + nonsep_zero + "." + nonsep_zero));
+
+ // From: 250,0...0,000.000...000
+ // To: -1000...0000.000...000
+ df.setMultiplier(-250000000);
+ check("250,000,000," + sep_zero + "." + nonsep_zero,
+ new BigDecimal("-1" + nonsep_zero + "." + nonsep_zero));
+
+ // From: -250,0...0,000.000...000
+ // To: 1000...0000.000...000
+ check("-250,000,000," + sep_zero + "." + nonsep_zero,
+ new BigDecimal("1" + nonsep_zero + "." + nonsep_zero));
+
+ // Confirm that ArithmeticException is handled properly
+ // From: 1000.000
+ // To: 333.333
+ df.setMultiplier(3);
+ check("1000.000", new BigDecimal("333.333"));
+
+ // Confirm that ArithmeticException is handled properly
+ // From: 10000.0000
+ // To: 303.0303
+ df.setMultiplier(33);
+ check("10000.0000", new BigDecimal("303.0303"));
+ }
+
+ /**
+ * Test for division by zero (BigDecimal)
+ */
+ void test_Parse_in_DecimalFormat_BigDecimal_DivisionByZero() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+ df.setMultiplier(0);
+
+ // From: 1000.000
+ // To: Double.POSITIVE_INFINITY
+ check("1000.000", new Double(Double.POSITIVE_INFINITY));
+
+ // From: -1000
+ // To: Double.NEGATIVE_INFINITY
+ check("-1000", new Double(Double.NEGATIVE_INFINITY));
+
+ // From: -0.00
+ // To: Double.NaN
+ check("-0.00", new Double(Double.NaN));
+ }
+
+ /**
+ * Test for division by zero (Double)
+ */
+ void test_Parse_in_DecimalFormat_Double_DivisionByZero() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(false);
+ df.setMultiplier(0);
+
+ // From: 1000.000
+ // To: Double.POSITIVE_INFINITY
+ check("1000.000", new Double(Double.POSITIVE_INFINITY));
+
+ // From: -1000.000
+ // To: Double.NEGATIVE_INFINITY
+ check("-1000.000", new Double(Double.NEGATIVE_INFINITY));
+
+ // From: 0.0
+ // To: Double.NaN
+ check("0.0", new Double(Double.NaN));
+
+ // From: -0.0 (Double)
+ // To: Double.NaN
+ check("-0.0", new Double(Double.NaN));
+
+ // From: Double.NaN
+ // To: Double.NaN
+ check("\ufffd", new Double(Double.NaN));
+
+ // From: Double.POSITIVE_INFINITY
+ // To: Double.NaN
+ check("\u221e", new Double(Double.POSITIVE_INFINITY));
+
+ // From: Double.NEGATIVE_INFINITY
+ // To: Double.NaN
+ check("-\u221e", new Double(Double.NEGATIVE_INFINITY));
+ }
+
+ /**
+ * Test for division by zero (Long)
+ */
+ void test_Parse_in_DecimalFormat_Long_DivisionByZero() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(false);
+ df.setMultiplier(0);
+
+ // From: 1000
+ // To: Double.POSITIVE_INFINITY
+ check("1000", new Double(Double.POSITIVE_INFINITY));
+
+ // From: -1000
+ // To: Double.NEGATIVE_INFINITY
+ check("-1000", new Double(Double.NEGATIVE_INFINITY));
+
+ // From: -000 (Long)
+ // To: Double.NaN
+ check("-000", new Double(Double.NaN));
+ }
+
+ /**
+ * Test for normal big numbers which don't have the fraction part
+ */
+ void test_Parse_in_DecimalFormat_BigInteger() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+
+ // From: 123...890
+ // To: BigDecimal 123...890
+ check(nonsep_int + nonsep_int, new BigDecimal(nonsep_int + nonsep_int));
+
+ // From: 123,4...7,890
+ // To: BigDecimal 1234...7890
+ check(sep_int + "," + sep_int, new BigDecimal(nonsep_int + nonsep_int));
+
+ // From: -000...000123...890
+ // To: BigDecimal -123...890
+ check("-" + nonsep_zero + nonsep_int, new BigDecimal("-" + nonsep_int));
+
+ // From: -000,0...0,000,123,4...7,890
+ // To: BigDecimal -123...890
+ check("-" + sep_zero + "," + sep_int, new BigDecimal("-" + nonsep_int));
+ }
+
+ /**
+ * Test for normal big numbers which don't have the fraction part with
+ * multiplier
+ */
+ void test_Parse_in_DecimalFormat_BigInteger_usingMultiplier() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+
+ // From: 250,0...0,000
+ // To: 1000...0000
+ df.setMultiplier(250000000);
+ check("250,000,000," + sep_zero, new BigDecimal("1" + nonsep_zero));
+
+ // From: -250,0...0,000
+ // To: -1000...0000
+ check("-250,000,000," + sep_zero, new BigDecimal("-1" + nonsep_zero));
+
+ // From: 250,0...0,000
+ // To: -1000...0000
+ df.setMultiplier(-250000000);
+ check("250,000,000," + sep_zero, new BigDecimal("-1" + nonsep_zero));
+
+ // From: -250,0...0,000
+ // To: 1000...0000
+ check("-250,000,000," + sep_zero, new BigDecimal("1" + nonsep_zero));
+
+ // From: 250,0...0,000E-360
+ // To: -1000...0000.000...000
+ check("250,000,000," + sep_zero + "," + sep_zero + "E-360",
+ new BigDecimal("-1" + nonsep_zero + "." + nonsep_zero));
+
+ // Confirm that a division which results in a irrational number is done
+ // properly
+ // From: 1000
+ // To: 333
+ df.setMultiplier(3);
+ check("1000", new BigDecimal("333"));
+ }
+
+ /**
+ * Test for special numbers
+ * Double.NaN
+ * Double.POSITIVE_INFINITY
+ * Double.NEGATIVE_INFINITY
+ */
+ void test_Parse_in_DecimalFormat_SpecialNumber() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+
+ String[] numbers = {
+ "0", "0.0", "25", "25.0", "25.5", "\u221e", "\ufffd",
+ "-0", "-0.0", "-25", "-25.0", "-25.5", "-\u221e",
+ };
+ int multipliers[] = {5, -5};
+ Number[][] expected = {
+ {
+ new BigDecimal("0"), new BigDecimal("0.0"), new BigDecimal("5"),
+ new BigDecimal("5.0"), new BigDecimal("5.1"),
+ new Double(Double.POSITIVE_INFINITY), new Double(Double.NaN),
+ new BigDecimal("0"), new BigDecimal("0.0"),
+ new BigDecimal("-5"), new BigDecimal("-5.0"),
+ new BigDecimal("-5.1"),
+ new Double(Double.NEGATIVE_INFINITY), new Double(Double.NaN),
+ },
+ {
+ new BigDecimal("0"), new BigDecimal("0.0"),
+ new BigDecimal("-5"), new BigDecimal("-5.0"),
+ new BigDecimal("-5.1"),
+ new Double(Double.NEGATIVE_INFINITY), new Double(Double.NaN),
+ new BigDecimal("0"), new BigDecimal("0.0"), new BigDecimal("5"),
+ new BigDecimal("5.0"), new BigDecimal("5.1"),
+ new Double(Double.POSITIVE_INFINITY),
+ },
+ };
+
+ for (int i = 0; i < multipliers.length; i++) {
+ df.setMultiplier(multipliers[i]);
+ for (int j = 0; j < numbers.length; j++) {
+ check(String.valueOf(numbers[j]), expected[i][j]);
+ }
+ }
+ }
+
+ /**
+ * Test for special numbers
+ */
+ void test_Parse_in_DecimalFormat_Other() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+
+ String[] numbers = {
+ "-9223372036854775808", // Long.MIN_VALUE
+ };
+ int multipliers[] = {1, -1};
+ String[][] expected = {
+ {"-9223372036854775808"}, // Long.MIN_VALUE
+ {"9223372036854775808"}, // Long.MAX_VALUE+1 = abs(MIN_VALUE)
+ };
+
+ for (int i = 0; i < multipliers.length; i++) {
+ df.setMultiplier(multipliers[i]);
+ for (int j = 0; j < numbers.length; j++) {
+ check(String.valueOf(numbers[j]),
+ new BigDecimal(expected[i][j]));
+ }
+ }
+ }
+
+ static final String[] patterns = {
+ " {0, number} ",
+ " {0, number} ",
+ " {0, number, currency} ",
+ " {0, number, currency} ",
+ " {0, number, percent} ",
+ " {0, number, percent} ",
+ " {0, number,#,##0.###E0} ",
+ " {0, number,#,##0.###E0} ",
+
+ " {0, number} ",
+ " {0, number} ",
+ " {0, number, integer} ",
+ " {0, number, integer} ",
+ " {0, number, currency} ",
+ " {0, number, currency} ",
+ " {0, number, percent} ",
+ " {0, number, percent} ",
+ " {0, number,#,##0.###E0} ",
+ " {0, number,#,##0.###E0} ",
+ };
+ static final String[] from = {
+ " 12,345,678,901,234,567,890.98765432109876543210987654321 ",
+ " -12,345,678,901,234,567,890.98765432109876543210987654321 ",
+ " $12,345,678,901,234,567,890.98765432109876543210987654321 ",
+ " ($12,345,678,901,234,567,890.98765432109876543210987654321) ",
+ " 1,234,567,890,123,456,789,098.76543210987654321098765432100% ",
+ " -1,234,567,890,123,456,789,098.76543210987654321098765432100% ",
+ " 12,345,678,901,234,567,890.98765432109876543210987654321E-20 ",
+ " -12,345,678,901,234,567,890.98765432109876543210987654321E-20 ",
+
+ " 9,876,543,210,987,654,321,098,765,432,109,876,543,210 ",
+ " -9,876,543,210,987,654,321,098,765,432,109,876,543,210 ",
+ " 9,876,543,210,987,654,321,098,765,432,109,876,543,210E5 ",
+ " -9,876,543,210,987,654,321,098,765,432,109,876,543,210E-5 ",
+ " $9,876,543,210,987,654,321,098,765,432,109,876,543,210.00 ",
+ " ($9,876,543,210,987,654,321,098,765,432,109,876,543,210.00) ",
+ " 987,654,321,098,765,432,109,876,543,210,987,654,321,012% ",
+ " -987,654,321,098,765,432,109,876,543,210,987,654,321,012% ",
+ " 98,765,432,109,876,543,210.98765432109876543210E20 ",
+ " -987,654,321,098,765,432,109,876,543,210,987,654,321,000,000,000,000,000,000,000E-20 ",
+ };
+
+ static final String[] expected1 = { // isParseIntegerOnly() == false
+ "12345678901234567890.98765432109876543210987654321",
+ "-12345678901234567890.98765432109876543210987654321",
+ "12345678901234567890.98765432109876543210987654321",
+ "-12345678901234567890.98765432109876543210987654321",
+ "12345678901234567890.98765432109876543210987654321",
+ "-12345678901234567890.98765432109876543210987654321",
+ "0.1234567890123456789098765432109876543210987654321",
+ "-0.1234567890123456789098765432109876543210987654321",
+
+ "9876543210987654321098765432109876543210",
+ "-9876543210987654321098765432109876543210",
+ "9.876543210987654321098765432109876543210E44",
+ "-98765432109876543210987654321098765.43210",
+ "9876543210987654321098765432109876543210.00",
+ "-9876543210987654321098765432109876543210.00",
+ "9876543210987654321098765432109876543210.12",
+ "-9876543210987654321098765432109876543210.12",
+ "9876543210987654321098765432109876543210",
+ "-9876543210987654321098765432109876543210.00000000000000000000",
+ };
+ static final int[] parsePosition1 = {
+ 60, 61, 61, 63, 64, 65, 64, 65,
+ 57, 58, 59, 61, 61, 63, 60, 61, 54, 88,
+ };
+
+ /**
+ * Test for MessageFormat: setParseIntegerOnly(false)
+ */
+ void test_Parse_in_MessageFormat_NotParseIntegerOnly() {
+ for (int i=0; i < patterns.length; i++) {
+ pp = new ParsePosition(0);
+ Object[] parsed = null;
+
+ try {
+ MessageFormat mf = new MessageFormat(patterns[i]);
+ Format[] formats = mf.getFormats();
+ for (int j=0; j < formats.length; j++) {
+ ((DecimalFormat)formats[j]).setParseBigDecimal(true);
+ }
+
+ parsed = mf.parse(from[i], pp);
+
+ if (pp.getErrorIndex() != -1) {
+ errln("Case" + (i+1) +
+ ": getErrorIndex() returns wrong value. expected:-1, got:"+
+ pp.getErrorIndex() + " for " + from[i]);
+ }
+ if (pp.getIndex() != parsePosition1[i]) {
+ errln("Case" + (i+1) +
+ ": getIndex() returns wrong value. expected:" +
+ parsePosition1[i] + ", got:"+ pp.getIndex() +
+ " for " + from[i]);
+ }
+ }
+ catch(Exception e) {
+ errln("Unexpected exception: " + e.getMessage());
+ }
+
+ checkType(from[i], getType(new BigDecimal(expected1[i])),
+ getType((Number)parsed[0]));
+ checkParse(from[i], new BigDecimal(expected1[i]),
+ (Number)parsed[0]);
+ }
+ }
+
+ static final String[] expected2 = { // isParseIntegerOnly() == true
+ "12345678901234567890",
+ "-12345678901234567890",
+ "12345678901234567890",
+ "-12345678901234567890",
+ "12345678901234567890",
+ "-12345678901234567890",
+ "0",
+ "0",
+
+ "9876543210987654321098765432109876543210",
+ "-9876543210987654321098765432109876543210",
+ "9.876543210987654321098765432109876543210E44",
+ "-98765432109876543210987654321098765.43210",
+ "9876543210987654321098765432109876543210",
+ "-9876543210987654321098765432109876543210",
+ "9876543210987654321098765432109876543210.12",
+ "-9876543210987654321098765432109876543210.12",
+ "9876543210987654321098765432109876543210",
+ "-9876543210987654321098765432109876543210.00000000000000000000",
+ };
+ static final int[][] parsePosition2 = { // {errorIndex, index}
+ /*
+ * Should keep in mind that the expected result is different from
+ * DecimalFormat.parse() for some cases.
+ */
+ {28, 0}, // parsing stopped at '.'
+ {29, 0}, // parsing stopped at '.'
+ {29, 0}, // parsing stopped at '.'
+ {2, 0}, // parsing stopped at '(' because cannot find ')'
+ {2, 0}, // parsing stopped at the first numeric
+ // because cannot find '%'
+ {2, 0}, // parsing stopped at the first numeric
+ // because cannot find '%'
+ {28, 0}, // parsing stopped at '.'
+ {29, 0}, // parsing stopped at '.'
+
+ {-1, 57}, {-1, 58}, {-1, 59}, {-1, 61},
+ {56, 0}, // parsing stopped at '.'
+ // because cannot find '%'
+ {2, 0}, // parsing stopped at '(' because cannot find ')'
+ {-1, 60}, {-1, 61},
+ {28, 0}, // parsing stopped at '.'
+ {-1, 88},
+ };
+
+ /**
+ * Test for MessageFormat: setParseIntegerOnly(true)
+ */
+ void test_Parse_in_MessageFormat_ParseIntegerOnly() {
+ for (int i=0; i < patterns.length; i++) {
+ pp = new ParsePosition(0);
+ Object[] parsed = null;
+
+ try {
+ MessageFormat mf = new MessageFormat(patterns[i]);
+ Format[] formats = mf.getFormats();
+ for (int j=0; j < formats.length; j++) {
+ ((DecimalFormat)formats[j]).setParseBigDecimal(true);
+ ((DecimalFormat)formats[j]).setParseIntegerOnly(true);
+ }
+
+ parsed = mf.parse(from[i], pp);
+
+ if (pp.getErrorIndex() != parsePosition2[i][0]) {
+ errln("Case" + (i+1) +
+ ": getErrorIndex() returns wrong value. expected:" +
+ parsePosition2[i][0] + ", got:"+ pp.getErrorIndex() +
+ " for " + from[i]);
+ }
+ if (pp.getIndex() != parsePosition2[i][1]) {
+ errln("Case" + (i+1) +
+ ": getIndex() returns wrong value. expected:" +
+ parsePosition2[i][1] + ", got:"+ pp.getIndex() +
+ " for " + from[i]);
+ }
+ }
+ catch(Exception e) {
+ errln("Unexpected exception: " + e.getMessage());
+ }
+
+ if (parsePosition2[i][0] == -1) {
+ checkType(from[i], getType(new BigDecimal(expected2[i])),
+ getType((Number)parsed[0]));
+ checkParse(from[i], new BigDecimal(expected2[i]),
+ (Number)parsed[0]);
+ }
+ }
+ }
+
+ static final String[] from3 = {
+ "12,345,678,901,234,567,890.98765432109876543210987654321",
+ "-12,345,678,901,234,567,890.98765432109876543210987654321",
+ "9,876,543,210,987,654,321,098,765,432,109,876,543,210",
+ "-9,876,543,210,987,654,321,098,765,432,109,876,543,210",
+ "1234556790000E-8",
+ };
+ static final String[] expected3 = {
+ "12345678901234567890",
+ "-12345678901234567890",
+ "9876543210987654321098765432109876543210",
+ "-9876543210987654321098765432109876543210",
+ "12345.56790000",
+ };
+ static final int[][] parsePosition3 = { // {errorIndex, index}
+ {-1, 26},
+ {-1, 27},
+ {-1, 53},
+ {-1, 54},
+ {-1, 16},
+ };
+
+ /**
+ * Test for DecimalFormat: setParseIntegerOnly(true)
+ */
+ void test_Parse_in_DecimalFormat_ParseIntegerOnly() {
+ DecimalFormat df = (DecimalFormat)NumberFormat.getIntegerInstance();
+ df.setParseBigDecimal(true);
+
+ for (int i=0; i < from3.length; i++) {
+ pp = new ParsePosition(0);
+ Number parsed = null;
+
+ try {
+ parsed = df.parse(from3[i], pp);
+
+ if (pp.getErrorIndex() != parsePosition3[i][0]) {
+ errln("Case" + (i+1) +
+ ": getErrorIndex() returns wrong value. expected:" +
+ parsePosition3[i][0] + ", got:"+ pp.getErrorIndex() +
+ " for " + from3[i]);
+ }
+ if (pp.getIndex() != parsePosition3[i][1]) {
+ errln("Case" + (i+1) +
+ ": getIndex() returns wrong value. expected:" +
+ parsePosition3[i][1] + ", got:"+ pp.getIndex() +
+ " for " + from3[i]);
+ }
+ }
+ catch(Exception e) {
+ errln("Unexpected exception: " + e.getMessage());
+ }
+
+ if (parsePosition3[i][0] == -1) {
+ checkType(from3[i], getType(new BigDecimal(expected3[i])),
+ getType(parsed));
+ checkParse(from3[i], new BigDecimal(expected3[i]), parsed);
+ }
+ }
+ }
+
+ protected void check(String from, Number to) {
+ pp = new ParsePosition(0);
+ try {
+ parsed = df.parse(from, pp);
+ }
+ catch(Exception e) {
+ exceptionOccurred = true;
+ errln(e.getMessage());
+ }
+ if (!exceptionOccurred) {
+ checkParse(from, to, parsed);
+ checkType(from, getType(to), getType(parsed));
+ checkParsePosition(from, from.length(), pp.getIndex());
+ }
+ }
+
+ private void checkParse(String orig, Number expected, Number got) {
+ if (!expected.equals(got)) {
+ errln("Parsing... failed." +
+ "\n original: " + orig +
+ "\n parsed: " + got +
+ "\n expected: " + expected + "\n");
+ }
+ }
+
+ private void checkType(String orig, String expected, String got) {
+ if (!expected.equals(got)) {
+ errln("Parsing... unexpected Class returned." +
+ "\n original: " + orig +
+ "\n got: " + got +
+ "\n expected: " + expected + "\n");
+ }
+ }
+
+ private void checkParsePosition(String orig, int expected, int got) {
+ if (expected != got) {
+ errln("Parsing... wrong ParsePosition returned." +
+ "\n original: " + orig +
+ "\n got: " + got +
+ "\n expected: " + expected + "\n");
+ }
+ }
+
+ private String getType(Number number) {
+ return number.getClass().getName();
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/Bug4208135.java b/jdk/test/java/text/Format/NumberFormat/Bug4208135.java
new file mode 100644
index 00000000000..3f5785b6f6c
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/Bug4208135.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Confirm that the decimal separator is shown when explicitly requested.
+ * @bug 4208135
+ */
+
+import java.math.*;
+import java.text.*;
+import java.util.*;
+
+public class Bug4208135 {
+
+ static DecimalFormat df;
+
+ static boolean err = false;
+
+ static public void main(String[] args){
+
+ Locale defaultLoc = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+
+ df = new DecimalFormat();
+
+ df.applyPattern("0.#E0");
+
+ df.setDecimalSeparatorAlwaysShown(true);
+ checkFormat(new Double(0.0), "0.E0");
+ checkFormat(new Double(10.0), "1.E1");
+ checkFormat(new Double(1000.0), "1.E3");
+ checkFormat(new Long(0), "0.E0");
+ checkFormat(new Long(10), "1.E1");
+ checkFormat(new Long(1000), "1.E3");
+ checkFormat(new BigDecimal("0.0"), "0.E0");
+ checkFormat(new BigDecimal("10.0"), "1.E1");
+ checkFormat(new BigDecimal("1000.0"), "1.E3");
+ checkFormat(new BigInteger("00"), "0.E0");
+ checkFormat(new BigInteger("10"), "1.E1");
+ checkFormat(new BigInteger("1000"), "1.E3");
+
+ df.setDecimalSeparatorAlwaysShown(false);
+ checkFormat(new Double(0.0), "0E0");
+ checkFormat(new Double(10.0), "1E1");
+ checkFormat(new Double(1000.0), "1E3");
+ checkFormat(new Long(0), "0E0");
+ checkFormat(new Long(10), "1E1");
+ checkFormat(new Long(1000), "1E3");
+ checkFormat(new BigDecimal("0.0"), "0E0");
+ checkFormat(new BigDecimal("10.0"), "1E1");
+ checkFormat(new BigDecimal("1000.0"), "1E3");
+ checkFormat(new BigInteger("0"), "0E0");
+ checkFormat(new BigInteger("10"), "1E1");
+ checkFormat(new BigInteger("1000"), "1E3");
+
+ df.applyPattern("0.###");
+
+ df.setDecimalSeparatorAlwaysShown(true);
+ checkFormat(new Double(0.0), "0.");
+ checkFormat(new Double(10.0), "10.");
+ checkFormat(new Double(1000.0), "1000.");
+ checkFormat(new Long(0), "0.");
+ checkFormat(new Long(10), "10.");
+ checkFormat(new Long(1000), "1000.");
+ checkFormat(new BigDecimal("0.0"), "0.");
+ checkFormat(new BigDecimal("10.0"), "10.");
+ checkFormat(new BigDecimal("1000.0"), "1000.");
+ checkFormat(new BigInteger("0"), "0.");
+ checkFormat(new BigInteger("10"), "10.");
+ checkFormat(new BigInteger("1000"), "1000.");
+
+ df.setDecimalSeparatorAlwaysShown(false);
+ checkFormat(new Double(0.0), "0");
+ checkFormat(new Double(10.0), "10");
+ checkFormat(new Double(1000.0), "1000");
+ checkFormat(new Long(0), "0");
+ checkFormat(new Long(10), "10");
+ checkFormat(new Long(1000), "1000");
+ checkFormat(new BigDecimal("0.0"), "0");
+ checkFormat(new BigDecimal("10.0"), "10");
+ checkFormat(new BigDecimal("1000.0"), "1000");
+ checkFormat(new BigInteger("0"), "0");
+ checkFormat(new BigInteger("10"), "10");
+ checkFormat(new BigInteger("1000"), "1000");
+
+ Locale.setDefault(defaultLoc);
+
+ if (err) {
+ throw new RuntimeException("Wrong format/parse with DecimalFormat");
+ }
+ }
+
+ static void checkFormat(Number num, String expected) {
+ String got = df.format(num);
+ if (!got.equals(expected)) {
+ err = true;
+ System.err.println(" DecimalFormat format(" +
+ num.getClass().getName() +
+ ") error:" +
+ "\n\tnumber: " + num +
+ "\n\tSeparatorShown? : " + df.isDecimalSeparatorAlwaysShown() +
+ "\n\tgot: " + got +
+ "\n\texpected: " + expected);
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/Bug4833877.java b/jdk/test/java/text/Format/NumberFormat/Bug4833877.java
new file mode 100644
index 00000000000..5f3c5056014
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/Bug4833877.java
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Confirm that the negative multiplier works as expected.
+ * @bug 4833877
+ */
+
+import java.math.*;
+import java.text.*;
+import java.util.*;
+
+public class Bug4833877 {
+
+ static DecimalFormat df;
+
+ static boolean err = false;
+
+ public static void main(String[] args) throws Exception {
+
+ Locale defaultLoc = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+
+ /* ================================================================ */
+
+ df = new DecimalFormat();
+ df.setMaximumFractionDigits(50);
+ df.setMultiplier(4);
+
+ /*
+ * Test for double/Double
+ */
+ checkFormat(new Double(252.5252525252525), "1,010.10101010101");
+ checkParse("-1,010.10101010101", new Double(-252.5252525252525));
+
+ checkFormat(new Double(-2222.2222), "-8,888.8888");
+ checkParse("8888.8888", new Double(2222.2222));
+
+ /*
+ * Test for long/Long
+ */
+ checkFormat(new Long(1000), "4,000");
+ checkParse("-4,000", new Long(-1000));
+
+ checkFormat(new Long(-250), "-1,000");
+ checkParse("1000", new Long(250));
+
+ /* ---------------------------------------------------------------- */
+
+ df.setParseBigDecimal(true);
+
+ /*
+ * Test for BigDecimal
+ */
+ checkFormat(new BigDecimal("22222.222222222222222222222"),
+ "88,888.888888888888888888888");
+ checkParse("-88,888.888888888888888888888",
+ new BigDecimal("-22222.222222222222222222222"));
+
+ checkFormat(new BigDecimal("-1111111111111111111.111111111111111111"),
+ "-4,444,444,444,444,444,444.444444444444444444");
+ checkParse("4444444444444444444.444444444444444444",
+ new BigDecimal("1111111111111111111.111111111111111111"));
+
+ /*
+ * Test for BigInteger
+ */
+ checkFormat(new BigInteger("22222222222222222222222222"),
+ "88,888,888,888,888,888,888,888,888");
+ checkParse("-88,888,888,888,888,888,888,888,888",
+ new BigDecimal("-22222222222222222222222222"));
+
+ checkFormat(new BigInteger("-1111111111111111111111111"),
+ "-4,444,444,444,444,444,444,444,444");
+ checkParse("4444444444444444444444444",
+ new BigDecimal("1111111111111111111111111"));
+
+ /* ---------------------------------------------------------------- */
+
+ df.setParseBigDecimal(false);
+ df.setMultiplier(-4);
+
+ /*
+ * Test for double/Double
+ */
+ checkFormat(new Double(252.5252525252525), "-1,010.10101010101");
+ checkParse("-1,010.10101010101", new Double(252.5252525252525));
+
+ checkFormat(new Double(-2222.2222), "8,888.8888");
+ checkParse("8888.8888", new Double(-2222.2222));
+
+ /*
+ * Test for long/Long
+ */
+ checkFormat(new Long(1000), "-4,000");
+ checkParse("-4,000", new Long(1000));
+
+ checkFormat(new Long(-250), "1,000");
+ checkParse("1000", new Long(-250));
+
+ /* ---------------------------------------------------------------- */
+
+ df.setParseBigDecimal(true);
+
+ /*
+ * Test for BigDecimal
+ */
+ checkFormat(new BigDecimal("22222.222222222222222222222"),
+ "-88,888.888888888888888888888");
+ checkParse("-88,888.888888888888888888888",
+ new BigDecimal("22222.222222222222222222222"));
+
+ checkFormat(new BigDecimal("-1111111111111111111.111111111111111111"),
+ "4,444,444,444,444,444,444.444444444444444444");
+ checkParse("4444444444444444444.444444444444444444",
+ new BigDecimal("-1111111111111111111.111111111111111111"));
+
+ /*
+ * Test for BigInteger
+ */
+ checkFormat(new BigInteger("22222222222222222222222222"),
+ "-88,888,888,888,888,888,888,888,888");
+ checkParse("-88,888,888,888,888,888,888,888,888",
+ new BigDecimal("22222222222222222222222222"));
+
+ checkFormat(new BigInteger("-1111111111111111111111111"),
+ "4,444,444,444,444,444,444,444,444");
+ checkParse("4444444444444444444444444",
+ new BigDecimal("-1111111111111111111111111"));
+
+ /* ---------------------------------------------------------------- */
+
+ df.setParseBigDecimal(false);
+ df.setMultiplier(-3);
+
+ /*
+ * Test for double/Double
+ */
+ checkFormat(new Double(3333.3333333), "-9,999.9999999");
+ checkParse("-10,000.00000000000", new Double(3333.3333333333335));// rounding error
+
+ df.setParseIntegerOnly(true);
+ checkFormat(new Double(-3333.3333333), "9,999.9999999");
+ checkParse("10,000.00000000000", new Long(-3333));
+ df.setParseIntegerOnly(false);
+ checkFormat(new Double(-3333.3333333), "9,999.9999999");
+ checkParse("10,000.00000000000", new Double(-3333.3333333333335));// rounding error
+
+ /*
+ * Test for long/Long
+ */
+ checkFormat(new Long(3333), "-9,999");
+ df.setParseIntegerOnly(true);
+ checkParse("-10,000", new Long(3333));
+ df.setParseIntegerOnly(false);
+ checkParse("-10000", new Double(3333.3333333333335));// rounding error
+
+ checkFormat(new Long(-3333), "9,999");
+ df.setParseIntegerOnly(true);
+ checkParse("10,000", new Long(-3333));
+ df.setParseIntegerOnly(false);
+ checkParse("10000", new Double(-3333.3333333333335));// rounding error
+
+ /* ---------------------------------------------------------------- */
+
+ df.setParseBigDecimal(true);
+
+ /*
+ * Test for BigDecimal
+ */
+ checkFormat(new BigDecimal("33333.333333333333333333333"),
+ "-99,999.999999999999999999999");
+ checkParse("-100,000.000000000000000000000",
+ new BigDecimal("33333.333333333333333333333"));
+
+ checkFormat(new BigDecimal("-33333.333333333333333333333"),
+ "99,999.999999999999999999999");
+ checkParse("100,000.000000000000000000000",
+ new BigDecimal("-33333.333333333333333333333"));
+
+ /*
+ * Test for BigInteger
+ */
+ checkFormat(new BigInteger("33333333333333333333333333"),
+ "-99,999,999,999,999,999,999,999,999");
+ checkParse("-100,000,000,000,000,000,000,000,000",
+ new BigDecimal("33333333333333333333333333"));
+
+ checkFormat(new BigInteger("-33333333333333333333333333"),
+ "99,999,999,999,999,999,999,999,999");
+ df.setParseIntegerOnly(true);
+ checkParse("100,000,000,000,000,000,000,000,000.000",
+ new BigDecimal("-33333333333333333333333333"));
+ df.setParseIntegerOnly(false);
+ checkParse("100,000,000,000,000,000,000,000,000.000",
+ new BigDecimal("-33333333333333333333333333.333"));
+
+ /* ================================================================ */
+
+ df = new DecimalFormat("0.#E0;-0.#E0");
+ df.setMaximumFractionDigits(50);
+ df.setMultiplier(4);
+
+ /*
+ * Test for double/Double
+ */
+ checkFormat(new Double(252.5252525252525), "1.01010101010101E3");
+ checkParse("-1.01010101010101E3", new Double(-2.525252525252525E2));
+
+ checkFormat(new Double(-2222.2222), "-8.8888888E3");
+ checkParse("8888.8888", new Double(2.2222222E3));
+
+ /*
+ * Test for long/Long
+ */
+ checkFormat(new Long(1000), "4E3");
+ checkParse("-4E3", new Long(-1000));
+
+ checkFormat(new Long(-250), "-1E3");
+ checkParse("1000", new Long(250));
+
+ /* ---------------------------------------------------------------- */
+
+ df.setParseBigDecimal(true);
+
+ /*
+ * Test for BigDecimal
+ */
+
+ checkFormat(new BigDecimal("22222.222222222222222222222"),
+ "8.8888888888888888888888888E4");
+ checkParse("-8.8888888888888888888888888E4",
+ new BigDecimal("-2.2222222222222222222222222E4"));
+
+ checkFormat(new BigDecimal("-1111111111111111111.111111111111111111"),
+ "-4.444444444444444444444444444444444444E18");
+ checkParse("4444444444444444444.444444444444444444",
+ new BigDecimal("1111111111111111111.111111111111111111"));
+
+ /*
+ * Test for BigInteger
+ */
+ checkFormat(new BigInteger("22222222222222222222222222"),
+ "8.8888888888888888888888888E25");
+ checkParse("-8.8888888888888888888888888E25",
+ new BigDecimal("-22222222222222222222222222"));
+
+ checkFormat(new BigInteger("-1111111111111111111111111"),
+ "-4.444444444444444444444444E24");
+ checkParse("4444444444444444444444444",
+ new BigDecimal("1111111111111111111111111"));
+
+ /* ---------------------------------------------------------------- */
+
+ df.setParseBigDecimal(false);
+ df.setMultiplier(-4);
+
+ /*
+ * Test for double/Double
+ */
+ checkFormat(new Double(252.5252525252525), "-1.01010101010101E3");
+ checkParse("-1.01010101010101E3", new Double(2.525252525252525E2));
+
+ checkFormat(new Double(-2222.2222), "8.8888888E3");
+ checkParse("8888.8888", new Double(-2.2222222E3));
+
+ /*
+ * Test for long/Long
+ */
+ checkFormat(new Long(1000), "-4E3");
+ checkParse("-4E3", new Long(1000));
+
+ checkFormat(new Long(-250), "1E3");
+ checkParse("1000", new Long(-250));
+
+ /* ---------------------------------------------------------------- */
+
+ df.setParseBigDecimal(true);
+
+ /*
+ * Test for BigDecimal
+ */
+
+ checkFormat(new BigDecimal("22222.222222222222222222222"),
+ "-8.8888888888888888888888888E4");
+ checkParse("-8.8888888888888888888888888E4",
+ new BigDecimal("2.2222222222222222222222222E4"));
+
+ checkFormat(new BigDecimal("-1111111111111111111.111111111111111111"),
+ "4.444444444444444444444444444444444444E18");
+ checkParse("4444444444444444444.444444444444444444",
+ new BigDecimal("-1111111111111111111.111111111111111111"));
+
+ /*
+ * Test for BigInteger
+ */
+ checkFormat(new BigInteger("22222222222222222222222222"),
+ "-8.8888888888888888888888888E25");
+ checkParse("-8.8888888888888888888888888E25",
+ new BigDecimal("22222222222222222222222222"));
+
+ checkFormat(new BigInteger("-1111111111111111111111111"),
+ "4.444444444444444444444444E24");
+ checkParse("4444444444444444444444444",
+ new BigDecimal("-1111111111111111111111111"));
+
+ /* ---------------------------------------------------------------- */
+
+ df.setParseBigDecimal(false);
+ df.setMultiplier(-3);
+
+ /*
+ * Test for double/Double
+ */
+ checkFormat(new Double(3333.3333333), "-9.9999999999E3");
+ checkParse("-1.00000000000000E3", new Double(3.33333333333333333E2));
+
+ df.setParseIntegerOnly(true);
+ checkFormat(new Double(-3333.3333333), "9.9999999999E3");
+ checkParse("10.00000000000000E3", new Long(-3));
+ df.setParseIntegerOnly(false);
+ checkFormat(new Double(-3333.3333333), "9.9999999999E3");
+ checkParse("10.00000000000000E3", new Double(-3.33333333333333333E3));
+
+ /*
+ * Test for long/Long
+ */
+ checkFormat(new Long(3333), "-9.999E3");
+ df.setParseIntegerOnly(true);
+ checkParse("-1.0E4", new Long(0));
+ df.setParseIntegerOnly(false);
+ checkParse("-1.0E4", new Double(3333.3333333333335));
+
+ checkFormat(new Long(-3333), "9.999E3");
+ df.setParseIntegerOnly(true);
+ checkParse("10.0E4", new Long(-3));
+ df.setParseIntegerOnly(false);
+ checkParse("10.0E4", new Double(-33333.3333333333336));
+
+ /* ---------------------------------------------------------------- */
+
+ df.setParseBigDecimal(true);
+
+ /*
+ * Test for BigDecimal
+ */
+
+ checkFormat(new BigDecimal("333.333333333333333333333333"),
+ "-9.99999999999999999999999999E2");
+ checkParse("-1.0000000000000000000000000E3",
+ new BigDecimal("3.333333333333333333333333E2"));
+
+ df.setParseIntegerOnly(true);
+ checkFormat(new BigDecimal("-333.333333333333333333333333"),
+ "9.99999999999999999999999999E2");
+ checkParse("10.0000000000000000000000000E3",
+ new BigDecimal("-3"));
+ df.setParseIntegerOnly(false);
+ checkFormat(new BigDecimal("-333.333333333333333333333333"),
+ "9.99999999999999999999999999E2");
+ checkParse("1.0000000000000000000000000E3",
+ new BigDecimal("-3.333333333333333333333333E2"));
+
+ /*
+ * Test for BigInteger
+ */
+ checkFormat(new BigInteger("33333333333333333333333333"),
+ "-9.9999999999999999999999999E25");
+ checkParse("-100000000000000000000000000",
+ new BigDecimal("33333333333333333333333333"));
+
+ checkFormat(new BigInteger("-33333333333333333333333333"),
+ "9.9999999999999999999999999E25");
+ df.setParseIntegerOnly(true);
+ checkParse("100000000000000000000000000000",
+ new BigDecimal("-33333333333333333333333333333"));
+ df.setParseIntegerOnly(false);
+ checkParse("100000000000000000000000000.000",
+ new BigDecimal("-33333333333333333333333333.333"));
+
+ /* ================================================================ */
+
+ Locale.setDefault(defaultLoc);
+
+ if (err) {
+ throw new RuntimeException("Wrong format/parse with DecimalFormat");
+ }
+ }
+
+ static void checkFormat(Number num, String expected) {
+ String got = df.format(num);
+ if (!got.equals(expected)) {
+ err = true;
+ System.err.println(" DecimalFormat format(" +
+ num.getClass().getName() +
+ ") error:" +
+ "\n\tnumber: " + num +
+ "\n\tpattern: " + df.toPattern() +
+ "\n\tmultiplier: " + df.getMultiplier() +
+ "\n\tgot: " + got +
+ "\n\texpected: " + expected);
+ }
+ }
+
+ static void checkParse(String text, Double expected) {
+ Double got = (Double)df.parse(text, new ParsePosition(0));
+ if (!got.equals(expected)) {
+ err = true;
+ System.err.println(" DecimalFormat parse(double) error:" +
+ "\n\ttext: " + text +
+ "\n\tpattern: " + df.toPattern() +
+ "\n\tmultiplier: " + df.getMultiplier() +
+ "\n\tgot: " + got +
+ "\n\texpected: " + expected);
+ }
+ }
+
+ static void checkParse(String text, Long expected) {
+ Long got = (Long)df.parse(text, new ParsePosition(0));
+ if (!got.equals(expected)) {
+ err = true;
+ System.err.println(" DecimalFormat parse(long) error:" +
+ "\n\ttext: " + text +
+ "\n\tpattern: " + df.toPattern() +
+ "\n\tmultiplier: " + df.getMultiplier() +
+ "\n\tgot: " + got +
+ "\n\texpected: " + expected);
+ }
+ }
+
+ static void checkParse(String text, BigDecimal expected) {
+ BigDecimal got = (BigDecimal)df.parse(text, new ParsePosition(0));
+ if (!got.equals(expected)) {
+ err = true;
+ System.err.println(" DecimalFormat parse(BigDecimal) error:" +
+ "\n\ttext: " + text +
+ "\n\tpattern: " + df.toPattern() +
+ "\n\tmultiplier: " + df.getMultiplier() +
+ "\n\tgot: " + got +
+ "\n\texpected: " + expected);
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/Bug4838107.java b/jdk/test/java/text/Format/NumberFormat/Bug4838107.java
new file mode 100644
index 00000000000..a15d537d8e6
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/Bug4838107.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4838107 8008577
+ * @summary Confirm that DecimalFormat can format a number with negative exponent number correctly.
+ * @library /java/text/testlib
+ * @run main/othervm -Djava.locale.providers=COMPAT,SPI Bug4838107
+ */
+
+import java.math.*;
+import java.util.*;
+import java.text.*;
+
+public class Bug4838107 extends IntlTest {
+
+ static DecimalFormat df;
+ static DecimalFormatSymbols dfs;
+ static boolean err = false;
+
+ static public void main(String[] args) {
+ Locale defaultLoc = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+
+ /**
+ * This bug is about exponential formatting. But I added test cases for:
+ * - Double and BigDecimal numbers which don't have exponent parts.
+ * - Long and BigInteger numbers which don't support exponential
+ * notation.
+ * because there are few test cases for suffix and prefix.
+ * And also, I added test cases to guarantee further formatting and
+ * parsing using the same DecimalFormat instance will not change the
+ * Number's value anymore.
+ */
+
+ test_double();
+ test_long();
+ test_BigDecimal();
+ test_BigInteger();
+
+ Locale.setDefault(defaultLoc);
+
+ if (err) {
+ throw new RuntimeException("Wrong format with DecimalFormat");
+ }
+ }
+
+ static void test_double() {
+ df = new DecimalFormat();
+ dfs = df.getDecimalFormatSymbols();
+
+ /* Test with default pattern */
+ test(new Double(1234), "1,234");
+ test(new Double(0.1234), "0.123"); // rounded
+ test(new Double(-1234), "-1,234");
+ test(new Double(-0.1234), "-0.123"); // rounded
+
+ test(new Double(Double.POSITIVE_INFINITY), "\u221e");
+ test(new Double(Double.NEGATIVE_INFINITY), "-\u221e");
+ test(new Double(Double.NaN), "\ufffd"); // without prefix and suffix
+ test(new Double(0.0), "0");
+ test(new Double(-0.0), "-0"); // with the minus sign
+
+ /* Specify a pattern and the minus sign. */
+ prepareFormatter("#.###E00", 'm');
+ test(new Double(1234), "
1.234E03");
+ test(new Double(0.1234), "
1.234Em01");
+ test(new Double(-1234), "m
1.234E03");
+ test(new Double(-0.1234), "m
1.234Em01");
+
+ prepareFormatter("
#.###E00;#.###E00", 'm');
+ test(new Double(1234), "
1.234E03");
+ test(new Double(0.1234), "
1.234Em01");
+ test(new Double(-1234), "1.234E03");
+ test(new Double(-0.1234), "1.234Em01");
+
+ prepareFormatter("#.###E00;
#.###E00", 'm');
+ test(new Double(1234), "1.234E03");
+ test(new Double(0.1234), "1.234Em01");
+ test(new Double(-1234), "
1.234E03");
+ test(new Double(-0.1234), "
1.234Em01");
+
+ prepareFormatter("
#.###E00;
-#.###E00", 'm');
+ test(new Double(1234), "
1.234E03");
+ test(new Double(0.1234), "
1.234Em01");
+ test(new Double(-1234), "
m1.234E03");
+ test(new Double(-0.1234), "
m1.234Em01");
+
+ test(new Double(Double.POSITIVE_INFINITY), "
\u221e");
+ test(new Double(Double.NEGATIVE_INFINITY), "
m\u221e");
+ test(new Double(Double.NaN), "\ufffd"); // without prefix and suffix
+ test(new Double(0.0), "
0E00");
+ test(new Double(-0.0), "
m0E00"); // with the minus sign
+ }
+
+ static void test_BigDecimal() {
+ df = new DecimalFormat();
+ dfs = df.getDecimalFormatSymbols();
+
+ /* Test with default pattern */
+ test(new BigDecimal("123456789012345678901234567890"),
+ "123,456,789,012,345,678,901,234,567,890");
+ test(new BigDecimal("0.000000000123456789012345678901234567890"),
+ "0");
+ test(new BigDecimal("-123456789012345678901234567890"),
+ "-123,456,789,012,345,678,901,234,567,890");
+ test(new BigDecimal("-0.000000000123456789012345678901234567890"),
+ "-0");
+
+ test(new BigDecimal("0"), "0");
+ test(new BigDecimal("-0"), "0");
+
+ /* Specify a pattern and the minus sign. */
+ prepareFormatter("
#.####################E00;
-#.####################E00", 'm');
+ test(new BigDecimal("123456789012345678901234567890"),
+ "
1.23456789012345678901E29");
+ test(new BigDecimal("0.000000000123456789012345678901234567890"),
+ "
1.23456789012345678901Em10");
+ test(new BigDecimal("-123456789012345678901234567890"),
+ "
m1.23456789012345678901E29");
+ test(new BigDecimal("-0.000000000123456789012345678901234567890"),
+ "
m1.23456789012345678901Em10");
+
+ test(new BigDecimal("0"), "
0E00");
+ test(new BigDecimal("-0"), "
0E00");
+ }
+
+ static void test_long() {
+ df = new DecimalFormat();
+ dfs = df.getDecimalFormatSymbols();
+
+ /* Test with default pattern */
+ test(new Long(123456789), "123,456,789");
+ test(new Long(-123456789), "-123,456,789");
+
+ test(new Long(0), "0");
+ test(new Long(-0), "0");
+
+ /* Specify a pattern and the minus sign. */
+ prepareFormatter("
#,###;
-#,###", 'm');
+ test(new Long(123456789), "
123,456,789");
+ test(new Long(-123456789), "
m123,456,789");
+
+ test(new Long(0), "
0");
+ test(new Long(-0), "
0");
+ }
+
+ static void test_BigInteger() {
+ df = new DecimalFormat();
+ dfs = df.getDecimalFormatSymbols();
+
+ /* Test with default pattern */
+ test(new BigInteger("123456789012345678901234567890"),
+ "123,456,789,012,345,678,901,234,567,890");
+ test(new BigInteger("-123456789012345678901234567890"),
+ "-123,456,789,012,345,678,901,234,567,890");
+
+ test(new BigInteger("0"), "0");
+ test(new BigInteger("-0"), "0");
+
+ /* Specify a pattern and the minus sign. */
+ prepareFormatter("
#,###;
-#,###", 'm');
+ test(new BigInteger("123456789012345678901234567890"),
+ "
123,456,789,012,345,678,901,234,567,890");
+ test(new BigInteger("-123456789012345678901234567890"),
+ "
m123,456,789,012,345,678,901,234,567,890");
+
+ test(new BigInteger("0"), "
0");
+ test(new BigInteger("-0"), "
0");
+ }
+
+ static void prepareFormatter(String pattern, char minusSign) {
+ dfs = df.getDecimalFormatSymbols();
+ df.applyPattern(pattern);
+ dfs.setMinusSign(minusSign);
+ df.setDecimalFormatSymbols(dfs);
+ }
+
+ static void test(Number num, String str) {
+ String formatted = df.format(num);
+ if (!formatted.equals(str)) {
+ err = true;
+ System.err.println(" DecimalFormat format(" +
+ num.getClass().getName() +
+ ") error: \n\tnumber: " + num +
+ "\n\tminus sign: " + dfs.getMinusSign() +
+ "\n\tgot: " + formatted +
+ "\n\texpected: " + str);
+ return;
+ }
+
+ if (num instanceof BigDecimal || num instanceof BigInteger) {
+ df.setParseBigDecimal(true);
+ }
+ Number parsed1 = null, parsed2 = null;
+ try {
+ parsed1 = df.parse(formatted);
+ formatted = df.format(parsed1);
+ parsed2 = df.parse(formatted);
+ if (!parsed1.equals(parsed2)) {
+ err = true;
+ System.err.println(" DecimalFormat roundtrip parse(" +
+ num.getClass().getName() +
+ ") error: \n\toriginal number: " + str +
+ "\n\tparsed number: " + parsed1 +
+ " (" + parsed1.getClass().getName() + ")" +
+ "\n\tformatted number: " + formatted +
+ "\n\tre-parsed number: " + parsed2 +
+ " (" + parsed2.getClass().getName() + ")" +
+ "\n\tminus sign: " + dfs.getMinusSign());
+ }
+ }
+ catch (Exception e) {
+ err = true;
+ System.err.println(" DecimalFormat parse(" +
+ num.getClass().getName() +
+ ") threw an Exception: " + e.getMessage() +
+ "\n\toriginal number: " + str +
+ "\n\tparsed number : " + parsed1 +
+ " (" + parsed1.getClass().getName() + ")" +
+ "\n\tformatted number: " + formatted +
+ "\n\tre-parsed number: " + parsed2 +
+ " (" + parsed2.getClass().getName() + ")" +
+ "\n\tminus sign: " + dfs.getMinusSign());
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/Bug4944439.java b/jdk/test/java/text/Format/NumberFormat/Bug4944439.java
new file mode 100644
index 00000000000..beb4d77c235
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/Bug4944439.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4944439
+ * @summary Confirm that numbers where all digits after the decimal separator are 0
+ * and which are between Long.MIN_VALUE and Long.MAX_VALUE are returned as Long(not double).
+ */
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.text.DecimalFormat;
+import java.util.Locale;
+
+public class Bug4944439 {
+
+ static boolean err = false;
+ static DecimalFormat df;
+
+ public static void main(String[] args) throws Exception {
+
+ Locale defaultLoc = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+
+ df = new DecimalFormat();
+ String s = "-9223372036854775809"; // Long.MIN_VALUE-1
+ check_Double(s);
+
+ test(Long.MIN_VALUE, Long.MIN_VALUE+10);
+ test(-10, 10);
+ test(Long.MAX_VALUE-10, Long.MAX_VALUE-1);
+
+ s = "9223372036854775807.00"; // Long.MAX_VALUE
+ check_Long(s);
+ s = "9223372036854775808"; // Long.MAX_VALUE+1
+ check_Double(s);
+
+ s = "-0.0";
+ check_Double(s);
+ s = "0.0";
+ check_Long(s);
+
+ Locale.setDefault(defaultLoc);
+
+ if (err) {
+ throw new RuntimeException("Wrong parsing with DecimalFormat");
+ }
+ }
+
+ private static void test(long from, long to) throws Exception {
+ for (long l = from; l <= to; l++) {
+ check_Long(Long.toString(l) + ".00");
+ }
+ }
+
+ private static void check_Long(String s) throws Exception {
+ Number number = df.parse(s);
+ if (!(number instanceof Long)) {
+ err = true;
+ System.err.println("Failed: DecimalFormat.parse(\"" + s +
+ "\") should return a Long, but returned a " +
+ number.getClass().getName());
+ }
+
+ int index = s.indexOf('.');
+ Long l = new Long(s.substring(0, index));
+ if (!l.equals(number)) {
+ err = true;
+ System.err.println("Failed: DecimalFormat.parse(" + s +
+ ") should return a Long(" + l + "), but returned " + number);
+ }
+ }
+
+ private static void check_Double(String s) throws Exception {
+ Number number = df.parse(s);
+ if (!(number instanceof Double)) {
+ err = true;
+ System.err.println("Failed: DecimalFormat.parse(\"" + s +
+ "\") should return a Double, but returned a " +
+ number.getClass().getName());
+ }
+
+ Double d = new Double(s);
+ if (!d.equals(number)) {
+ err = true;
+ System.err.println("Failed: DecimalFormat.parse(" + s +
+ ") should return a Double(" + d + "), but returned " + number);
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/Bug4990596.java b/jdk/test/java/text/Format/NumberFormat/Bug4990596.java
new file mode 100644
index 00000000000..a8c03b8a035
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/Bug4990596.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2004, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4990596
+ * @summary Make sure that any subclass of Number can be formatted using DecimalFormat.format().
+ */
+
+import java.text.DecimalFormat;
+
+public class Bug4990596 {
+
+ public static void main(String[] args) {
+ new DecimalFormat().format(new MutableInteger(0));
+ }
+
+ public static class MutableInteger extends Number {
+ public int value;
+
+ public MutableInteger() {
+ }
+ public MutableInteger(int value) {
+ this.value = value;
+ }
+ public double doubleValue() {
+ return this.value;
+ }
+ public float floatValue() {
+ return this.value;
+ }
+ public int intValue() {
+ return this.value;
+ }
+ public long longValue() {
+ return this.value;
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/Bug6278616.java b/jdk/test/java/text/Format/NumberFormat/Bug6278616.java
new file mode 100644
index 00000000000..9066a7da02e
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/Bug6278616.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Confirm that AtomicInteger and AtomicLong are formatted correctly.
+ * @bug 6278616
+ */
+
+import java.text.NumberFormat;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import java.util.Locale;
+
+public class Bug6278616 {
+
+ static final int[] ints = {
+ Integer.MIN_VALUE, -1, 0, 1, Integer.MAX_VALUE
+ };
+
+ static final long[] longs = {
+ Long.MIN_VALUE, -1, 0, 1, Long.MAX_VALUE
+ };
+
+ public static void main(String[] args) {
+ NumberFormat nf = NumberFormat.getInstance();
+
+ for (int j = 0; j < ints.length; j++) {
+ String s_i = nf.format(new Integer(ints[j]));
+ String s_ai = nf.format(new AtomicInteger(ints[j]));
+ if (!s_i.equals(s_ai)) {
+ throw new RuntimeException("format(AtomicInteger " + s_ai +
+ ") doesn't equal format(Integer " +
+ s_i + ")");
+ }
+ }
+
+ for (int j = 0; j < longs.length; j++) {
+ String s_l = nf.format(new Long(longs[j]));
+ String s_al = nf.format(new AtomicLong(longs[j]));
+ if (!s_l.equals(s_al)) {
+ throw new RuntimeException("format(AtomicLong " + s_al +
+ ") doesn't equal format(Long " +
+ s_l + ")");
+ }
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/CurrencyFormat.java b/jdk/test/java/text/Format/NumberFormat/CurrencyFormat.java
new file mode 100644
index 00000000000..96fa3976701
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/CurrencyFormat.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2001, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4290801 4942982 5102005 8008577 8021121
+ * @summary Basic tests for currency formatting.
+ * @run main/othervm -Djava.locale.providers=JRE,SPI CurrencyFormat
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Currency;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+
+public class CurrencyFormat {
+
+ public static void main(String[] args) throws Exception {
+ testFormatting();
+ testSymbols();
+ }
+
+ static void testFormatting() {
+ boolean failed = false;
+ Locale[] locales = {
+ Locale.US,
+ Locale.JAPAN,
+ Locale.GERMANY,
+ Locale.ITALY,
+ new Locale("it", "IT", "EURO") };
+ Currency[] currencies = {
+ null,
+ Currency.getInstance("USD"),
+ Currency.getInstance("JPY"),
+ Currency.getInstance("DEM"),
+ Currency.getInstance("EUR"),
+ };
+ String[][] expecteds = {
+ {"$1,234.56", "$1,234.56", "JPY1,235", "DEM1,234.56", "EUR1,234.56"},
+ {"\uFFE51,235", "USD1,234.56", "\uFFE51,235", "DEM1,234.56", "EUR1,234.56"},
+ {"1.234,56 \u20AC", "1.234,56 USD", "1.235 JPY", "1.234,56 DM", "1.234,56 \u20AC"},
+ {"\u20AC 1.234,56", "USD 1.234,56", "JPY 1.235", "DEM 1.234,56", "\u20AC 1.234,56"},
+ {"\u20AC 1.234,56", "USD 1.234,56", "JPY 1.235", "DEM 1.234,56", "\u20AC 1.234,56"},
+ };
+
+ for (int i = 0; i < locales.length; i++) {
+ Locale locale = locales[i];
+ NumberFormat format = NumberFormat.getCurrencyInstance(locale);
+ for (int j = 0; j < currencies.length; j++) {
+ Currency currency = currencies[j];
+ String expected = expecteds[i][j];
+ if (currency != null) {
+ format.setCurrency(currency);
+ int digits = currency.getDefaultFractionDigits();
+ format.setMinimumFractionDigits(digits);
+ format.setMaximumFractionDigits(digits);
+ }
+ String result = format.format(1234.56);
+ if (!result.equals(expected)) {
+ failed = true;
+ System.out.println("FAIL: Locale " + locale
+ + (currency == null ? ", default currency" : (", currency: " + currency))
+ + ", expected: " + expected
+ + ", actual: " + result);
+ }
+ }
+ }
+
+ if (failed) {
+ throw new RuntimeException();
+ }
+ }
+
+ static void testSymbols() throws Exception {
+ FileInputStream stream = new FileInputStream(new File(System.getProperty("test.src", "."), "CurrencySymbols.properties"));
+ Properties props = new Properties();
+ props.load(stream);
+ SimpleDateFormat format = null;
+
+ Locale[] locales = NumberFormat.getAvailableLocales();
+ for (int i = 0; i < locales.length; i++) {
+ Locale locale = locales[i];
+ DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locale);
+ String result = symbols.getCurrencySymbol();
+ String expected = (String) props.get(locale.toString());
+
+ if (expected == null) {
+ System.out.println("Warning: No expected currency symbol defined for locale " + locale);
+ } else {
+ if (expected.contains(";")) {
+ StringTokenizer tokens = new StringTokenizer(expected, ";");
+ int tokensCount = tokens.countTokens();
+
+ if (tokensCount == 3) {
+ expected = tokens.nextToken();
+ if (format == null) {
+ format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US);
+ format.setTimeZone(TimeZone.getTimeZone("GMT"));
+ format.setLenient(false);
+ }
+
+ if (format.parse(tokens.nextToken()).getTime() < System.currentTimeMillis()) {
+ expected = tokens.nextToken();
+ }
+ }
+ }
+
+ if (!expected.equals(result)) {
+ throw new RuntimeException("Wrong currency symbol for locale " +
+ locale + ", expected: " + expected + ", got: " + result);
+ }
+ }
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/CurrencySymbols.properties b/jdk/test/java/text/Format/NumberFormat/CurrencySymbols.properties
new file mode 100644
index 00000000000..cc919005db7
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/CurrencySymbols.properties
@@ -0,0 +1,134 @@
+ar=\u00A4
+ar_AE=\u062F.\u0625.\u200F
+ar_BH=\u062F.\u0628.\u200F
+ar_DZ=\u062F.\u062C.\u200F
+ar_EG=\u062C.\u0645.\u200F
+ar_IQ=\u062F.\u0639.\u200F
+ar_JO=\u062F.\u0623.\u200F
+ar_KW=\u062F.\u0643.\u200F
+ar_LB=\u0644.\u0644.\u200F
+ar_LY=\u062F.\u0644.\u200F
+ar_MA=\u062F.\u0645.\u200F
+ar_OM=\u0631.\u0639.\u200F
+ar_QA=\u0631.\u0642.\u200F
+ar_SA=\u0631.\u0633.\u200F
+# see bug 4412080
+# ar_SD=\u062C.\u0633.\u200F
+ar_SY=\u0644.\u0633.\u200F
+ar_TN=\u062F.\u062A.\u200F
+ar_YE=\u0631.\u064A.\u200F
+be=\u00A4
+# see bug 4412080
+# be_BY=\u0420\u0443\u0431
+bg=\u00A4
+# see bug 4412080
+# bg_BG=Lr
+ca=\u00A4
+ca_ES=\u20AC
+cs=\u00A4
+cs_CZ=K\u010D
+da=\u00A4
+da_DK=kr
+de=\u00A4
+de_AT=\u20AC
+de_CH=SFr.
+de_DE=\u20AC
+de_LU=\u20AC
+el=\u00A4
+el_GR=\u20AC
+en=\u00A4
+en_AU=$
+en_CA=$
+en_GB=\u00A3
+en_IE=\u20AC
+en_NZ=$
+en_US=$
+en_ZA=R
+es=\u00A4
+es_AR=$
+es_BO=B$
+es_CL=Ch$
+# 5102005
+es_CO=$
+es_CR=C
+es_CU=CU$
+es_DO=RD$
+# see bug 4412080
+# es_EC=S/
+es_ES=\u20AC
+es_GT=Q
+es_HN=L
+es_MX=$
+es_NI=$C
+es_PA=B
+es_PE=S/.
+es_PR=$
+es_PY=G
+es_SV=C
+es_UY=NU$
+es_VE=Bs.F.
+et=\u00A4
+et_EE=\u20AC
+fi=\u00A4
+fi_FI=\u20AC
+fr=\u00A4
+fr_BE=\u20AC
+fr_CA=$
+fr_CH=SFr.
+fr_FR=\u20AC
+fr_LU=\u20AC
+hi_IN=\u0930\u0942
+hr=\u00A4
+hr_HR=Kn
+hu=\u00A4
+hu_HU=Ft
+is=\u00A4
+is_IS=kr.
+it=\u00A4
+it_CH=SFr.
+it_IT=\u20AC
+iw=\u00A4
+iw_IL=\u05E9"\u05D7
+ja=\u00A4
+ja_JP=\uFFE5
+ko=\u00A4
+ko_KR=\uFFE6
+lt=\u00A4
+lt_LT=Lt;2014-12-31-22-00-00;\u20AC
+lv=\u00A4
+lv_LV=Ls;2013-12-31-22-00-00;\u20AC
+mk=\u00A4
+mk_MK=Den
+nl=\u00A4
+nl_BE=\u20AC
+nl_NL=\u20AC
+no=\u00A4
+no_NO=kr
+no_NO_NY=kr
+pl=\u00A4
+pl_PL=z\u0142
+pt=\u00A4
+pt_BR=R$
+pt_PT=\u20AC
+ro=\u00A4
+ro_RO=LEI
+ru=\u00A4
+ru_RU=\u0440\u0443\u0431.
+sk=\u00A4
+sk_SK=\u20AC
+sl=\u00A4
+sl_SI=\u20AC
+sq=\u00A4
+sq_AL=Lek
+sv=\u00A4
+sv_SE=kr
+th=\u00A4
+th_TH=\u0E3F
+tr=\u00A4
+tr_TR=TL
+uk=\u00A4
+uk_UA=\u0433\u0440\u043d.
+zh=\u00A4
+zh_CN=\uFFE5
+zh_HK=HK$
+zh_TW=NT$
diff --git a/jdk/test/java/text/Format/NumberFormat/DFSDeserialization142.java b/jdk/test/java/text/Format/NumberFormat/DFSDeserialization142.java
new file mode 100644
index 00000000000..2927f4e2c3b
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/DFSDeserialization142.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * No at-test for this test, because it needs to be run on older version JDK than 1.6 to test.
+ * It was tested using 1.4.2. The file object was created using JDK1.6.
+ */
+
+
+
+import java.awt.*;
+import java.text.*;
+import java.util.*;
+import java.io.*;
+
+public class DFSDeserialization142{
+
+ public static void main(String[] args)
+ {
+ try {
+
+ File file = new File("DecimalFormatSymbols.current");
+ FileInputStream istream = new FileInputStream(file);
+ ObjectInputStream p = new ObjectInputStream(istream);
+ DecimalFormatSymbols dfs = (DecimalFormatSymbols)p.readObject();
+ if (dfs.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){
+ System.out.println("Serialization/Deserialization Test Passed.");
+ }else{
+ throw new Exception("Serialization/Deserialization Test Failed:"+dfs.getCurrencySymbol());
+ }
+ istream.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/DFSExponential.java b/jdk/test/java/text/Format/NumberFormat/DFSExponential.java
new file mode 100644
index 00000000000..898fb3feccb
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/DFSExponential.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4068067
+ * @library /java/text/testlib
+ * @summary test NumberFormat with exponential separator symbols. It also tests the new
+ * public methods in DecimalFormatSymbols, setExponentSeparator() and
+ * getExponentSeparator()
+ */
+
+import java.util.*;
+import java.text.*;
+
+public class DFSExponential extends IntlTest
+{
+
+ public static void main(String[] args) throws Exception {
+ new DFSExponential().run(args);
+ }
+
+
+ public void DFSExponenTest() throws Exception {
+ DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
+ String pat[] = { "0.####E0", "00.000E00", "##0.####E000", "0.###E0;[0.###E0]" };
+ double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
+ long lval[] = { 0, -1, 1, 123456789 };
+ String valFormat[][] = {
+ {"1.234x10^-2", "1.2346x10^8", "1.23x10^300", "-3.1416x10^-271"},
+ {"12.340x10^-03", "12.346x10^07", "12.300x10^299", "-31.416x10^-272"},
+ {"12.34x10^-003", "123.4568x10^006", "1.23x10^300", "-314.1593x10^-273"},
+ {"1.234x10^-2", "1.235x10^8", "1.23x10^300", "[3.142x10^-271]"},
+ };
+
+
+ int ival = 0, ilval = 0;
+ logln("Default exponent separator: "+sym.getExponentSeparator());
+ try {
+ sym.setExponentSeparator("x10^");
+ } catch (NullPointerException e){
+ errln("null String was passed to set an exponent separator symbol");
+ throw new RuntimeException("Test Malfunction: null String was passed to set an exponent separator symbol" );
+ }
+ logln("Current exponent separator: "+sym.getExponentSeparator());
+
+ for (int p=0; p "+s);
+ if(valFormat[p][v].equals(s)){
+ logln(": Passed");
+ }else{
+ errln(" Failed: Should be formatted as "+valFormat[p][v]+ "but got "+s);
+ throw new RuntimeException(" Failed: Should be formatted as "+valFormat[p][v]+ "but got "+s);
+ }
+ }
+ } //end of the first for loop
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/DFSSerialization.java b/jdk/test/java/text/Format/NumberFormat/DFSSerialization.java
new file mode 100644
index 00000000000..40b40b39b87
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/DFSSerialization.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4068067
+ * @library /java/text/testlib
+ * @build DFSSerialization IntlTest HexDumpReader
+ * @run main DFSSerialization
+ * @summary Three different tests are done. 1.read from the object created using jdk1.4.2 2.create a valid DecimalFormatSymbols object with current JDK, then read the object 3.Try to create an valid DecimalFormatSymbols object by passing null to set null for the exponent separator symbol. Expect the NullPointerException.
+ */
+
+import java.awt.*;
+import java.text.*;
+import java.util.*;
+import java.io.*;
+
+public class DFSSerialization extends IntlTest{
+ public static void main(String[] args) throws Exception {
+ new DFSSerialization().run(args);
+ }
+ public void TestDFSSerialization(){
+ /*
+ * 1. read from the object created using jdk1.4.2
+ */
+ File oldFile = new File(System.getProperty("test.src", "."), "DecimalFormatSymbols.142.txt");
+ DecimalFormatSymbols dfs142 = readTestObject(oldFile);
+ if (dfs142 != null){
+ if (dfs142.getExponentSeparator().equals("E") && dfs142.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){
+ System.out.println("\n Deserialization of JDK1.4.2 Object from the current JDK: Passed.");
+ logln(" Deserialization of JDK1.4.2 Object from the current JDK: Passed.");
+ } else {
+ errln(" Deserialization of JDK1.4.2 Object from the current JDK was Failed:"
+ +dfs142.getCurrencySymbol()+" "+dfs142.getExponentSeparator());
+ /*
+ * logically should not throw this exception as errln throws exception
+ * if not thrown yet - but in case errln got changed
+ */
+ throw new RuntimeException(" Deserialization of JDK1.4.2 Object from the current JDK was Failed:"
+ +dfs142.getCurrencySymbol()+" "+dfs142.getExponentSeparator());
+ }
+ }
+ /*
+ * 2. create a valid DecimalFormatSymbols object with current JDK, then read the object
+ */
+ String validObject = "DecimalFormatSymbols.current";
+ File currentFile = createTestObject(validObject, "*SpecialExponentSeparator*");
+
+ DecimalFormatSymbols dfsValid = readTestObject(currentFile);
+ if (dfsValid != null){
+ if (dfsValid.getExponentSeparator().equals("*SpecialExponentSeparator*") &&
+ dfsValid.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){
+ System.out.println(" Deserialization of current JDK Object from the current JDK: Passed.");
+ logln(" Deserialization of current JDK Object from the current JDK: Passed.");
+ } else {
+ errln(" Deserialization of current JDK Object from the current JDK was Failed:"
+ +dfsValid.getCurrencySymbol()+" "+dfsValid.getExponentSeparator());
+ /*
+ * logically should not throw this exception as errln throws exception
+ * if not thrown yet - but in case errln got changed
+ */
+ throw new RuntimeException(" Deserialization of current Object from the current JDK was Failed:"
+ +dfsValid.getCurrencySymbol()+" "+dfsValid.getExponentSeparator());
+ }
+ }
+ /*
+ * 3. Try to create an valid DecimalFormatSymbols object by passing null
+ * to set null for the exponent separator symbol. Expect the NullPointerException.
+ */
+ DecimalFormatSymbols symNPE = new DecimalFormatSymbols(Locale.US);
+ boolean npePassed = false;
+ try {
+ symNPE.setExponentSeparator(null);
+ } catch (NullPointerException npe){
+ npePassed = true;
+ System.out.println(" Trying to set exponent separator with null: Passed.");
+ logln(" Trying to set exponent separator with null: Passed.");
+ }
+ if (!npePassed){
+ System.out.println(" Trying to set exponent separator with null:Failed.");
+ errln(" Trying to set exponent separator with null:Failed.");
+ /*
+ * logically should not throw this exception as errln throws exception
+ * if not thrown yet - but in case errln got changed
+ */
+ throw new RuntimeException(" Trying to set exponent separator with null:Failed.");
+ }
+
+ }
+
+ private DecimalFormatSymbols readTestObject(File inputFile){
+ try (InputStream istream = inputFile.getName().endsWith(".txt") ?
+ HexDumpReader.getStreamFromHexDump(inputFile) :
+ new FileInputStream(inputFile)) {
+ ObjectInputStream p = new ObjectInputStream(istream);
+ DecimalFormatSymbols dfs = (DecimalFormatSymbols)p.readObject();
+ return dfs;
+ } catch (Exception e) {
+ errln("Test Malfunction in DFSSerialization: Exception while reading the object");
+ /*
+ * logically should not throw this exception as errln throws exception
+ * if not thrown yet - but in case errln got changed
+ */
+ throw new RuntimeException("Test Malfunction: re-throwing the exception", e);
+ }
+ }
+
+ private File createTestObject(String objectName, String expString){
+ DecimalFormatSymbols dfs= new DecimalFormatSymbols();
+ dfs.setExponentSeparator(expString);
+ dfs.setCurrencySymbol("*SpecialCurrencySymbol*");
+ logln(" The special exponent separator is set : " + dfs.getExponentSeparator());
+ logln(" The special currency symbol is set : " + dfs.getCurrencySymbol());
+
+ // 6345659: create a test object in the test.class dir where test user has a write permission.
+ File file = new File(System.getProperty("test.class", "."), objectName);
+ try (FileOutputStream ostream = new FileOutputStream(file)) {
+ ObjectOutputStream p = new ObjectOutputStream(ostream);
+ p.writeObject(dfs);
+ //System.out.println(" The special currency symbol is set : " + dfs.getCurrencySymbol());
+ return file;
+ } catch (Exception e){
+ errln("Test Malfunction in DFSSerialization: Exception while creating an object");
+ /*
+ * logically should not throw this exception as errln throws exception
+ * if not thrown yet - but in case errln got changed
+ */
+ throw new RuntimeException("Test Malfunction: re-throwing the exception", e);
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/DFSSerialization142.java b/jdk/test/java/text/Format/NumberFormat/DFSSerialization142.java
new file mode 100644
index 00000000000..4a5e873ee23
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/DFSSerialization142.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * No at-test for this test, because it needs to be run on JDK 1.4.2
+ * Instead, the resulting serialized file
+ * DecimalFormatSymbols.142 is archived.
+ */
+
+import java.awt.*;
+import java.text.*;
+import java.util.*;
+import java.io.*;
+
+public class DFSSerialization142 {
+
+ public static void main(String[] args)
+ {
+ try {
+
+ DecimalFormatSymbols dfs= new DecimalFormatSymbols();
+ System.out.println("Default currency symbol in the default locale : " + dfs.getCurrencySymbol());
+ dfs.setCurrencySymbol("*SpecialCurrencySymbol*");
+ System.out.println("The special currency symbol is set : " + dfs.getCurrencySymbol());
+ FileOutputStream ostream = new FileOutputStream("DecimalFormatSymbols.142");
+ ObjectOutputStream p = new ObjectOutputStream(ostream);
+ p.writeObject(dfs);
+ ostream.close();
+ System.out.println("DecimalFormatSymbols saved ok.");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/DecimalFormat.114.txt b/jdk/test/java/text/Format/NumberFormat/DecimalFormat.114.txt
new file mode 100644
index 00000000000..efa6df41419
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/DecimalFormat.114.txt
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 1998, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Hex dump of a serialized DecimalFormat for SerializationLoadTest.
+
+aced000573720012436865636b446563696d616c466f726d6174aa9218d3b530
+540a0200014c000a5f646563466f726d61747400194c6a6176612f746578742f
+446563696d616c466f726d61743b7870737200176a6176612e746578742e4465
+63696d616c466f726d61740bff0362d872303a0200085a001b646563696d616c
+536570617261746f72416c7761797353686f776e42000c67726f7570696e6753
+697a6549000a6d756c7469706c6965724c000e6e656761746976655072656669
+787400124c6a6176612f6c616e672f537472696e673b4c000e6e656761746976
+655375666669787400124c6a6176612f6c616e672f537472696e673b4c000e70
+6f7369746976655072656669787400124c6a6176612f6c616e672f537472696e
+673b4c000e706f7369746976655375666669787400124c6a6176612f6c616e67
+2f537472696e673b4c000773796d626f6c737400204c6a6176612f746578742f
+446563696d616c466f726d617453796d626f6c733b787200166a6176612e7465
+78742e4e756d626572466f726d6174dff6b3bf137d07e80200065a000c67726f
+7570696e67557365644200116d61784672616374696f6e446967697473420010
+6d6178496e74656765724469676974734200116d696e4672616374696f6e4469
+676974734200106d696e496e74656765724469676974735a0010706172736549
+6e74656765724f6e6c79787200106a6176612e746578742e466f726d6174fbd8
+bc12e90f1843020000787001037f0001000003000000017400012d7400007400
+007400007372001e6a6176612e746578742e446563696d616c466f726d617453
+796d626f6c73501d17990868939c02000c430010646563696d616c5365706172
+61746f72430005646967697443001167726f7570696e67536570617261746f72
+4300096d696e75735369676e4300107061747465726e536570617261746f7243
+00077065724d696c6c43000770657263656e744300097a65726f44696769744c
+00034e614e7400124c6a6176612f6c616e672f537472696e673b4c000e637572
+72656e637953796d626f6c7400124c6a6176612f6c616e672f537472696e673b
+4c0008696e66696e6974797400124c6a6176612f6c616e672f537472696e673b
+4c0012696e746c43757272656e637953796d626f6c7400124c6a6176612f6c61
+6e672f537472696e673b7870002e0023002c002d003b203000250030740003ef
+bfbd74000124740003e2889e740003555344
diff --git a/jdk/test/java/text/Format/NumberFormat/DecimalFormatSymbols.114.txt b/jdk/test/java/text/Format/NumberFormat/DecimalFormatSymbols.114.txt
new file mode 100644
index 00000000000..6707e375a99
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/DecimalFormatSymbols.114.txt
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 1998, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Hex dump of a serialized DecimalFormatSymbols for SerializationLoadTest.
+
+aced000573720019436865636b446563696d616c466f726d617453796d626f6c
+737763237e1aa359bb0200014c00115f646563466f726d617453796d626f6c73
+7400204c6a6176612f746578742f446563696d616c466f726d617453796d626f
+6c733b78707372001e6a6176612e746578742e446563696d616c466f726d6174
+53796d626f6c73501d17990868939c02000c430010646563696d616c53657061
+7261746f72430005646967697443001167726f7570696e67536570617261746f
+724300096d696e75735369676e4300107061747465726e536570617261746f72
+4300077065724d696c6c43000770657263656e744300097a65726f4469676974
+4c00034e614e7400124c6a6176612f6c616e672f537472696e673b4c000e6375
+7272656e637953796d626f6c7400124c6a6176612f6c616e672f537472696e67
+3b4c0008696e66696e6974797400124c6a6176612f6c616e672f537472696e67
+3b4c0012696e746c43757272656e637953796d626f6c7400124c6a6176612f6c
+616e672f537472696e673b7870002e0023002c002d003b203000250030740003
+efbfbd74000124740003e2889e740003555344
diff --git a/jdk/test/java/text/Format/NumberFormat/DecimalFormatSymbols.142.txt b/jdk/test/java/text/Format/NumberFormat/DecimalFormatSymbols.142.txt
new file mode 100644
index 00000000000..723f107b402
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/DecimalFormatSymbols.142.txt
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 1998, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Hex dump of a serialized DecimalFormatSymbols for SerializationLoadTest.
+
+aced00057372001e6a6176612e746578742e446563696d616c466f726d617453
+796d626f6c73501d17990868939c020010430010646563696d616c5365706172
+61746f72430005646967697443000b6578706f6e656e7469616c43001167726f
+7570696e67536570617261746f724300096d696e75735369676e4300116d6f6e
+6574617279536570617261746f724300107061747465726e536570617261746f
+724300077065724d696c6c43000770657263656e7449001573657269616c5665
+7273696f6e4f6e53747265616d4300097a65726f44696769744c00034e614e74
+00124c6a6176612f6c616e672f537472696e673b4c000e63757272656e637953
+796d626f6c71007e00014c0008696e66696e69747971007e00014c0012696e74
+6c43757272656e637953796d626f6c71007e00014c00066c6f63616c65740012
+4c6a6176612f7574696c2f4c6f63616c653b7870002e00230045002c002d002e
+003b20300025000000020030740003efbfbd7400172a5370656369616c437572
+72656e637953796d626f6c2a740003e2889e740003434e59737200106a617661
+2e7574696c2e4c6f63616c657ef811609c30f9ec03000449000868617368636f
+64654c0007636f756e74727971007e00014c00086c616e677561676571007e00
+014c000776617269616e7471007e00017870ffffffff740002434e7400027a68
+74000078
diff --git a/jdk/test/java/text/Format/NumberFormat/IntlTestDecimalFormatAPI.java b/jdk/test/java/text/Format/NumberFormat/IntlTestDecimalFormatAPI.java
new file mode 100644
index 00000000000..fcda5b863b4
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/IntlTestDecimalFormatAPI.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 1998, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /java/text/testlib
+ * @summary test International Decimal Format API
+ */
+/*
+(C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+(C) Copyright IBM Corp. 1996, 1997 - All Rights Reserved
+
+ The original version of this source code and documentation is copyrighted and
+owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
+provided under terms of a License Agreement between Taligent and Sun. This
+technology is protected by multiple US and International patents. This notice and
+attribution to Taligent may not be removed.
+ Taligent is a registered trademark of Taligent, Inc.
+*/
+
+import java.text.*;
+import java.util.*;
+
+public class IntlTestDecimalFormatAPI extends IntlTest
+{
+ public static void main(String[] args) throws Exception {
+ new IntlTestDecimalFormatAPI().run(args);
+ }
+
+ // This test checks various generic API methods in DecimalFormat to achieve 100% API coverage.
+ public void TestAPI()
+ {
+ Locale reservedLocale = Locale.getDefault();
+ try {
+ logln("DecimalFormat API test---"); logln("");
+ Locale.setDefault(Locale.ENGLISH);
+
+ // ======= Test constructors
+
+ logln("Testing DecimalFormat constructors");
+
+ DecimalFormat def = new DecimalFormat();
+
+ final String pattern = new String("#,##0.# FF");
+ DecimalFormat pat = null;
+ try {
+ pat = new DecimalFormat(pattern);
+ }
+ catch (IllegalArgumentException e) {
+ errln("ERROR: Could not create DecimalFormat (pattern)");
+ }
+
+ DecimalFormatSymbols symbols =
+ new DecimalFormatSymbols(Locale.FRENCH);
+
+ DecimalFormat cust1 = new DecimalFormat(pattern, symbols);
+
+ // ======= Test clone(), assignment, and equality
+
+ logln("Testing clone() and equality operators");
+
+ Format clone = (Format) def.clone();
+ if( ! def.equals(clone)) {
+ errln("ERROR: Clone() failed");
+ }
+
+ // ======= Test various format() methods
+
+ logln("Testing various format() methods");
+
+// final double d = -10456.0037; // this appears as
+ // -10456.003700000001 on NT
+// final double d = -1.04560037e-4; // this appears as
+ // -1.0456003700000002E-4 on NT
+ final double d = -10456.00370000000000; // this works!
+ final long l = 100000000;
+ logln("" + d + " is the double value");
+
+ StringBuffer res1 = new StringBuffer();
+ StringBuffer res2 = new StringBuffer();
+ StringBuffer res3 = new StringBuffer();
+ StringBuffer res4 = new StringBuffer();
+ FieldPosition pos1 = new FieldPosition(0);
+ FieldPosition pos2 = new FieldPosition(0);
+ FieldPosition pos3 = new FieldPosition(0);
+ FieldPosition pos4 = new FieldPosition(0);
+
+ res1 = def.format(d, res1, pos1);
+ logln("" + d + " formatted to " + res1);
+
+ res2 = pat.format(l, res2, pos2);
+ logln("" + l + " formatted to " + res2);
+
+ res3 = cust1.format(d, res3, pos3);
+ logln("" + d + " formatted to " + res3);
+
+ res4 = cust1.format(l, res4, pos4);
+ logln("" + l + " formatted to " + res4);
+
+ // ======= Test parse()
+
+ logln("Testing parse()");
+
+ String text = new String("-10,456.0037");
+ ParsePosition pos = new ParsePosition(0);
+ String patt = new String("#,##0.#");
+ pat.applyPattern(patt);
+ double d2 = pat.parse(text, pos).doubleValue();
+ if(d2 != d) {
+ errln("ERROR: Roundtrip failed (via parse(" +
+ d2 + " != " + d + ")) for " + text);
+ }
+ logln(text + " parsed into " + (long) d2);
+
+ // ======= Test getters and setters
+
+ logln("Testing getters and setters");
+
+ final DecimalFormatSymbols syms = pat.getDecimalFormatSymbols();
+ def.setDecimalFormatSymbols(syms);
+ if(!pat.getDecimalFormatSymbols().equals(
+ def.getDecimalFormatSymbols())) {
+ errln("ERROR: set DecimalFormatSymbols() failed");
+ }
+
+ String posPrefix;
+ pat.setPositivePrefix("+");
+ posPrefix = pat.getPositivePrefix();
+ logln("Positive prefix (should be +): " + posPrefix);
+ if(posPrefix != "+") {
+ errln("ERROR: setPositivePrefix() failed");
+ }
+
+ String negPrefix;
+ pat.setNegativePrefix("-");
+ negPrefix = pat.getNegativePrefix();
+ logln("Negative prefix (should be -): " + negPrefix);
+ if(negPrefix != "-") {
+ errln("ERROR: setNegativePrefix() failed");
+ }
+
+ String posSuffix;
+ pat.setPositiveSuffix("_");
+ posSuffix = pat.getPositiveSuffix();
+ logln("Positive suffix (should be _): " + posSuffix);
+ if(posSuffix != "_") {
+ errln("ERROR: setPositiveSuffix() failed");
+ }
+
+ String negSuffix;
+ pat.setNegativeSuffix("~");
+ negSuffix = pat.getNegativeSuffix();
+ logln("Negative suffix (should be ~): " + negSuffix);
+ if(negSuffix != "~") {
+ errln("ERROR: setNegativeSuffix() failed");
+ }
+
+ long multiplier = 0;
+ pat.setMultiplier(8);
+ multiplier = pat.getMultiplier();
+ logln("Multiplier (should be 8): " + multiplier);
+ if(multiplier != 8) {
+ errln("ERROR: setMultiplier() failed");
+ }
+
+ int groupingSize = 0;
+ pat.setGroupingSize(2);
+ groupingSize = pat.getGroupingSize();
+ logln("Grouping size (should be 2): " + (long) groupingSize);
+ if(groupingSize != 2) {
+ errln("ERROR: setGroupingSize() failed");
+ }
+
+ pat.setDecimalSeparatorAlwaysShown(true);
+ boolean tf = pat.isDecimalSeparatorAlwaysShown();
+ logln("DecimalSeparatorIsAlwaysShown (should be true) is " +
+ (tf ? "true" : "false"));
+ if(tf != true) {
+ errln("ERROR: setDecimalSeparatorAlwaysShown() failed");
+ }
+
+ String funkyPat;
+ funkyPat = pat.toPattern();
+ logln("Pattern is " + funkyPat);
+
+ String locPat;
+ locPat = pat.toLocalizedPattern();
+ logln("Localized pattern is " + locPat);
+
+ // ======= Test applyPattern()
+
+ logln("Testing applyPattern()");
+
+ String p1 = new String("#,##0.0#;(#,##0.0#)");
+ logln("Applying pattern " + p1);
+ pat.applyPattern(p1);
+ String s2;
+ s2 = pat.toPattern();
+ logln("Extracted pattern is " + s2);
+ if( ! s2.equals(p1) ) {
+ errln("ERROR: toPattern() result did not match " +
+ "pattern applied");
+ }
+
+ String p2 = new String("#,##0.0# FF;(#,##0.0# FF)");
+ logln("Applying pattern " + p2);
+ pat.applyLocalizedPattern(p2);
+ String s3;
+ s3 = pat.toLocalizedPattern();
+ logln("Extracted pattern is " + s3);
+ if( ! s3.equals(p2) ) {
+ errln("ERROR: toLocalizedPattern() result did not match " +
+ "pattern applied");
+ }
+
+ // ======= Test getStaticClassID()
+
+// logln("Testing instanceof()");
+
+// try {
+// NumberFormat test = new DecimalFormat();
+
+// if (! (test instanceof DecimalFormat)) {
+// errln("ERROR: instanceof failed");
+// }
+// }
+// catch (Exception e) {
+// errln("ERROR: Couldn't create a DecimalFormat");
+// }
+ } finally {
+ // restore the reserved locale
+ Locale.setDefault(reservedLocale);
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/IntlTestDecimalFormatSymbols.java b/jdk/test/java/text/Format/NumberFormat/IntlTestDecimalFormatSymbols.java
new file mode 100644
index 00000000000..cd19fee1e35
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/IntlTestDecimalFormatSymbols.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1998, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /java/text/testlib
+ * @summary test International Decimal Format Symbols
+ */
+/*
+(C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+(C) Copyright IBM Corp. 1996, 1997 - All Rights Reserved
+
+ The original version of this source code and documentation is copyrighted and
+owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
+provided under terms of a License Agreement between Taligent and Sun. This
+technology is protected by multiple US and International patents. This notice and
+attribution to Taligent may not be removed.
+ Taligent is a registered trademark of Taligent, Inc.
+*/
+
+import java.text.*;
+import java.util.*;
+
+public class IntlTestDecimalFormatSymbols extends IntlTest
+{
+ public static void main(String[] args) throws Exception {
+ new IntlTestDecimalFormatSymbols().run(args);
+ }
+
+ // Test the API of DecimalFormatSymbols; primarily a simple get/set set.
+ public void TestSymbols()
+ {
+ DecimalFormatSymbols fr = new DecimalFormatSymbols(Locale.FRENCH);
+
+ DecimalFormatSymbols en = new DecimalFormatSymbols(Locale.ENGLISH);
+
+ if(en.equals(fr)) {
+ errln("ERROR: English DecimalFormatSymbols equal to French");
+ }
+
+ // just do some VERY basic tests to make sure that get/set work
+
+ char zero = en.getZeroDigit();
+ fr.setZeroDigit(zero);
+ if(fr.getZeroDigit() != en.getZeroDigit()) {
+ errln("ERROR: get/set ZeroDigit failed");
+ }
+
+ char group = en.getGroupingSeparator();
+ fr.setGroupingSeparator(group);
+ if(fr.getGroupingSeparator() != en.getGroupingSeparator()) {
+ errln("ERROR: get/set GroupingSeparator failed");
+ }
+
+ char decimal = en.getDecimalSeparator();
+ fr.setDecimalSeparator(decimal);
+ if(fr.getDecimalSeparator() != en.getDecimalSeparator()) {
+ errln("ERROR: get/set DecimalSeparator failed");
+ }
+
+ char perMill = en.getPerMill();
+ fr.setPerMill(perMill);
+ if(fr.getPerMill() != en.getPerMill()) {
+ errln("ERROR: get/set PerMill failed");
+ }
+
+ char percent = en.getPercent();
+ fr.setPercent(percent);
+ if(fr.getPercent() != en.getPercent()) {
+ errln("ERROR: get/set Percent failed");
+ }
+
+ char digit = en.getDigit();
+ fr.setDigit(digit);
+ if(fr.getPercent() != en.getPercent()) {
+ errln("ERROR: get/set Percent failed");
+ }
+
+ char patternSeparator = en.getPatternSeparator();
+ fr.setPatternSeparator(patternSeparator);
+ if(fr.getPatternSeparator() != en.getPatternSeparator()) {
+ errln("ERROR: get/set PatternSeparator failed");
+ }
+
+ String infinity = en.getInfinity();
+ fr.setInfinity(infinity);
+ String infinity2 = fr.getInfinity();
+ if(! infinity.equals(infinity2)) {
+ errln("ERROR: get/set Infinity failed");
+ }
+
+ String nan = en.getNaN();
+ fr.setNaN(nan);
+ String nan2 = fr.getNaN();
+ if(! nan.equals(nan2)) {
+ errln("ERROR: get/set NaN failed");
+ }
+
+ char minusSign = en.getMinusSign();
+ fr.setMinusSign(minusSign);
+ if(fr.getMinusSign() != en.getMinusSign()) {
+ errln("ERROR: get/set MinusSign failed");
+ }
+
+// char exponential = en.getExponentialSymbol();
+// fr.setExponentialSymbol(exponential);
+// if(fr.getExponentialSymbol() != en.getExponentialSymbol()) {
+// errln("ERROR: get/set Exponential failed");
+// }
+
+ DecimalFormatSymbols foo = new DecimalFormatSymbols();
+
+ en = (DecimalFormatSymbols) fr.clone();
+
+ if(! en.equals(fr)) {
+ errln("ERROR: Clone failed");
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/IntlTestNumberFormatAPI.java b/jdk/test/java/text/Format/NumberFormat/IntlTestNumberFormatAPI.java
new file mode 100644
index 00000000000..ab1069bdfc2
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/IntlTestNumberFormatAPI.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 1998, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /java/text/testlib
+ * @summary test International Number Format API
+ */
+/*
+(C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+(C) Copyright IBM Corp. 1996, 1997 - All Rights Reserved
+
+ The original version of this source code and documentation is copyrighted and
+owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
+provided under terms of a License Agreement between Taligent and Sun. This
+technology is protected by multiple US and International patents. This notice and
+attribution to Taligent may not be removed.
+ Taligent is a registered trademark of Taligent, Inc.
+*/
+
+import java.text.*;
+import java.util.*;
+
+public class IntlTestNumberFormatAPI extends IntlTest
+{
+ public static void main(String[] args) throws Exception {
+ new IntlTestNumberFormatAPI().run(args);
+ }
+
+ // This test checks various generic API methods in DecimalFormat to achieve 100% API coverage.
+ public void TestAPI()
+ {
+ Locale reservedLocale = Locale.getDefault();
+ try {
+ logln("NumberFormat API test---"); logln("");
+ Locale.setDefault(Locale.ENGLISH);
+
+ // ======= Test constructors
+
+ logln("Testing NumberFormat constructors");
+
+ NumberFormat def = NumberFormat.getInstance();
+
+ NumberFormat fr = NumberFormat.getInstance(Locale.FRENCH);
+
+ NumberFormat cur = NumberFormat.getCurrencyInstance();
+
+ NumberFormat cur_fr =
+ NumberFormat.getCurrencyInstance(Locale.FRENCH);
+
+ NumberFormat per = NumberFormat.getPercentInstance();
+
+ NumberFormat per_fr =
+ NumberFormat.getPercentInstance(Locale.FRENCH);
+
+ // ======= Test equality
+
+ logln("Testing equality operator");
+
+ if( per_fr.equals(cur_fr) ) {
+ errln("ERROR: == failed");
+ }
+
+ // ======= Test various format() methods
+
+ logln("Testing various format() methods");
+
+// final double d = -10456.0037; // this appears as
+ // -10456.003700000001 on NT
+// final double d = -1.04560037e-4; // this appears as
+ // -1.0456003700000002E-4 on NT
+ final double d = -10456.00370000000000; // this works!
+ final long l = 100000000;
+
+ String res1 = new String();
+ String res2 = new String();
+ StringBuffer res3 = new StringBuffer();
+ StringBuffer res4 = new StringBuffer();
+ StringBuffer res5 = new StringBuffer();
+ StringBuffer res6 = new StringBuffer();
+ FieldPosition pos1 = new FieldPosition(0);
+ FieldPosition pos2 = new FieldPosition(0);
+ FieldPosition pos3 = new FieldPosition(0);
+ FieldPosition pos4 = new FieldPosition(0);
+
+ res1 = cur_fr.format(d);
+ logln( "" + d + " formatted to " + res1);
+
+ res2 = cur_fr.format(l);
+ logln("" + l + " formatted to " + res2);
+
+ res3 = cur_fr.format(d, res3, pos1);
+ logln( "" + d + " formatted to " + res3);
+
+ res4 = cur_fr.format(l, res4, pos2);
+ logln("" + l + " formatted to " + res4);
+
+ res5 = cur_fr.format(d, res5, pos3);
+ logln("" + d + " formatted to " + res5);
+
+ res6 = cur_fr.format(l, res6, pos4);
+ logln("" + l + " formatted to " + res6);
+
+
+ // ======= Test parse()
+
+ logln("Testing parse()");
+
+// String text = new String("-10,456.0037");
+ String text = new String("-10456,0037");
+ ParsePosition pos = new ParsePosition(0);
+ ParsePosition pos01 = new ParsePosition(0);
+ double d1 = ((Number)fr.parseObject(text, pos)).doubleValue();
+ if(d1 != d) {
+ errln("ERROR: Roundtrip failed (via parse()) for " + text);
+ }
+ logln(text + " parsed into " + d1);
+
+ double d2 = fr.parse(text, pos01).doubleValue();
+ if(d2 != d) {
+ errln("ERROR: Roundtrip failed (via parse()) for " + text);
+ }
+ logln(text + " parsed into " + d2);
+
+ double d3 = 0;
+ try {
+ d3 = fr.parse(text).doubleValue();
+ }
+ catch (ParseException e) {
+ errln("ERROR: parse() failed");
+ }
+ if(d3 != d) {
+ errln("ERROR: Roundtrip failed (via parse()) for " + text);
+ }
+ logln(text + " parsed into " + d3);
+
+
+ // ======= Test getters and setters
+
+ logln("Testing getters and setters");
+
+ final Locale[] locales = NumberFormat.getAvailableLocales();
+ long count = locales.length;
+ logln("Got " + count + " locales" );
+ for(int i = 0; i < count; i++) {
+ String name;
+ name = locales[i].getDisplayName();
+ logln(name);
+ }
+
+ fr.setParseIntegerOnly( def.isParseIntegerOnly() );
+ if(fr.isParseIntegerOnly() != def.isParseIntegerOnly() ) {
+ errln("ERROR: setParseIntegerOnly() failed");
+ }
+
+ fr.setGroupingUsed( def.isGroupingUsed() );
+ if(fr.isGroupingUsed() != def.isGroupingUsed() ) {
+ errln("ERROR: setGroupingUsed() failed");
+ }
+
+ fr.setMaximumIntegerDigits( def.getMaximumIntegerDigits() );
+ if(fr.getMaximumIntegerDigits() != def.getMaximumIntegerDigits() ) {
+ errln("ERROR: setMaximumIntegerDigits() failed");
+ }
+
+ fr.setMinimumIntegerDigits( def.getMinimumIntegerDigits() );
+ if(fr.getMinimumIntegerDigits() != def.getMinimumIntegerDigits() ) {
+ errln("ERROR: setMinimumIntegerDigits() failed");
+ }
+
+ fr.setMaximumFractionDigits( def.getMaximumFractionDigits() );
+ if(fr.getMaximumFractionDigits() != def.getMaximumFractionDigits() ) {
+ errln("ERROR: setMaximumFractionDigits() failed");
+ }
+
+ fr.setMinimumFractionDigits( def.getMinimumFractionDigits() );
+ if(fr.getMinimumFractionDigits() != def.getMinimumFractionDigits() ) {
+ errln("ERROR: setMinimumFractionDigits() failed");
+ }
+
+ // ======= Test getStaticClassID()
+
+// logln("Testing instanceof()");
+
+// try {
+// NumberFormat test = new DecimalFormat();
+
+// if (! (test instanceof DecimalFormat)) {
+// errln("ERROR: instanceof failed");
+// }
+// }
+// catch (Exception e) {
+// errln("ERROR: Couldn't create a DecimalFormat");
+// }
+ } finally {
+ // restore the reserved locale
+ Locale.setDefault(reservedLocale);
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/NumberFormat4185761a.ser.txt b/jdk/test/java/text/Format/NumberFormat/NumberFormat4185761a.ser.txt
new file mode 100644
index 00000000000..d27bb94eb69
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/NumberFormat4185761a.ser.txt
@@ -0,0 +1,57 @@
+#
+# Copyright (c) 1999, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Hex dump of a serialized NumberFormat for NumberRegression.
+
+aced0005737200176a6176612e746578742e446563696d616c466f726d61740b
+ff0362d872303a02000b5a001b646563696d616c536570617261746f72416c77
+61797353686f776e42000c67726f7570696e6753697a654200116d696e457870
+6f6e656e7444696769747349000a6d756c7469706c6965724900157365726961
+6c56657273696f6e4f6e53747265616d5a00167573654578706f6e656e746961
+6c4e6f746174696f6e4c000e6e656761746976655072656669787400124c6a61
+76612f6c616e672f537472696e673b4c000e6e65676174697665537566666978
+71007e00014c000e706f73697469766550726566697871007e00014c000e706f
+73697469766553756666697871007e00014c000773796d626f6c737400204c6a
+6176612f746578742f446563696d616c466f726d617453796d626f6c733b7872
+00166a6176612e746578742e4e756d626572466f726d6174dff6b3bf137d07e8
+03000b5a000c67726f7570696e67557365644200116d61784672616374696f6e
+4469676974734200106d6178496e74656765724469676974734900156d617869
+6d756d4672616374696f6e4469676974734900146d6178696d756d496e746567
+65724469676974734200116d696e4672616374696f6e4469676974734200106d
+696e496e74656765724469676974734900156d696e696d756d4672616374696f
+6e4469676974734900146d696e696d756d496e74656765724469676974735a00
+107061727365496e74656765724f6e6c7949001573657269616c56657273696f
+6e4f6e53747265616d787200106a6176612e746578742e466f726d6174fbd8bc
+12e90f18430200007870017f7f00000123000001217f7f000001240000012200
+00000001780003000000000100000001007400012d7400007400007400007372
+001e6a6176612e746578742e446563696d616c466f726d617453796d626f6c73
+501d17990868939c02000f430010646563696d616c536570617261746f724300
+05646967697443000b6578706f6e656e7469616c43001167726f7570696e6753
+6570617261746f724300096d696e75735369676e4300116d6f6e657461727953
+6570617261746f724300107061747465726e536570617261746f724300077065
+724d696c6c43000770657263656e7449001573657269616c56657273696f6e4f
+6e53747265616d4300097a65726f44696769744c00034e614e71007e00014c00
+0e63757272656e637953796d626f6c71007e00014c0008696e66696e69747971
+007e00014c0012696e746c43757272656e637953796d626f6c71007e00017870
+002e00230045002c002d002e003b20300025000000010030740003efbfbd7400
+0124740003e2889e740003555344
diff --git a/jdk/test/java/text/Format/NumberFormat/NumberFormat4185761b.ser.txt b/jdk/test/java/text/Format/NumberFormat/NumberFormat4185761b.ser.txt
new file mode 100644
index 00000000000..8da4dde6bd1
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/NumberFormat4185761b.ser.txt
@@ -0,0 +1,57 @@
+#
+# Copyright (c) 1999, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Hex dump of a serialized NumberFormat for NumberRegression.
+
+aced0005737200176a6176612e746578742e446563696d616c466f726d61740b
+ff0362d872303a02000b5a001b646563696d616c536570617261746f72416c77
+61797353686f776e42000c67726f7570696e6753697a654200116d696e457870
+6f6e656e7444696769747349000a6d756c7469706c6965724900157365726961
+6c56657273696f6e4f6e53747265616d5a00167573654578706f6e656e746961
+6c4e6f746174696f6e4c000e6e656761746976655072656669787400124c6a61
+76612f6c616e672f537472696e673b4c000e6e65676174697665537566666978
+71007e00014c000e706f73697469766550726566697871007e00014c000e706f
+73697469766553756666697871007e00014c000773796d626f6c737400204c6a
+6176612f746578742f446563696d616c466f726d617453796d626f6c733b7872
+00166a6176612e746578742e4e756d626572466f726d6174dff6b3bf137d07e8
+03000b5a000c67726f7570696e67557365644200116d61784672616374696f6e
+4469676974734200106d6178496e74656765724469676974734900156d617869
+6d756d4672616374696f6e4469676974734900146d6178696d756d496e746567
+65724469676974734200116d696e4672616374696f6e4469676974734200106d
+696e496e74656765724469676974734900156d696e696d756d4672616374696f
+6e4469676974734900146d696e696d756d496e74656765724469676974735a00
+107061727365496e74656765724f6e6c7949001573657269616c56657273696f
+6e4f6e53747265616d787200106a6176612e746578742e466f726d6174fbd8bc
+12e90f18430200007870017f7f00000314000003127f7f000003130000031100
+00000001780003000000000100000001007400012d7400007400007400007372
+001e6a6176612e746578742e446563696d616c466f726d617453796d626f6c73
+501d17990868939c02000f430010646563696d616c536570617261746f724300
+05646967697443000b6578706f6e656e7469616c43001167726f7570696e6753
+6570617261746f724300096d696e75735369676e4300116d6f6e657461727953
+6570617261746f724300107061747465726e536570617261746f724300077065
+724d696c6c43000770657263656e7449001573657269616c56657273696f6e4f
+6e53747265616d4300097a65726f44696769744c00034e614e71007e00014c00
+0e63757272656e637953796d626f6c71007e00014c0008696e66696e69747971
+007e00014c0012696e746c43757272656e637953796d626f6c71007e00017870
+002e00230045002c002d002e003b20300025000000010030740003efbfbd7400
+0124740003e2889e740003555344
diff --git a/jdk/test/java/text/Format/NumberFormat/NumberFormatRounding.java b/jdk/test/java/text/Format/NumberFormat/NumberFormatRounding.java
new file mode 100644
index 00000000000..895d885ff2e
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/NumberFormatRounding.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4092330 6246348
+ * @summary Tests for rounding mode in NumberFormat
+ */
+
+import java.math.*;
+import java.text.*;
+
+public class NumberFormatRounding {
+
+ static final String AE = "ArithmeticException";
+
+ static final double src[] = {5.5, 2.5, 1.6, 1.1, 1.0, -1.0, -1.1, -1.6, -2.5, -5.5,
+ 5.501, -5.501, 5.500, -5.500, 1.001, -1.001, 4.501, -4.501, 4.500, -4.500};
+ static final String up[] = {"6", "3", "2", "2", "1", "-1", "-2", "-2", "-3", "-6",
+ "6", "-6", "6", "-6", "2", "-2", "5", "-5", "5", "-5"};
+ static final String down[] = {"5", "2", "1", "1", "1", "-1", "-1", "-1", "-2", "-5",
+ "5", "-5", "5", "-5", "1", "-1", "4", "-4", "4", "-4"};
+ static final String ceiling[] = {"6", "3", "2", "2", "1", "-1", "-1", "-1", "-2", "-5",
+ "6", "-5", "6", "-5", "2", "-1", "5", "-4", "5", "-4"};
+ static final String floor[] = {"5", "2", "1", "1", "1", "-1", "-2", "-2", "-3", "-6",
+ "5", "-6", "5", "-6", "1", "-2", "4", "-5", "4", "-5"};
+ static final String half_up[] = {"6", "3", "2", "1", "1", "-1", "-1", "-2", "-3", "-6",
+ "6", "-6", "6", "-6", "1", "-1", "5", "-5", "5", "-5"};
+ static final String half_down[] = {"5", "2", "2", "1", "1", "-1", "-1", "-2", "-2", "-5",
+ "6", "-6", "5", "-5", "1", "-1", "5", "-5", "4", "-4"};
+ static final String half_even[] = {"6", "2", "2", "1", "1", "-1", "-1", "-2", "-2", "-6",
+ "6", "-6", "6", "-6", "1", "-1", "5", "-5", "4", "-4"};
+ static final String unnecessary[] = {AE, AE, AE, AE, "1", "-1", AE, AE, AE, AE,
+ AE, AE, AE, AE, AE, AE, AE, AE, AE, AE};
+
+ public static void main(String[] args) {
+ basicTest();
+
+ roundTest(RoundingMode.UP, up);
+ roundTest(RoundingMode.DOWN, down);
+ roundTest(RoundingMode.CEILING, ceiling);
+ roundTest(RoundingMode.FLOOR, floor);
+ roundTest(RoundingMode.HALF_UP, half_up);
+ roundTest(RoundingMode.HALF_DOWN, half_down);
+ roundTest(RoundingMode.HALF_EVEN, half_even);
+ roundTest(RoundingMode.UNNECESSARY, unnecessary);
+ }
+
+ static void basicTest() {
+ NumberFormat nf = NumberFormat.getIntegerInstance();
+
+ if (nf.getRoundingMode() != RoundingMode.HALF_EVEN) {
+ throw new RuntimeException("default rounding is not HALF_EVEN");
+ }
+
+ try {
+ nf.setRoundingMode(null);
+ throw new RuntimeException(
+ "NullPointerException is not thrown by calling setRoundingMode(null)");
+ } catch (NullPointerException npe) {
+ // continue testing
+ }
+
+ ChoiceFormat cf = new ChoiceFormat("");
+
+ try {
+ cf.setRoundingMode(RoundingMode.HALF_EVEN);
+ throw new RuntimeException(
+ "UnsupportedOperationException is not thrown by calling setRoundingMode()");
+ } catch (UnsupportedOperationException uoe) {
+ // continue testing
+ }
+
+ try {
+ cf.getRoundingMode();
+ throw new RuntimeException(
+ "UnsupportedOperationException is not thrown by calling getRoundingMode()");
+ } catch (UnsupportedOperationException uoe) {
+ // continue testing
+ }
+ }
+
+ static void roundTest(RoundingMode rm, String[] expected) {
+ NumberFormat nf = NumberFormat.getIntegerInstance();
+ nf.setRoundingMode(rm);
+
+ if (nf.getRoundingMode() != rm) {
+ throw new RuntimeException("set rounding mode is not returned by get method");
+ }
+
+ for (int i = 0; i < src.length; i ++) {
+ String result = null;
+ try {
+ result = nf.parse(nf.format(src[i])).toString();
+ if (!result.equals(expected[i])) {
+ throw new RuntimeException("rounding test #"+i+" failed. mode: "+rm+" src: "+src[i]+" expected: "+expected[i]+" result: "+result);
+ }
+ } catch (ArithmeticException ae) {
+ if (expected[i].equals(AE)) {
+ continue;
+ } else {
+ result = AE;
+ throw new RuntimeException("rounding test #"+i+" failed. mode: "+rm+" src: "+src[i]+" expected: "+expected[i]+" result: "+result);
+ }
+ } catch (ParseException pe) {
+ throw new RuntimeException("ParseException ocurred.", pe);
+ }
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/NumberRegression.java b/jdk/test/java/text/Format/NumberFormat/NumberRegression.java
new file mode 100644
index 00000000000..674fdd619ca
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/NumberRegression.java
@@ -0,0 +1,1824 @@
+/*
+ * Copyright (c) 1997, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4052223 4059870 4061302 4062486 4066646 4068693 4070798 4071005 4071014
+ * 4071492 4071859 4074454 4074620 4075713 4083018 4086575 4087244 4087245
+ * 4087251 4087535 4088161 4088503 4090489 4090504 4092480 4092561 4095713
+ * 4098741 4099404 4101481 4106658 4106662 4106664 4108738 4110936 4122840
+ * 4125885 4134034 4134300 4140009 4141750 4145457 4147295 4147706 4162198
+ * 4162852 4167494 4170798 4176114 4179818 4185761 4212072 4212073 4216742
+ * 4217661 4243011 4243108 4330377 4233840 4241880 4833877 8008577
+ * @summary Regression tests for NumberFormat and associated classes
+ * @library /java/text/testlib
+ * @build IntlTest HexDumpReader
+ * @modules java.base/sun.util.resources
+ * @compile -XDignore.symbol.file NumberRegression.java
+ * @run main/othervm -Djava.locale.providers=COMPAT,SPI NumberRegression
+ */
+
+/*
+(C) Copyright Taligent, Inc. 1996 - All Rights Reserved
+(C) Copyright IBM Corp. 1996 - All Rights Reserved
+
+ The original version of this source code and documentation is copyrighted and
+owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
+provided under terms of a License Agreement between Taligent and Sun. This
+technology is protected by multiple US and International patents. This notice and
+attribution to Taligent may not be removed.
+ Taligent is a registered trademark of Taligent, Inc.
+*/
+
+import java.text.*;
+import java.util.*;
+import java.math.BigDecimal;
+import java.io.*;
+import java.math.BigInteger;
+import sun.util.resources.LocaleData;
+
+public class NumberRegression extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new NumberRegression().run(args);
+ }
+
+ /**
+ * NumberFormat.equals comparing with null should always return false.
+ */
+ public void Test4075713(){
+
+ try {
+ MyNumberFormatTest tmp = new MyNumberFormatTest();
+ if (!tmp.equals(null))
+ logln("NumberFormat.equals passed");
+ } catch (NullPointerException e) {
+ errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception");
+ }
+ }
+
+ /**
+ * NumberFormat.equals comparing two obj equal even the setGroupingUsed
+ * flag is different.
+ */
+ public void Test4074620() {
+
+ MyNumberFormatTest nf1 = new MyNumberFormatTest();
+ MyNumberFormatTest nf2 = new MyNumberFormatTest();
+
+ nf1.setGroupingUsed(false);
+ nf2.setGroupingUsed(true);
+
+ if (nf1.equals(nf2)) errln("Test for bug 4074620 failed");
+ else logln("Test for bug 4074620 passed.");
+ return;
+ }
+
+
+ /**
+ * DecimalFormat.format() incorrectly uses maxFractionDigits setting.
+ */
+
+ public void Test4088161 (){
+ DecimalFormat df = new DecimalFormat();
+ double d = 100;
+ df.setMinimumFractionDigits(0);
+ df.setMaximumFractionDigits(16);
+ StringBuffer sBuf1 = new StringBuffer("");
+ FieldPosition fp1 = new FieldPosition(0);
+ logln("d = " + d);
+ logln("maxFractionDigits = " + df.getMaximumFractionDigits());
+ logln(" format(d) = '" + df.format(d, sBuf1, fp1) + "'");
+ df.setMaximumFractionDigits(17);
+ StringBuffer sBuf2 = new StringBuffer("");
+ FieldPosition fp2 = new FieldPosition(0);
+ logln("maxFractionDigits = " + df.getMaximumFractionDigits());
+ df.format(d, sBuf2, fp2);
+ String expected = Locale.getDefault().equals(new Locale("hi", "IN")) ?
+ "\u0967\u0966\u0966" : "100";
+ if (!sBuf2.toString().equals(expected))
+ errln(" format(d) = '" + sBuf2 + "'");
+ }
+ /**
+ * DecimalFormatSymbols should be cloned in the ctor DecimalFormat.
+ * DecimalFormat(String, DecimalFormatSymbols).
+ */
+ public void Test4087245 (){
+ DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
+ DecimalFormat df = new DecimalFormat("#,##0.0", symbols);
+ long n = 123;
+ StringBuffer buf1 = new StringBuffer();
+ StringBuffer buf2 = new StringBuffer();
+ logln("format(" + n + ") = " +
+ df.format(n, buf1, new FieldPosition(0)));
+ symbols.setDecimalSeparator('p'); // change value of field
+ logln("format(" + n + ") = " +
+ df.format(n, buf2, new FieldPosition(0)));
+ if (!buf1.toString().equals(buf2.toString()))
+ errln("Test for bug 4087245 failed");
+ }
+ /**
+ * DecimalFormat.format() incorrectly formats 0.0
+ */
+ public void Test4087535 ()
+ {
+ DecimalFormat df = new DecimalFormat();
+ df.setMinimumIntegerDigits(0);
+
+ double n = 0;
+ String buffer = new String();
+ buffer = df.format(n);
+ if (buffer.length() == 0)
+ errln(n + ": '" + buffer + "'");
+ n = 0.1;
+ buffer = df.format(n);
+ if (buffer.length() == 0)
+ errln(n + ": '" + buffer + "'");
+ }
+
+ /**
+ * DecimalFormat.format fails when groupingSize is set to 0.
+ */
+ public void Test4088503 (){
+ DecimalFormat df = new DecimalFormat();
+ df.setGroupingSize(0);
+ StringBuffer sBuf = new StringBuffer("");
+ FieldPosition fp = new FieldPosition(0);
+ try {
+ logln(df.format(123, sBuf, fp).toString());
+ } catch (Exception foo) {
+ errln("Test for bug 4088503 failed.");
+ }
+
+ }
+ /**
+ * NumberFormat.getCurrencyInstance is wrong.
+ */
+ public void Test4066646 () {
+ float returnfloat = 0.0f;
+ assignFloatValue(2.04f);
+ assignFloatValue(2.03f);
+ assignFloatValue(2.02f);
+ assignFloatValue(0.0f);
+ }
+
+ public float assignFloatValue(float returnfloat)
+ {
+ logln(" VALUE " + returnfloat);
+ NumberFormat nfcommon = NumberFormat.getCurrencyInstance(Locale.US);
+ nfcommon.setGroupingUsed(false);
+
+ String stringValue = nfcommon.format(returnfloat).substring(1);
+ if (Float.valueOf(stringValue).floatValue() != returnfloat)
+ errln(" DISPLAYVALUE " + stringValue);
+ return returnfloat;
+ } // End Of assignFloatValue()
+
+ /**
+ * DecimalFormat throws exception when parsing "0"
+ */
+ public void Test4059870() {
+ DecimalFormat format = new DecimalFormat("00");
+ try {
+ logln(format.parse("0").toString());
+ } catch (Exception e) { errln("Test for bug 4059870 failed : " + e); }
+ }
+ /**
+ * DecimalFormatSymbol.equals should always return false when
+ * comparing with null.
+ */
+
+ public void Test4083018 (){
+ DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance();
+ try {
+ if (!dfs.equals(null))
+ logln("Test Passed!");
+ } catch (Exception foo) {
+ errln("Test for bug 4083018 failed => Message : " + foo.getMessage());
+ }
+ }
+ /**
+ * DecimalFormat does not round up correctly.
+ */
+ public void Test4071492 (){
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ double x = 0.00159999;
+ NumberFormat nf = NumberFormat.getInstance();
+ nf.setMaximumFractionDigits(4);
+ String out = nf.format(x);
+ logln("0.00159999 formats with 4 fractional digits to " + out);
+ String expected = "0.0016";
+ if (!out.equals(expected))
+ errln("FAIL: Expected " + expected);
+ Locale.setDefault(savedLocale);
+ }
+
+ /**
+ * A space as a group separator for localized pattern causes
+ * wrong format. WorkAround : use non-breaking space.
+ */
+ public void Test4086575() {
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
+ logln("nf toPattern1: " + ((DecimalFormat)nf).toPattern());
+ logln("nf toLocPattern1: " + ((DecimalFormat)nf).toLocalizedPattern());
+
+ // No group separator
+ logln("...applyLocalizedPattern ###,00;(###,00) ");
+ ((DecimalFormat)nf).applyLocalizedPattern("###,00;(###,00)");
+ logln("nf toPattern2: " + ((DecimalFormat)nf).toPattern());
+ logln("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern());
+
+ logln("nf: " + nf.format(1234)); // 1234,00
+ logln("nf: " + nf.format(-1234)); // (1234,00)
+
+ // Space as group separator
+
+ logln("...applyLocalizedPattern # ###,00;(# ###,00) ");
+ ((DecimalFormat)nf).applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)");
+ logln("nf toPattern2: " + ((DecimalFormat)nf).toPattern());
+ logln("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern());
+ String buffer = nf.format(1234);
+ if (!buffer.equals("1\u00a0234,00"))
+ errln("nf : " + buffer); // Expect 1 234,00
+ buffer = nf.format(-1234);
+ if (!buffer.equals("(1\u00a0234,00)"))
+ errln("nf : " + buffer); // Expect (1 234,00)
+
+ // Erroneously prints:
+ // 1234,00 ,
+ // (1234,00 ,)
+
+ }
+ /**
+ * DecimalFormat.parse returns wrong value
+ */
+ public void Test4068693()
+ {
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ logln("----- Test Application -----");
+ ParsePosition pos;
+ DecimalFormat df = new DecimalFormat();
+ Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0));
+ if (!d.toString().equals("123.55456")) {
+ errln("Result -> " + d.doubleValue());
+ }
+ Locale.setDefault(savedLocale);
+ }
+
+ /* bugs 4069754, 4067878
+ * null pointer thrown when accessing a deserialized DecimalFormat
+ * object.
+ */
+ public void Test4069754()
+ {
+ try {
+ myformat it = new myformat();
+ logln(it.Now());
+ FileOutputStream ostream = new FileOutputStream("t.tmp");
+ ObjectOutputStream p = new ObjectOutputStream(ostream);
+ p.writeObject(it);
+ ostream.close();
+ logln("Saved ok.");
+
+ FileInputStream istream = new FileInputStream("t.tmp");
+ ObjectInputStream p2 = new ObjectInputStream(istream);
+ myformat it2 = (myformat)p2.readObject();
+ logln(it2.Now());
+ istream.close();
+ logln("Loaded ok.");
+ } catch (Exception foo) {
+ errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage());
+ }
+ }
+
+ /**
+ * DecimalFormat.applyPattern(String) allows illegal patterns
+ */
+ public void Test4087251 (){
+ DecimalFormat df = new DecimalFormat();
+ try {
+ df.applyPattern("#.#.#");
+ logln("toPattern() returns \"" + df.toPattern() + "\"");
+ errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ logln("Caught Illegal Argument Error !");
+ }
+ // Second test; added 5/11/98 when reported to fail on 1.2b3
+ try {
+ df.applyPattern("#0.0#0#0");
+ logln("toPattern() returns \"" + df.toPattern() + "\"");
+ errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ logln("Ok - IllegalArgumentException for #0.0#0#0");
+ }
+ }
+
+ /**
+ * DecimalFormat.format() loses precision
+ */
+ public void Test4090489 (){
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ DecimalFormat df = new DecimalFormat();
+ df.setMinimumFractionDigits(10);
+ df.setGroupingUsed(false);
+ double d = 1.000000000000001E7;
+ BigDecimal bd = new BigDecimal(d);
+ StringBuffer sb = new StringBuffer("");
+ FieldPosition fp = new FieldPosition(0);
+ logln("d = " + d);
+ logln("BigDecimal.toString(): " + bd.toString());
+ df.format(d, sb, fp);
+ if (!sb.toString().equals("10000000.0000000100")) {
+ errln("DecimalFormat.format(): " + sb.toString());
+ }
+ Locale.setDefault(savedLocale);
+ }
+
+ /**
+ * DecimalFormat.format() loses precision
+ */
+ public void Test4090504 ()
+ {
+ double d = 1;
+ logln("d = " + d);
+ DecimalFormat df = new DecimalFormat();
+ StringBuffer sb;
+ FieldPosition fp;
+ try {
+ for (int i = 17; i <= 20; i++) {
+ df.setMaximumFractionDigits(i);
+ sb = new StringBuffer("");
+ fp = new FieldPosition(0);
+ logln(" getMaximumFractionDigits() = " + i);
+ logln(" formated: " + df.format(d, sb, fp));
+ }
+ } catch (Exception foo) {
+ errln("Bug 4090504 regression test failed. Message : " + foo.getMessage());
+ }
+ }
+ /**
+ * DecimalFormat.parse(String str, ParsePosition pp) loses precision
+ */
+ public void Test4095713 ()
+ {
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ DecimalFormat df = new DecimalFormat();
+ String str = "0.1234";
+ Double d1 = new Double(str);
+ Double d2 = (Double) df.parse(str, new ParsePosition(0));
+ logln(d1.toString());
+ if (d2.doubleValue() != d1.doubleValue())
+ errln("Bug 4095713 test failed, new double value : " + d2.doubleValue());
+ Locale.setDefault(savedLocale);
+ }
+
+ /**
+ * DecimalFormat.parse() fails when multiplier is not set to 1
+ */
+ public void Test4092561 ()
+ {
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ DecimalFormat df = new DecimalFormat();
+
+ String str = Long.toString(Long.MIN_VALUE);
+ logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString());
+ df.setMultiplier(100);
+ Number num = df.parse(str, new ParsePosition(0));
+ if (num.doubleValue() != -9.223372036854776E16) {
+ errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: -9.223372036854776E16, got: " + num.doubleValue());
+ }
+
+ df.setMultiplier(-100);
+ num = df.parse(str, new ParsePosition(0));
+ if (num.doubleValue() != 9.223372036854776E16) {
+ errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: 9.223372036854776E16, got: " + num.doubleValue());
+ }
+
+ str = Long.toString(Long.MAX_VALUE);
+ logln("Long.MAX_VALUE : " + df.parse(str, new ParsePosition(0)).toString());
+
+ df.setMultiplier(100);
+ num = df.parse(str, new ParsePosition(0));
+ if (num.doubleValue() != 9.223372036854776E16) {
+ errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: 9.223372036854776E16, got: " + num.doubleValue());
+ }
+
+ df.setMultiplier(-100);
+ num = df.parse(str, new ParsePosition(0));
+ if (num.doubleValue() != -9.223372036854776E16) {
+ errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: -9.223372036854776E16, got: " + num.doubleValue());
+ }
+
+ Locale.setDefault(savedLocale);
+ }
+
+ /**
+ * DecimalFormat: Negative format ignored.
+ */
+ public void Test4092480 ()
+ {
+ DecimalFormat dfFoo = new DecimalFormat("000");
+
+ try {
+ dfFoo.applyPattern("0000;-000");
+ if (!dfFoo.toPattern().equals("#0000"))
+ errln("dfFoo.toPattern : " + dfFoo.toPattern());
+ logln(dfFoo.format(42));
+ logln(dfFoo.format(-42));
+ dfFoo.applyPattern("000;-000");
+ if (!dfFoo.toPattern().equals("#000"))
+ errln("dfFoo.toPattern : " + dfFoo.toPattern());
+ logln(dfFoo.format(42));
+ logln(dfFoo.format(-42));
+
+ dfFoo.applyPattern("000;-0000");
+ if (!dfFoo.toPattern().equals("#000"))
+ errln("dfFoo.toPattern : " + dfFoo.toPattern());
+ logln(dfFoo.format(42));
+ logln(dfFoo.format(-42));
+
+ dfFoo.applyPattern("0000;-000");
+ if (!dfFoo.toPattern().equals("#0000"))
+ errln("dfFoo.toPattern : " + dfFoo.toPattern());
+ logln(dfFoo.format(42));
+ logln(dfFoo.format(-42));
+ } catch (Exception foo) {
+ errln("Message " + foo.getMessage());
+ }
+ }
+ /**
+ * NumberFormat.getCurrencyInstance() produces format that uses
+ * decimal separator instead of monetary decimal separator.
+ *
+ * Rewrote this test not to depend on the actual pattern. Pattern should
+ * never contain the monetary separator! Decimal separator in pattern is
+ * interpreted as monetary separator if currency symbol is seen!
+ */
+ public void Test4087244 () {
+ Locale de = new Locale("pt", "PT");
+ DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(de);
+ DecimalFormatSymbols sym = df.getDecimalFormatSymbols();
+ sym.setMonetaryDecimalSeparator('$');
+ df.setDecimalFormatSymbols(sym);
+ char decSep = sym.getDecimalSeparator();
+ char monSep = sym.getMonetaryDecimalSeparator();
+ char zero = sym.getZeroDigit();
+ if (decSep == monSep) {
+ errln("ERROR in test: want decimal sep != monetary sep");
+ } else {
+ df.setMinimumIntegerDigits(1);
+ df.setMinimumFractionDigits(2);
+ String str = df.format(1.23);
+ String monStr = "1" + monSep + "23";
+ String decStr = "1" + decSep + "23";
+ if (str.indexOf(monStr) >= 0 && str.indexOf(decStr) < 0) {
+ logln("OK: 1.23 -> \"" + str + "\" contains \"" +
+ monStr + "\" and not \"" + decStr + '"');
+ } else {
+ errln("FAIL: 1.23 -> \"" + str + "\", should contain \"" +
+ monStr +
+ "\" and not \"" + decStr + '"');
+ }
+ }
+ }
+ /**
+ * Number format data rounding errors for locale FR
+ */
+ public void Test4070798 () {
+ NumberFormat formatter;
+ String tempString;
+ /* User error :
+ String expectedDefault = "-5\u00a0789,987";
+ String expectedCurrency = "5\u00a0789,98 F";
+ String expectedPercent = "-578\u00a0998%";
+ */
+ String expectedDefault = "-5\u00a0789,988";
+ String expectedCurrency = "5\u00a0789,99 \u20AC";
+ // changed for bug 6547501
+ String expectedPercent = "-578\u00a0999 %";
+
+ formatter = NumberFormat.getNumberInstance(Locale.FRANCE);
+ tempString = formatter.format (-5789.9876);
+
+ if (tempString.equals(expectedDefault)) {
+ logln ("Bug 4070798 default test passed.");
+ } else {
+ errln("Failed:" +
+ " Expected " + expectedDefault +
+ " Received " + tempString );
+ }
+
+
+ formatter = NumberFormat.getCurrencyInstance(Locale.FRANCE);
+ tempString = formatter.format( 5789.9876 );
+
+ if (tempString.equals(expectedCurrency) ) {
+ logln ("Bug 4070798 currency test assed.");
+ } else {
+ errln("Failed:" +
+ " Expected " + expectedCurrency +
+ " Received " + tempString );
+ }
+
+
+ formatter = NumberFormat.getPercentInstance(Locale.FRANCE);
+ tempString = formatter.format (-5789.9876);
+
+ if (tempString.equals(expectedPercent) ) {
+ logln ("Bug 4070798 percentage test passed.");
+ } else {
+ errln("Failed:" +
+ " Expected " + expectedPercent +
+ " Received " + tempString );
+ }
+ }
+ /**
+ * Data rounding errors for French (Canada) locale
+ */
+ public void Test4071005 () {
+
+ NumberFormat formatter;
+ String tempString;
+ /* user error :
+ String expectedDefault = "-5 789,987";
+ String expectedCurrency = "5 789,98 $";
+ String expectedPercent = "-578 998%";
+ */
+ String expectedDefault = "-5\u00a0789,988";
+ String expectedCurrency = "5\u00a0789,99 $";
+ // changed for bug 6547501
+ String expectedPercent = "-578\u00a0999 %";
+
+ formatter = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH);
+ tempString = formatter.format (-5789.9876);
+ if (tempString.equals(expectedDefault)) {
+ logln ("Bug 4071005 default test passed.");
+ } else {
+ errln("Failed:" +
+ " Expected " + expectedDefault +
+ " Received " + tempString );
+ }
+
+ formatter = NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH);
+ tempString = formatter.format( 5789.9876 ) ;
+
+ if (tempString.equals(expectedCurrency) ) {
+ logln ("Bug 4071005 currency test passed.");
+ } else {
+ errln("Failed:" +
+ " Expected " + expectedCurrency +
+ " Received " + tempString );
+ }
+ formatter = NumberFormat.getPercentInstance(Locale.CANADA_FRENCH);
+ tempString = formatter.format (-5789.9876);
+
+ if (tempString.equals(expectedPercent) ) {
+ logln ("Bug 4071005 percentage test passed.");
+ } else {
+ errln("Failed:" +
+ " Expected " + expectedPercent +
+ " Received " + tempString );
+ }
+ }
+
+ /**
+ * Data rounding errors for German (Germany) locale
+ */
+ public void Test4071014 () {
+ NumberFormat formatter;
+ String tempString;
+ /* user error :
+ String expectedDefault = "-5.789,987";
+ String expectedCurrency = "5.789,98 DM";
+ String expectedPercent = "-578.998%";
+ */
+ String expectedDefault = "-5.789,988";
+ String expectedCurrency = "5.789,99 \u20AC";
+ String expectedPercent = "-578.999%";
+
+ formatter = NumberFormat.getNumberInstance(Locale.GERMANY);
+ tempString = formatter.format (-5789.9876);
+
+ if (tempString.equals(expectedDefault)) {
+ logln ("Bug 4071014 default test passed.");
+ } else {
+ errln("Failed:" +
+ " Expected " + expectedDefault +
+ " Received " + tempString );
+ }
+
+ formatter = NumberFormat.getCurrencyInstance(Locale.GERMANY);
+ tempString = formatter.format( 5789.9876 ) ;
+
+ if (tempString.equals(expectedCurrency) ) {
+ logln ("Bug 4071014 currency test passed.");
+ } else {
+ errln("Failed:" +
+ " Expected " + expectedCurrency +
+ " Received " + tempString );
+ }
+
+ formatter = NumberFormat.getPercentInstance(Locale.GERMANY);
+ tempString = formatter.format (-5789.9876);
+
+ if (tempString.equals(expectedPercent) ) {
+ logln ("Bug 4071014 percentage test passed.");
+ } else {
+ errln("Failed:" +
+ " Expected " + expectedPercent +
+ " Received " + tempString );
+ }
+
+ }
+ /**
+ * Data rounding errors for Italian locale number formats
+ */
+ public void Test4071859 () {
+ NumberFormat formatter;
+ String tempString;
+ /* user error :
+ String expectedDefault = "-5.789,987";
+ String expectedCurrency = "-L. 5.789,98";
+ String expectedPercent = "-578.998%";
+ */
+ String expectedDefault = "-5.789,988";
+ String expectedCurrency = "-\u20AC 5.789,99";
+ String expectedPercent = "-578.999%";
+
+ formatter = NumberFormat.getNumberInstance(Locale.ITALY);
+ tempString = formatter.format (-5789.9876);
+
+ if (tempString.equals(expectedDefault)) {
+ logln ("Bug 4071859 default test passed.");
+ } else {
+ errln("Failed:" +
+ " Expected " + expectedDefault +
+ " Received " + tempString );
+ }
+
+ formatter = NumberFormat.getCurrencyInstance(Locale.ITALY);
+ tempString = formatter.format( -5789.9876 ) ;
+
+ if (tempString.equals(expectedCurrency) ) {
+ logln ("Bug 4071859 currency test passed.");
+ } else {
+ errln("Failed:" +
+ " Expected " + expectedCurrency +
+ " Received " + tempString );
+ }
+
+ formatter = NumberFormat.getPercentInstance(Locale.ITALY);
+ tempString = formatter.format (-5789.9876);
+
+ if (tempString.equals(expectedPercent) ) {
+ logln ("Bug 4071859 percentage test passed.");
+ } else {
+ errln("Failed:" +
+ " Expected " + expectedPercent +
+ " Received " + tempString );
+ }
+
+ }
+
+ /* bug 4071859
+ * Test rounding for nearest even.
+ */
+ public void Test4093610()
+ {
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ DecimalFormat df = new DecimalFormat("#0.#");
+
+ roundingTest(df, 12.15, "12.2"); // Rounding-up. Above tie (12.150..)
+ roundingTest(df, 12.25, "12.2"); // No round-up. Exact + half-even rule.
+ roundingTest(df, 12.45, "12.4"); // No round-up. Below tie (12.449..)
+ roundingTest(df, 12.450000001,"12.5"); // Rounding-up. Above tie.
+ roundingTest(df, 12.55, "12.6"); // Rounding-up. Above tie (12.550..)
+ roundingTest(df, 12.650000001,"12.7"); // Rounding-up. Above tie.
+ roundingTest(df, 12.75, "12.8"); // Rounding-up. Exact + half-even rule.
+ roundingTest(df, 12.750000001,"12.8"); // Rounding-up. Above tie.
+ roundingTest(df, 12.85, "12.8"); // No round-up. Below tie (12.849..)
+ roundingTest(df, 12.850000001,"12.9"); // Rounding-up. Above tie.
+ roundingTest(df, 12.950000001,"13"); // Rounding-up. Above tie.
+
+ Locale.setDefault(savedLocale);
+ }
+
+ void roundingTest(DecimalFormat df, double x, String expected)
+ {
+ String out = df.format(x);
+ logln("" + x + " formats with 1 fractional digits to " + out);
+ if (!out.equals(expected)) errln("FAIL: Expected " + expected);
+ }
+ /**
+ * Tests the setMaximumFractionDigits limit.
+ */
+ public void Test4098741()
+ {
+ try {
+ NumberFormat fmt = NumberFormat.getPercentInstance();
+ fmt.setMaximumFractionDigits(20);
+ logln(fmt.format(.001));
+ } catch (Exception foo) {
+ errln("Bug 4098471 failed with exception thrown : " + foo.getMessage());
+ }
+ }
+ /**
+ * Tests illegal pattern exception.
+ * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated.
+ * Part2 has been fixed.
+ */
+ public void Test4074454()
+ {
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ try {
+ DecimalFormat fmt = new DecimalFormat("#,#00.00;-#.#");
+ logln("Inconsistent negative pattern is fine.");
+ DecimalFormat newFmt = new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces");
+ String tempString = newFmt.format(3456.78);
+ if (!tempString.equals("3,456.78 p'ieces"))
+ errln("Failed! 3,456.78 p'ieces expected, but got : " + tempString);
+ } catch (Exception foo) {
+ errln("An exception was thrown for any inconsistent negative pattern.");
+ }
+ Locale.setDefault(savedLocale);
+ }
+
+ /**
+ * Tests all different comments.
+ * Response to some comments :
+ * [1] DecimalFormat.parse API documentation is more than just one line.
+ * This is not a reproducable doc error in 116 source code.
+ * [2] See updated javadoc.
+ * [3] Fixed.
+ * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails,
+ * a null object will be returned. The unchanged parse position also
+ * reflects an error.
+ * NumberFormat.parse(String) : If parsing fails, an ParseException
+ * will be thrown.
+ * See updated javadoc for more details.
+ * [5] See updated javadoc.
+ * [6] See updated javadoc.
+ * [7] This is a correct behavior if the DateFormat object is linient.
+ * Otherwise, an IllegalArgumentException will be thrown when formatting
+ * "January 35". See GregorianCalendar class javadoc for more details.
+ */
+ public void Test4099404()
+ {
+ try {
+ DecimalFormat fmt = new DecimalFormat("000.0#0");
+ errln("Bug 4099404 failed applying illegal pattern \"000.0#0\"");
+ } catch (Exception foo) {
+ logln("Bug 4099404 pattern \"000.0#0\" passed");
+ }
+ try {
+ DecimalFormat fmt = new DecimalFormat("0#0.000");
+ errln("Bug 4099404 failed applying illegal pattern \"0#0.000\"");
+ } catch (Exception foo) {
+ logln("Bug 4099404 pattern \"0#0.000\" passed");
+ }
+ }
+ /**
+ * DecimalFormat.applyPattern doesn't set minimum integer digits
+ */
+ public void Test4101481()
+ {
+ DecimalFormat sdf = new DecimalFormat("#,##0");
+ if (sdf.getMinimumIntegerDigits() != 1)
+ errln("Minimum integer digits : " + sdf.getMinimumIntegerDigits());
+ }
+ /**
+ * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition().
+ */
+ public void Test4052223()
+ {
+ try {
+ DecimalFormat fmt = new DecimalFormat("#,#00.00");
+ Number num = fmt.parse("abc3");
+ errln("Bug 4052223 failed : can't parse string \"a\". Got " + num);
+ } catch (ParseException foo) {
+ logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset());
+ }
+ }
+ /**
+ * API tests for API addition request A9.
+ */
+ public void Test4061302()
+ {
+ DecimalFormatSymbols fmt = DecimalFormatSymbols.getInstance();
+ String currency = fmt.getCurrencySymbol();
+ String intlCurrency = fmt.getInternationalCurrencySymbol();
+ char monDecSeparator = fmt.getMonetaryDecimalSeparator();
+ if (currency.equals("") ||
+ intlCurrency.equals("") ||
+ monDecSeparator == 0) {
+ errln("getCurrencySymbols failed, got empty string.");
+ }
+ logln("Before set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator);
+ fmt.setCurrencySymbol("XYZ");
+ fmt.setInternationalCurrencySymbol("ABC");
+ fmt.setMonetaryDecimalSeparator('*');
+ currency = fmt.getCurrencySymbol();
+ intlCurrency = fmt.getInternationalCurrencySymbol();
+ monDecSeparator = fmt.getMonetaryDecimalSeparator();
+ if (!currency.equals("XYZ") ||
+ !intlCurrency.equals("ABC") ||
+ monDecSeparator != '*') {
+ errln("setCurrencySymbols failed.");
+ }
+ logln("After set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator);
+ }
+ /**
+ * API tests for API addition request A23. FieldPosition.getBeginIndex and
+ * FieldPosition.getEndIndex.
+ */
+ public void Test4062486()
+ {
+ DecimalFormat fmt = new DecimalFormat("#,##0.00");
+ StringBuffer formatted = new StringBuffer();
+ FieldPosition field = new FieldPosition(0);
+ Double num = new Double(1234.5);
+ fmt.format(num, formatted, field);
+ if (field.getBeginIndex() != 0 && field.getEndIndex() != 5)
+ errln("Format 1234.5 failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex());
+ field.setBeginIndex(7);
+ field.setEndIndex(4);
+ if (field.getBeginIndex() != 7 && field.getEndIndex() != 4)
+ errln("Set begin/end field indexes failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex());
+ }
+
+ /**
+ * DecimalFormat.parse incorrectly works with a group separator.
+ */
+ public void Test4108738()
+ {
+
+ DecimalFormat df = new DecimalFormat("#,##0.###",
+ DecimalFormatSymbols.getInstance(java.util.Locale.US));
+ String text = "1.222,111";
+ Number num = df.parse(text,new ParsePosition(0));
+ if (!num.toString().equals("1.222"))
+ errln("\"" + text + "\" is parsed as " + num);
+ text = "1.222x111";
+ num = df.parse(text,new ParsePosition(0));
+ if (!num.toString().equals("1.222"))
+ errln("\"" + text + "\" is parsed as " + num);
+ }
+
+ /**
+ * DecimalFormat.format() incorrectly formats negative doubles.
+ */
+ public void Test4106658()
+ {
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ DecimalFormat df = new DecimalFormat(); // Corrected; see 4147706
+ double d1 = -0.0;
+ double d2 = -0.0001;
+ StringBuffer buffer = new StringBuffer();
+ logln("pattern: \"" + df.toPattern() + "\"");
+ df.format(d1, buffer, new FieldPosition(0));
+ if (!buffer.toString().equals("-0")) { // Corrected; see 4147706
+ errln(d1 + " is formatted as " + buffer);
+ }
+ buffer.setLength(0);
+ df.format(d2, buffer, new FieldPosition(0));
+ if (!buffer.toString().equals("-0")) { // Corrected; see 4147706
+ errln(d2 + " is formatted as " + buffer);
+ }
+ Locale.setDefault(savedLocale);
+ }
+
+ /**
+ * DecimalFormat.parse returns 0 if string parameter is incorrect.
+ */
+ public void Test4106662()
+ {
+ DecimalFormat df = new DecimalFormat();
+ String text = "x";
+ ParsePosition pos1 = new ParsePosition(0), pos2 = new ParsePosition(0);
+
+ logln("pattern: \"" + df.toPattern() + "\"");
+ Number num = df.parse(text, pos1);
+ if (num != null) {
+ errln("Test Failed: \"" + text + "\" is parsed as " + num);
+ }
+ df = null;
+ df = new DecimalFormat("$###.00");
+ num = df.parse("$", pos2);
+ if (num != null){
+ errln("Test Failed: \"$\" is parsed as " + num);
+ }
+ }
+
+ /**
+ * NumberFormat.parse doesn't return null
+ */
+ public void Test4114639()
+ {
+ NumberFormat format = NumberFormat.getInstance();
+ String text = "time 10:x";
+ ParsePosition pos = new ParsePosition(8);
+ Number result = format.parse(text, pos);
+ if (result != null) errln("Should return null but got : " + result); // Should be null; it isn't
+ }
+
+ /**
+ * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG.
+ */
+ public void Test4106664()
+ {
+ DecimalFormat df = new DecimalFormat();
+ long n = 1234567890123456L;
+ int m = 12345678;
+ BigInteger bigN = BigInteger.valueOf(n);
+ bigN = bigN.multiply(BigInteger.valueOf(m));
+ df.setMultiplier(m);
+ df.setGroupingUsed(false);
+ logln("formated: " +
+ df.format(n, new StringBuffer(), new FieldPosition(0)));
+ logln("expected: " + bigN.toString());
+ }
+ /**
+ * DecimalFormat.format incorrectly formats -0.0.
+ */
+ public void Test4106667()
+ {
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ DecimalFormat df = new DecimalFormat();
+ df.setPositivePrefix("+");
+ double d = -0.0;
+ logln("pattern: \"" + df.toPattern() + "\"");
+ StringBuffer buffer = new StringBuffer();
+ df.format(d, buffer, new FieldPosition(0));
+ if (!buffer.toString().equals("-0")) { // Corrected; see 4147706
+ errln(d + " is formatted as " + buffer);
+ }
+ Locale.setDefault(savedLocale);
+ }
+
+ /**
+ * DecimalFormat.setMaximumIntegerDigits() works incorrectly.
+ */
+ public void Test4110936()
+ {
+ NumberFormat nf = NumberFormat.getInstance();
+ nf.setMaximumIntegerDigits(128);
+ logln("setMaximumIntegerDigits(128)");
+ if (nf.getMaximumIntegerDigits() != 128)
+ errln("getMaximumIntegerDigits() returns " +
+ nf.getMaximumIntegerDigits());
+ }
+
+ /**
+ * Locale data should use generic currency symbol
+ *
+ * 1) Make sure that all currency formats use the generic currency symbol.
+ * 2) Make sure we get the same results using the generic symbol or a
+ * hard-coded one.
+ */
+ public void Test4122840()
+ {
+ Locale[] locales = NumberFormat.getAvailableLocales();
+
+ for (int i = 0; i < locales.length; i++) {
+ ResourceBundle rb = LocaleData.getBundle("sun.text.resources.FormatData",
+ locales[i]);
+ //
+ // Get the currency pattern for this locale. We have to fish it
+ // out of the ResourceBundle directly, since DecimalFormat.toPattern
+ // will return the localized symbol, not \00a4
+ //
+ String[] numPatterns = (String[])rb.getObject("NumberPatterns");
+ String pattern = numPatterns[1];
+
+ if (pattern.indexOf("\u00A4") == -1 ) {
+ errln("Currency format for " + locales[i] +
+ " does not contain generic currency symbol:" +
+ pattern );
+ }
+
+ // Create a DecimalFormat using the pattern we got and format a number
+ DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locales[i]);
+ DecimalFormat fmt1 = new DecimalFormat(pattern, symbols);
+
+ String result1 = fmt1.format(1.111);
+
+ //
+ // Now substitute in the locale's currency symbol and create another
+ // pattern. Replace the decimal separator with the monetary separator.
+ //
+ char decSep = symbols.getDecimalSeparator();
+ char monSep = symbols.getMonetaryDecimalSeparator();
+ StringBuffer buf = new StringBuffer(pattern);
+ for (int j = 0; j < buf.length(); j++) {
+ if (buf.charAt(j) == '\u00a4') {
+ String cur = "'" + symbols.getCurrencySymbol() + "'";
+ buf.replace(j, j+1, cur);
+ j += cur.length() - 1;
+ }
+ }
+ symbols.setDecimalSeparator(monSep);
+ DecimalFormat fmt2 = new DecimalFormat(buf.toString(), symbols);
+
+ String result2 = fmt2.format(1.111);
+
+ if (!result1.equals(result2)) {
+ errln("Results for " + locales[i] + " differ: " +
+ result1 + " vs " + result2);
+ }
+ }
+ }
+
+ /**
+ * DecimalFormat.format() delivers wrong string.
+ */
+ public void Test4125885()
+ {
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ double rate = 12.34;
+ DecimalFormat formatDec = new DecimalFormat ("000.00");
+ logln("toPattern: " + formatDec.toPattern());
+ String rateString= formatDec.format(rate);
+ if (!rateString.equals("012.34"))
+ errln("result : " + rateString + " expected : 012.34");
+ rate = 0.1234;
+ formatDec = null;
+ formatDec = new DecimalFormat ("+000.00%;-000.00%");
+ logln("toPattern: " + formatDec.toPattern());
+ rateString= formatDec.format(rate);
+ if (!rateString.equals("+012.34%"))
+ errln("result : " + rateString + " expected : +012.34%");
+ Locale.setDefault(savedLocale);
+ }
+
+ /**
+ **
+ * DecimalFormat produces extra zeros when formatting numbers.
+ */
+ public void Test4134034() {
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ DecimalFormat nf = new DecimalFormat("##,###,###.00");
+
+ String f = nf.format(9.02);
+ if (f.equals("9.02")) logln(f + " ok"); else errln("9.02 -> " + f + "; want 9.02");
+
+ f = nf.format(0);
+ if (f.equals(".00")) logln(f + " ok"); else errln("0 -> " + f + "; want .00");
+ Locale.setDefault(savedLocale);
+ }
+
+ /**
+ * CANNOT REPRODUCE - This bug could not be reproduced. It may be
+ * a duplicate of 4134034.
+ *
+ * JDK 1.1.6 Bug, did NOT occur in 1.1.5
+ * Possibly related to bug 4125885.
+ *
+ * This class demonstrates a regression in version 1.1.6
+ * of DecimalFormat class.
+ *
+ * 1.1.6 Results
+ * Value 1.2 Format #.00 Result '01.20' !!!wrong
+ * Value 1.2 Format 0.00 Result '001.20' !!!wrong
+ * Value 1.2 Format 00.00 Result '0001.20' !!!wrong
+ * Value 1.2 Format #0.0# Result '1.2'
+ * Value 1.2 Format #0.00 Result '001.20' !!!wrong
+ *
+ * 1.1.5 Results
+ * Value 1.2 Format #.00 Result '1.20'
+ * Value 1.2 Format 0.00 Result '1.20'
+ * Value 1.2 Format 00.00 Result '01.20'
+ * Value 1.2 Format #0.0# Result '1.2'
+ * Value 1.2 Format #0.00 Result '1.20'
+ */
+ public void Test4134300() {
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ String[] DATA = {
+ // Pattern Expected string
+ "#.00", "1.20",
+ "0.00", "1.20",
+ "00.00", "01.20",
+ "#0.0#", "1.2",
+ "#0.00", "1.20",
+ };
+ for (int i=0; i " + s);
+ s = f.format(-123.456);
+ if (!s.equals("-123.456"))
+ errln("Fail: Format empty pattern x -123.456 => " + s);
+ }
+ }
+
+ /**
+ * BigDecimal numbers get their fractions truncated by NumberFormat.
+ */
+ public void Test4141750() {
+ try {
+ String str = "12345.67";
+ BigDecimal bd = new BigDecimal(str);
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ String sd = nf.format(bd);
+ if (!sd.endsWith("67")) {
+ errln("Fail: " + str + " x format -> " + sd);
+ }
+ }
+ catch (Exception e) {
+ errln(e.toString());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * DecimalFormat toPattern() doesn't quote special characters or handle
+ * single quotes.
+ */
+ public void Test4145457() {
+ try {
+ DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance();
+ DecimalFormatSymbols sym = nf.getDecimalFormatSymbols();
+ sym.setDecimalSeparator('\'');
+ nf.setDecimalFormatSymbols(sym);
+ double pi = 3.14159;
+
+ String[] PATS = { "#.00 'num''ber'", "''#.00''" };
+
+ for (int i=0; i \"" + pat + '"');
+
+ if (val == val2 && out.equals(out2)) {
+ logln("Ok " + pi + " x \"" + PATS[i] + "\" -> \"" +
+ out + "\" -> " + val + " -> \"" +
+ out2 + "\" -> " + val2);
+ }
+ else {
+ errln("Fail " + pi + " x \"" + PATS[i] + "\" -> \"" +
+ out + "\" -> " + val + " -> \"" +
+ out2 + "\" -> " + val2);
+ }
+ }
+ }
+ catch (ParseException e) {
+ errln("Fail: " + e);
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * DecimalFormat.applyPattern() sets minimum integer digits incorrectly.
+ * CANNOT REPRODUCE
+ * This bug is a duplicate of 4139344, which is a duplicate of 4134300
+ */
+ public void Test4147295() {
+ DecimalFormat sdf = new DecimalFormat();
+ String pattern = "#,###";
+ logln("Applying pattern \"" + pattern + "\"");
+ sdf.applyPattern(pattern);
+ int minIntDig = sdf.getMinimumIntegerDigits();
+ if (minIntDig != 0) {
+ errln("Test failed");
+ errln(" Minimum integer digits : " + minIntDig);
+ errln(" new pattern: " + sdf.toPattern());
+ } else {
+ logln("Test passed");
+ logln(" Minimum integer digits : " + minIntDig);
+ }
+ }
+
+ /**
+ * DecimalFormat formats -0.0 as +0.0
+ * See also older related bug 4106658, 4106667
+ */
+ public void Test4147706() {
+ DecimalFormat df = new DecimalFormat("#,##0.0##");
+ df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));
+ double d1 = -0.0;
+ double d2 = -0.0001;
+ StringBuffer f1 = df.format(d1, new StringBuffer(), new FieldPosition(0));
+ StringBuffer f2 = df.format(d2, new StringBuffer(), new FieldPosition(0));
+ if (!f1.toString().equals("-0.0")) {
+ errln(d1 + " x \"" + df.toPattern() + "\" is formatted as \"" + f1 + '"');
+ }
+ if (!f2.toString().equals("-0.0")) {
+ errln(d2 + " x \"" + df.toPattern() + "\" is formatted as \"" + f2 + '"');
+ }
+ }
+
+ /**
+ * NumberFormat cannot format Double.MAX_VALUE
+ */
+ public void Test4162198() {
+ double dbl = Double.MAX_VALUE;
+ NumberFormat f = NumberFormat.getInstance();
+ f.setMaximumFractionDigits(Integer.MAX_VALUE);
+ f.setMaximumIntegerDigits(Integer.MAX_VALUE);
+ String s = f.format(dbl);
+ logln("The number " + dbl + " formatted to " + s);
+ Number n = null;
+ try {
+ n = f.parse(s);
+ } catch (java.text.ParseException e) {
+ errln("Caught a ParseException:");
+ e.printStackTrace();
+ }
+ logln("The string " + s + " parsed as " + n);
+ if (n.doubleValue() != dbl) {
+ errln("Round trip failure");
+ }
+ }
+
+ /**
+ * NumberFormat does not parse negative zero.
+ */
+ public void Test4162852() throws ParseException {
+ for (int i=0; i<2; ++i) {
+ NumberFormat f = (i == 0) ? NumberFormat.getInstance()
+ : NumberFormat.getPercentInstance();
+ double d = -0.0;
+ String s = f.format(d);
+ double e = f.parse(s).doubleValue();
+ logln("" +
+ d + " -> " +
+ '"' + s + '"' + " -> " +
+ e);
+ if (e != 0.0 || 1.0/e > 0.0) {
+ logln("Failed to parse negative zero");
+ }
+ }
+ }
+
+ /**
+ * NumberFormat truncates data
+ */
+ public void Test4167494() throws Exception {
+ NumberFormat fmt = NumberFormat.getInstance(Locale.US);
+
+ double a = Double.MAX_VALUE;
+ String s = fmt.format(a);
+ double b = fmt.parse(s).doubleValue();
+ boolean match = a == b;
+ if (match) {
+ logln("" + a + " -> \"" + s + "\" -> " + b + " ok");
+ } else {
+ errln("" + a + " -> \"" + s + "\" -> " + b + " FAIL");
+ }
+
+ // We don't test Double.MIN_VALUE because the locale data for the US
+ // currently doesn't specify enough digits to display Double.MIN_VALUE.
+ // This is correct for now; however, we leave this here as a reminder
+ // in case we want to address this later.
+ if (false) {
+ a = Double.MIN_VALUE;
+ s = fmt.format(a);
+ b = fmt.parse(s).doubleValue();
+ match = a == b;
+ if (match) {
+ logln("" + a + " -> \"" + s + "\" -> " + b + " ok");
+ } else {
+ errln("" + a + " -> \"" + s + "\" -> " + b + " FAIL");
+ }
+ }
+ }
+
+ /**
+ * DecimalFormat.parse() fails when ParseIntegerOnly set to true
+ */
+ public void Test4170798() {
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ DecimalFormat df = new DecimalFormat();
+ df.setParseIntegerOnly(true);
+ Number n = df.parse("-0.0", new ParsePosition(0));
+ if (!(n instanceof Long || n instanceof Integer)
+ || n.intValue() != 0) {
+ errln("FAIL: parse(\"-0.0\") returns " +
+ n + " (" + n.getClass().getName() + ')');
+ }
+ Locale.setDefault(savedLocale);
+ }
+
+ /**
+ * toPattern only puts the first grouping separator in.
+ */
+ public void Test4176114() {
+ String[] DATA = {
+ "00", "#00",
+ "000", "#000", // No grouping
+ "#000", "#000", // No grouping
+ "#,##0", "#,##0",
+ "#,000", "#,000",
+ "0,000", "#0,000",
+ "00,000", "#00,000",
+ "000,000", "#,000,000",
+ "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported
+ };
+ for (int i=0; i " + s + ", want " + DATA[i+1]);
+ }
+ }
+ }
+
+ /**
+ * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2
+ */
+ public void Test4179818() {
+ String DATA[] = {
+ // Input Pattern Expected output
+ "1.2511", "#.#", "1.3",
+ "1.2501", "#.#", "1.3",
+ "0.9999", "#", "1",
+ };
+ DecimalFormat fmt = new DecimalFormat("#",
+ DecimalFormatSymbols.getInstance(Locale.US));
+ for (int i=0; i " + fmt.format(-1) +
+ ", exp ^1");
+ }
+ if (!fmt.getNegativePrefix().equals("^")) {
+ errln("FAIL: (minus=^).getNegativePrefix -> " +
+ fmt.getNegativePrefix() + ", exp ^");
+ }
+ sym.setMinusSign('-');
+
+ fmt.applyPattern("#%");
+ sym.setPercent('^');
+ fmt.setDecimalFormatSymbols(sym);
+ if (!fmt.format(0.25).equals("25^")) {
+ errln("FAIL: 0.25 x (percent=^) -> " + fmt.format(0.25) +
+ ", exp 25^");
+ }
+ if (!fmt.getPositiveSuffix().equals("^")) {
+ errln("FAIL: (percent=^).getPositiveSuffix -> " +
+ fmt.getPositiveSuffix() + ", exp ^");
+ }
+ sym.setPercent('%');
+
+ fmt.applyPattern("#\u2030");
+ sym.setPerMill('^');
+ fmt.setDecimalFormatSymbols(sym);
+ if (!fmt.format(0.25).equals("250^")) {
+ errln("FAIL: 0.25 x (permill=^) -> " + fmt.format(0.25) +
+ ", exp 250^");
+ }
+ if (!fmt.getPositiveSuffix().equals("^")) {
+ errln("FAIL: (permill=^).getPositiveSuffix -> " +
+ fmt.getPositiveSuffix() + ", exp ^");
+ }
+ sym.setPerMill('\u2030');
+
+ fmt.applyPattern("\u00A4#.00");
+ sym.setCurrencySymbol("usd");
+ fmt.setDecimalFormatSymbols(sym);
+ if (!fmt.format(12.5).equals("usd12.50")) {
+ errln("FAIL: 12.5 x (currency=usd) -> " + fmt.format(12.5) +
+ ", exp usd12.50");
+ }
+ if (!fmt.getPositivePrefix().equals("usd")) {
+ errln("FAIL: (currency=usd).getPositivePrefix -> " +
+ fmt.getPositivePrefix() + ", exp usd");
+ }
+ sym.setCurrencySymbol("$");
+
+ fmt.applyPattern("\u00A4\u00A4#.00");
+ sym.setInternationalCurrencySymbol("DOL");
+ fmt.setDecimalFormatSymbols(sym);
+ if (!fmt.format(12.5).equals("DOL12.50")) {
+ errln("FAIL: 12.5 x (intlcurrency=DOL) -> " + fmt.format(12.5) +
+ ", exp DOL12.50");
+ }
+ if (!fmt.getPositivePrefix().equals("DOL")) {
+ errln("FAIL: (intlcurrency=DOL).getPositivePrefix -> " +
+ fmt.getPositivePrefix() + ", exp DOL");
+ }
+ sym.setInternationalCurrencySymbol("USD");
+
+ // Since the pattern logic has changed, make sure that patterns round
+ // trip properly. Test stream in/out integrity too.
+ Locale[] avail = NumberFormat.getAvailableLocales();
+ for (int i=0; i \"" + pat +
+ "\" -> \"" + f2.toPattern() + '"');
+ }
+
+ // Test toLocalizedPattern/applyLocalizedPattern round trip
+ pat = df.toLocalizedPattern();
+ f2.applyLocalizedPattern(pat);
+ if (!df.equals(f2)) {
+ errln("FAIL: " + avail[i] + " -> localized \"" + pat +
+ "\" -> \"" + f2.toPattern() + '"');
+ }
+
+ // Test writeObject/readObject round trip
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(df);
+ oos.flush();
+ baos.close();
+ byte[] bytes = baos.toByteArray();
+ ObjectInputStream ois =
+ new ObjectInputStream(new ByteArrayInputStream(bytes));
+ f2 = (DecimalFormat) ois.readObject();
+ if (!df.equals(f2)) {
+ errln("FAIL: Stream in/out " + avail[i] + " -> \"" + pat +
+ "\" -> " +
+ (f2 != null ? ("\""+f2.toPattern()+'"') : "null"));
+ }
+
+ }
+ }
+ }
+
+ /**
+ * DecimalFormat.parse() fails for mulipliers 2^n.
+ */
+ public void Test4216742() throws ParseException {
+ DecimalFormat fmt = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+ long[] DATA = { Long.MIN_VALUE, Long.MAX_VALUE, -100000000L, 100000000L};
+ for (int i=0; i 0 != DATA[i] > 0) {
+ errln("\"" + str + "\" parse(x " + fmt.getMultiplier() +
+ ") => " + n);
+ }
+ }
+ }
+ }
+
+ /**
+ * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction
+ * digits.
+ */
+ public void Test4217661() {
+ Object[] DATA = {
+ new Double(0.001), "0",
+ new Double(1.001), "1",
+ new Double(0.006), "0.01",
+ new Double(1.006), "1.01",
+ };
+ NumberFormat fmt = NumberFormat.getInstance(Locale.US);
+ fmt.setMaximumFractionDigits(2);
+ for (int i=0; i 0 && args[0].equals("-debug")) {
+ DEBUG = true;
+ String[] newargs = new String[args.length - 1];
+ System.arraycopy(args, 1, newargs, 0, newargs.length);
+ args = newargs;
+ }
+ new NumberRoundTrip().run(args);
+ }
+
+ public void TestNumberFormatRoundTrip() {
+ logln("Default Locale");
+ localeName = "Default Locale";
+ formatName = "getInstance";
+ doTest(NumberFormat.getInstance());
+ formatName = "getNumberInstance";
+ doTest(NumberFormat.getNumberInstance());
+ formatName = "getCurrencyInstance";
+ doTest(NumberFormat.getCurrencyInstance());
+ formatName = "getPercentInstance";
+ doTest(NumberFormat.getPercentInstance());
+
+ Locale[] loc = NumberFormat.getAvailableLocales();
+ for (int i=0; i " + escape(s));
+ n = fmt.parse(s);
+ if (DEBUG) logln(" " + escape(s) + " P> " + n);
+ s2 = fmt.format(n);
+ if (DEBUG) logln(" " + n + " F> " + escape(s2));
+
+ if (STRING_COMPARE) {
+ if (!s.equals(s2)) {
+ if (fmt instanceof DecimalFormat) {
+ logln("Text mismatch: expected: " + s + ", got: " + s2 + " --- Try BigDecimal parsing.");
+ ((DecimalFormat)fmt).setParseBigDecimal(true);
+ n = fmt.parse(s);
+ if (DEBUG) logln(" " + escape(s) + " P> " + n);
+ s2 = fmt.format(n);
+ if (DEBUG) logln(" " + n + " F> " + escape(s2));
+ ((DecimalFormat)fmt).setParseBigDecimal(false);
+
+ if (!s.equals(s2)) {
+ err = "STRING ERROR(DecimalFormat): ";
+ }
+ } else {
+ err = "STRING ERROR(NumberFormat): ";
+ }
+ }
+ }
+
+ if (EXACT_NUMERIC_COMPARE) {
+ if (value.doubleValue() != n.doubleValue()) {
+ err += "NUMERIC ERROR: ";
+ }
+ } else {
+ // Compute proportional error
+ double error = proportionalError(value, n);
+
+ if (error > MAX_ERROR) {
+ err += "NUMERIC ERROR " + error + ": ";
+ }
+
+ if (error > max_numeric_error) max_numeric_error = error;
+ if (error < min_numeric_error) min_numeric_error = error;
+ }
+
+ String message = value + typeOf(value) + " F> " +
+ escape(s) + " P> " +
+ n + typeOf(n) + " F> " +
+ escape(s2);
+ if (err.length() > 0) {
+ errln("*** " + err + " with " +
+ formatName + " in " + localeName +
+ " " + message);
+ } else {
+ logln(message);
+ }
+ } catch (ParseException e) {
+ errln("*** " + e.toString() + " with " +
+ formatName + " in " + localeName);
+ }
+ }
+
+ static String typeOf(Number n) {
+ if (n instanceof Long) return " Long";
+ if (n instanceof Double) return " Double";
+ return " Number";
+ }
+
+ static String escape(String s) {
+ StringBuffer buf = new StringBuffer();
+ for (int i=0; i> 12));
+ buf.append(Integer.toHexString((c & 0x0F00) >> 8));
+ buf.append(Integer.toHexString((c & 0x00F0) >> 4));
+ buf.append(Integer.toHexString(c & 0x000F));
+ }
+ }
+ return buf.toString();
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/NumberTest.java b/jdk/test/java/text/Format/NumberFormat/NumberTest.java
new file mode 100644
index 00000000000..ca519bb6dab
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/NumberTest.java
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 1997, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4122840 4135202 4408066 4838107 8008577
+ * @summary test NumberFormat
+ * @library /java/text/testlib
+ * @modules java.base/sun.util.resources
+ * @compile -XDignore.symbol.file NumberTest.java
+ * @run main/othervm -Djava.locale.providers=COMPAT,SPI NumberTest
+ */
+
+import java.util.*;
+import java.text.*;
+import sun.util.resources.LocaleData;
+
+public class NumberTest extends IntlTest
+{
+ public static void main(String[] args) throws Exception {
+ new NumberTest().run(args);
+ }
+
+ // Test pattern handling
+ public void TestPatterns()
+ {
+ DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US);
+ String pat[] = { "#.#", "#.", ".#", "#" };
+ String newpat[] = { "#0.#", "#0.", "#.0", "#" };
+ String num[] = { "0", "0.", ".0", "0" };
+ for (int i=0; i \"" +
+ fmt.toPattern() + '"');
+
+ for (int v=0; v " + escape(s));
+ if (!s.equals(valFormat[v+ival])) {
+ errln("FAIL: Expected " + valFormat[v+ival] +
+ ", got " + s +
+ ", pattern=" + fmt.toPattern());
+ }
+
+ ParsePosition pos = new ParsePosition(0);
+ Number a = fmt.parse(s, pos);
+ if (pos.getIndex() == s.length()) {
+ logln(" Parse -> " + a);
+ if (a.doubleValue() != valParse[v+ival]) {
+ errln("FAIL: Expected " + valParse[v+ival] +
+ ", got " + a.doubleValue() +
+ ", pattern=" + fmt.toPattern());
+ }
+ } else {
+ errln(" FAIL: Partial parse (" + pos.getIndex() +
+ " chars) -> " + a);
+ }
+ }
+ for (int v=0; v " + escape(s));
+ if (!s.equals(lvalFormat[v+ilval])) {
+ errln("ERROR: Expected " + lvalFormat[v+ilval] +
+ ", got " + s +
+ ", pattern=" + fmt.toPattern());
+ }
+
+ ParsePosition pos = new ParsePosition(0);
+ Number a = fmt.parse(s, pos);
+ if (pos.getIndex() == s.length()) {
+ logln(" Parse -> " + a);
+ if (a.longValue() != lvalParse[v+ilval]) {
+ errln("FAIL: Expected " + lvalParse[v+ilval] +
+ ", got " + a +
+ ", pattern=" + fmt.toPattern());
+ }
+ } else {
+ errln(" FAIL: Partial parse (" + pos.getIndex() +
+ " chars) -> " + a);
+ }
+ }
+ ival += val.length;
+ ilval += lval.length;
+ }
+ }
+
+ // Test the handling of quotes
+ public void TestQuotes()
+ {
+ String pat;
+ DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US);
+ DecimalFormat fmt = new DecimalFormat(pat = "a'fo''o'b#", sym);
+ String s = fmt.format(123);
+ logln("Pattern \"" + pat + "\"");
+ logln(" Format 123 -> " + escape(s));
+ if (!s.equals("afo'ob123")) errln("FAIL: Expected afo'ob123");
+
+ fmt = new DecimalFormat(pat = "a''b#", sym);
+ s = fmt.format(123);
+ logln("Pattern \"" + pat + "\"");
+ logln(" Format 123 -> " + escape(s));
+ if (!s.equals("a'b123")) errln("FAIL: Expected a'b123");
+ }
+
+ // Test the use of the currency sign
+ public void TestCurrencySign()
+ {
+ DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US);
+ DecimalFormat fmt = new DecimalFormat("\u00A4#,##0.00;-\u00A4#,##0.00", sym);
+ // Can't test this properly until currency API goes public
+ // DecimalFormatSymbols sym = fmt.getDecimalFormatSymbols();
+
+ String s = fmt.format(1234.56);
+ logln("Pattern \"" + fmt.toPattern() + "\"");
+ logln(" Format " + 1234.56 + " -> " + escape(s));
+ if (!s.equals("$1,234.56")) errln("FAIL: Expected $1,234.56");
+ s = fmt.format(-1234.56);
+ logln(" Format " + -1234.56 + " -> " + escape(s));
+ if (!s.equals("-$1,234.56")) errln("FAIL: Expected -$1,234.56");
+
+ fmt = new DecimalFormat("\u00A4\u00A4 #,##0.00;\u00A4\u00A4 -#,##0.00", sym);
+ s = fmt.format(1234.56);
+ logln("Pattern \"" + fmt.toPattern() + "\"");
+ logln(" Format " + 1234.56 + " -> " + escape(s));
+ if (!s.equals("USD 1,234.56")) errln("FAIL: Expected USD 1,234.56");
+ s = fmt.format(-1234.56);
+ logln(" Format " + -1234.56 + " -> " + escape(s));
+ if (!s.equals("USD -1,234.56")) errln("FAIL: Expected USD -1,234.56");
+ }
+ static String escape(String s)
+ {
+ StringBuffer buf = new StringBuffer();
+ char HEX[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
+ for (int i=0; i> 12]);
+ buf.append(HEX[(c & 0x0F00) >> 8]);
+ buf.append(HEX[(c & 0x00F0) >> 4]);
+ buf.append(HEX[c & 0x000F]);
+ }
+ }
+ return buf.toString();
+ }
+
+ // Test simple currency format
+ // Bug 4024941; this code used to throw a NumberFormat exception
+ public void TestCurrency() {
+ NumberFormat currencyFmt =
+ NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH);
+ String s = currencyFmt.format(1.50);
+ logln("Un pauvre ici a..........." + s);
+ if (!s.equals("1,50 $")) {
+ errln("FAIL: Expected 1,50 $; got " + s + "; "+ dumpFmt(currencyFmt));
+ }
+ currencyFmt = NumberFormat.getCurrencyInstance(Locale.GERMANY);
+ s = currencyFmt.format(1.50);
+ logln("Un pauvre en Allemagne a.." + s);
+ if (!s.equals("1,50 \u20AC")) {
+ errln("FAIL: Expected 1,50 \u20AC; got " + s + "; " + dumpFmt(currencyFmt));
+ }
+ currencyFmt = NumberFormat.getCurrencyInstance(Locale.FRANCE);
+ s = currencyFmt.format(1.50);
+ logln("Un pauvre en France a....." + s);
+ if (!s.equals("1,50 \u20AC")) {
+ errln("FAIL: Expected 1,50 \u20AC; got " + s + "; " + dumpFmt(currencyFmt));
+ }
+ }
+
+ String dumpFmt(NumberFormat numfmt) {
+ DecimalFormat fmt = (DecimalFormat)numfmt;
+ StringBuffer buf = new StringBuffer();
+ buf.append("pattern \"");
+ buf.append(fmt.toPattern());
+ buf.append("\", currency \"");
+ buf.append(fmt.getDecimalFormatSymbols().getCurrencySymbol());
+ buf.append("\"");
+ return buf.toString();
+ }
+
+ // Test numeric parsing
+ // Bug 4059870
+ public void TestParse()
+ {
+ String arg = "0";
+ java.text.DecimalFormat format = new java.text.DecimalFormat("00");
+ try {
+ Number n = format.parse(arg);
+ logln("parse(" + arg + ") = " + n);
+ if (n.doubleValue() != 0.0) errln("FAIL: Expected 0");
+ } catch (Exception e) { errln("Exception caught: " + e); }
+ }
+
+ // Test rounding
+ public void TestRounding487() {
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ roundingTest(nf, 0.00159999, 4, "0.0016");
+ roundingTest(nf, 0.00995, 4, "0.01");
+ roundingTest(nf, 12.7995, 3, "12.8");
+ roundingTest(nf, 12.4999, 0, "12");
+ roundingTest(nf, -19.5, 0, "-20");
+ }
+
+ void roundingTest(NumberFormat nf, double x, int maxFractionDigits, String expected) {
+ nf.setMaximumFractionDigits(maxFractionDigits);
+ String out = nf.format(x);
+ logln("" + x + " formats with " + maxFractionDigits + " fractional digits to " + out);
+ if (!out.equals(expected)) {
+ errln("FAIL: Expected " + expected + ", got " + out);
+ }
+ }
+
+ /**
+ * Bug 4135202
+ * DecimalFormat should recognize not only Latin digits 0-9 (\u0030-\u0039)
+ * but also various other ranges of Unicode digits, such as Arabic
+ * digits \u0660-\u0669 and Devanagari digits \u0966-\u096F, to name
+ * a couple.
+ * @see java.lang.Character#isDigit(char)
+ */
+ public void TestUnicodeDigits() {
+ char[] zeros = {
+ 0x0030, // ISO-LATIN-1 digits ('0' through '9')
+ 0x0660, // Arabic-Indic digits
+ 0x06F0, // Extended Arabic-Indic digits
+ 0x0966, // Devanagari digits
+ 0x09E6, // Bengali digits
+ 0x0A66, // Gurmukhi digits
+ 0x0AE6, // Gujarati digits
+ 0x0B66, // Oriya digits
+ 0x0BE6, // Tamil digits
+ 0x0C66, // Telugu digits
+ 0x0CE6, // Kannada digits
+ 0x0D66, // Malayalam digits
+ 0x0E50, // Thai digits
+ 0x0ED0, // Lao digits
+ 0x0F20, // Tibetan digits
+ 0xFF10, // Fullwidth digits
+ };
+ NumberFormat format = NumberFormat.getInstance();
+ for (int i=0; i= 0) {
+ if (customNeg.indexOf(INTL_SYM) >= 0)
+ errln("Fail: Positive and negative patterns use different symbols");
+ else
+ logln("Ok: " + locales[i] +
+ " uses currency symbol: " + genericPos +
+ ", " + customPos);
+ }
+ else if (customPos.indexOf(INTL_SYM) >= 0) {
+ if (customNeg.indexOf(SYM) >= 0)
+ errln("Fail: Positive and negative patterns use different symbols");
+ else
+ logln("Ok: " + locales[i] +
+ " uses intl. currency symbol: " + genericPos +
+ ", " + customPos);
+ }
+ else {
+ errln("FAIL: " + locales[i] +
+ " contains no currency symbol (impossible!)");
+ }
+ }
+ }
+ else logln("Skipping " + locales[i] + "; not a DecimalFormat");
+ }
+ }
+
+ public void TestIntegerFormat() throws ParseException {
+ NumberFormat format = NumberFormat.getIntegerInstance(Locale.GERMANY);
+
+ float[] formatInput = { 12345.67f, -12345.67f, -0, 0 };
+ String[] formatExpected = { "12.346", "-12.346", "0", "0" };
+
+ for (int i = 0; i < formatInput.length; i++) {
+ String result = format.format(formatInput[i]);
+ if (!result.equals(formatExpected[i])) {
+ errln("FAIL: Expected " + formatExpected[i] + ", got " + result);
+ }
+ }
+
+ String[] parseInput = { "0", "-0", "12.345,67", "-12.345,67" };
+ float[] parseExpected = { 0, 0, 12345, -12345 };
+
+ for (int i = 0; i < parseInput.length; i++) {
+ float result = ((Number) format.parse(parseInput[i])).floatValue();
+ if (result != parseExpected[i]) {
+ errln("FAIL: Expected " + parseExpected[i] + ", got " + result);
+ }
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/NumberFormat/PositionTest.java b/jdk/test/java/text/Format/NumberFormat/PositionTest.java
new file mode 100644
index 00000000000..31a5a3dbebd
--- /dev/null
+++ b/jdk/test/java/text/Format/NumberFormat/PositionTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 1997, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4109023 4153060 4153061
+ * @library /java/text/testlib
+ * @summary test ParsePosition and FieldPosition
+ */
+/*
+(C) Copyright Taligent, Inc. 1996 - All Rights Reserved
+(C) Copyright IBM Corp. 1996 - All Rights Reserved
+
+ The original version of this source code and documentation is copyrighted and
+owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
+provided under terms of a License Agreement between Taligent and Sun. This
+technology is protected by multiple US and International patents. This notice and
+attribution to Taligent may not be removed.
+ Taligent is a registered trademark of Taligent, Inc.
+*/
+
+import java.text.*;
+import java.io.*;
+
+public class PositionTest extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new PositionTest().run(args);
+ }
+
+ public void TestParsePosition() {
+ ParsePosition pp1 = new ParsePosition(0);
+ if (pp1.getIndex() == 0) {
+ logln("PP constructor() tested.");
+ }else{
+ errln("*** PP getIndex or constructor() result");
+ }
+
+ {
+ int to = 5;
+ ParsePosition pp2 = new ParsePosition ( to );
+ if (pp2.getIndex() == 5) {
+ logln("PP getIndex and constructor(TextOffset) tested.");
+ }else{
+ errln("*** PP getIndex or constructor(TextOffset) result");
+ }
+ pp2.setIndex( 3 );
+ if (pp2.getIndex() == 3) {
+ logln("PP setIndex tested.");
+ }else{
+ errln("*** PP getIndex or setIndex result");
+ }
+ }
+
+ ParsePosition pp2, pp3;
+ pp2 = new ParsePosition( 3 );
+ pp3 = new ParsePosition( 5 );
+ ParsePosition pp4 = new ParsePosition(5);
+ if (! pp2.equals(pp3)) {
+ logln("PP not equals tested.");
+ }else{
+ errln("*** PP not equals fails");
+ }
+ if (pp3.equals(pp4)) {
+ logln("PP equals tested.");
+ }else{
+ errln("*** PP equals fails (" + pp3.getIndex() + " != " + pp4.getIndex() + ")");
+ }
+
+ ParsePosition pp5;
+ pp5 = pp4;
+ if (pp4.equals(pp5)) {
+ logln("PP operator= tested.");
+ }else{
+ errln("*** PP operator= operator== or operator != result");
+ }
+
+ }
+
+ public void TestFieldPosition() {
+ FieldPosition fp = new FieldPosition( 7 );
+
+ if (fp.getField() == 7) {
+ logln("FP constructor(int) and getField tested.");
+ }else{
+ errln("*** FP constructor(int) or getField");
+ }
+
+ FieldPosition fph = new FieldPosition( 3 );
+ if ( fph.getField() != 3) errln("*** FP getField or heap constr.");
+
+ boolean err1 = false;
+ boolean err2 = false;
+ boolean err3 = false;
+// for (long i = -50; i < 50; i++ ) {
+// fp.setField( i+8 );
+// fp.setBeginIndex( i+6 );
+// fp.setEndIndex( i+7 );
+// if (fp.getField() != i+8) err1 = true;
+// if (fp.getBeginIndex() != i+6) err2 = true;
+// if (fp.getEndIndex() != i+7) err3 = true;
+// }
+ if (!err1) {
+ logln("FP setField and getField tested.");
+ }else{
+ errln("*** FP setField or getField");
+ }
+ if (!err2) {
+ logln("FP setBeginIndex and getBeginIndex tested.");
+ }else{
+ errln("*** FP setBeginIndex or getBeginIndex");
+ }
+ if (!err3) {
+ logln("FP setEndIndex and getEndIndex tested.");
+ }else{
+ errln("*** FP setEndIndex or getEndIndex");
+ }
+
+ logln("");
+ }
+
+ public void TestFieldPosition_example() {
+ //***** no error detection yet !!!!!!!
+ //***** this test is for compiler checks and visual verification only.
+ double doubleNum[] = { 123456789.0, -12345678.9, 1234567.89, -123456.789,
+ 12345.6789, -1234.56789, 123.456789, -12.3456789, 1.23456789};
+ int dNumSize = doubleNum.length;
+
+ DecimalFormat fmt = (DecimalFormat) NumberFormat.getInstance();
+ fmt.setDecimalSeparatorAlwaysShown(true);
+
+ final int tempLen = 20;
+ StringBuffer temp;
+
+ for (int i=0; iformat(doubleNum[i], buf, pos), fmtText);
+ StringBuffer res = fmt.format(doubleNum[i], buf, pos);
+ int tempOffset = (tempLen <= (tempLen - pos.getEndIndex())) ?
+ tempLen : (tempLen - pos.getEndIndex());
+ for (int j=0; j succeeded.");
+ }
+}
diff --git a/jdk/test/java/text/Format/common/Bug6215962.java b/jdk/test/java/text/Format/common/Bug6215962.java
new file mode 100644
index 00000000000..85dd5e2cebd
--- /dev/null
+++ b/jdk/test/java/text/Format/common/Bug6215962.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6215962
+ * @summary Confirm that replacing Utility.arayEquals methods have with
+ * Arrays.equals introduces no problem.
+ */
+import java.text.*;
+import java.util.*;
+
+public class Bug6215962 {
+
+ public static void main(String[] args) {
+ testMessageFormat();
+ testChoiceFormat();
+ testDateFormatSymbols();
+ }
+
+ /**
+ * Test cases for MessageFormat
+ */
+ static void testMessageFormat() {
+ MessageFormat mf1 = new MessageFormat("{0}", null);
+ MessageFormat mf2 = new MessageFormat("{0}", null);
+ check(mf1, mf2, true);
+
+ mf1.setLocale(null);
+ check(mf1, mf2, true);
+
+ mf1 = new MessageFormat("{0}", Locale.US);
+ check(mf1, mf2, false);
+
+ mf2 = new MessageFormat("{0}", Locale.JAPAN);
+ check(mf1, mf2, false);
+
+ mf1 = new MessageFormat("{0}", new Locale("ja", "JP"));
+ check(mf1, mf2, true);
+
+ mf1.setLocale(null);
+ check(mf1, mf2, false);
+
+ mf1 = new MessageFormat("{0}", new Locale("ja", "JP", "FOO"));
+ check(mf1, mf2, false);
+
+ mf2 = new MessageFormat("{1}", new Locale("ja", "JP", "FOO"));
+ check(mf1, mf2, false);
+
+ mf1 = new MessageFormat("{1}", new Locale("ja", "JP", "FOO"));
+ check(mf1, mf2, true);
+
+ mf1 = new MessageFormat("{1, date}", new Locale("ja", "JP", "FOO"));
+ check(mf1, mf2, false);
+
+ mf2 = new MessageFormat("{1, date}", new Locale("ja", "JP", "FOO"));
+ check(mf1, mf2, true);
+ }
+
+ static void check(MessageFormat f1, MessageFormat f2, boolean expected) {
+ boolean got = f1.equals(f2);
+ if (got != expected) {
+ throw new RuntimeException("Test failed for MessageFormat.equals(). Got: " + got + ", Expected: " + expected);
+ }
+ }
+
+ /**
+ * Test cases for MessageFormat
+ */
+ static void testChoiceFormat() {
+ double[] limits0 = {0,1,2,3,4,5,6};
+ double[] limits1 = {1,2,3,4,5,6,7};
+ String[] monthNames0 = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
+ String[] monthNames1 = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"};
+
+ ChoiceFormat cf1 = new ChoiceFormat(limits1, monthNames0);
+ ChoiceFormat cf2 = new ChoiceFormat(limits1, monthNames0);
+ check(cf1, cf2, true);
+
+ cf2 = new ChoiceFormat(limits0, monthNames0);
+ check(cf1, cf2, false);
+
+ cf2 = new ChoiceFormat(limits1, monthNames1);
+ check(cf1, cf2, false);
+ }
+
+ static void check(ChoiceFormat f1, ChoiceFormat f2, boolean expected) {
+ boolean got = f1.equals(f2);
+ if (got != expected) {
+ throw new RuntimeException("Test failed for ChoiceFormat.equals(). Got: " + got + ", Expected: " + expected);
+ }
+ }
+
+ /**
+ * Test cases for DateFormatSymbols
+ */
+ static void testDateFormatSymbols() {
+ DateFormatSymbols dfs1 = new DateFormatSymbols();
+ DateFormatSymbols dfs2 = new DateFormatSymbols();
+ check(dfs1, dfs2, true);
+
+ // Becase eras, months, shortmonths, weekdays, shortweekdays, ampms are
+ // the same data type (String[]) and are treated in the same way, here
+ // I test only Months.
+ String[] tmp = dfs1.getMonths();
+ String saved = tmp[0];
+ tmp[0] = "Foo";
+ dfs1.setMonths(tmp);
+ check(dfs1, dfs2, false);
+
+ tmp[0] = saved;
+ dfs1.setMonths(tmp);
+ check(dfs1, dfs2, true);
+
+ // Test LocalizedpatternChars (String)
+ String pattern = dfs2.getLocalPatternChars();
+ dfs2.setLocalPatternChars("Bar");
+ check(dfs1, dfs2, false);
+
+ dfs2.setLocalPatternChars(pattern);
+ check(dfs1, dfs2, true);
+
+ // Test TimeZone strings (String[][])
+ String[][] zones = dfs1.getZoneStrings();
+ saved = zones[0][1];
+ zones[0][1] = "Yokohama Summer Time";
+ dfs1.setZoneStrings(zones);
+ check(dfs1, dfs2, false);
+
+ zones[0][1] = saved;
+ dfs1.setZoneStrings(zones);
+ check(dfs1, dfs2, true);
+ }
+
+ static void check(DateFormatSymbols dfs1, DateFormatSymbols dfs2, boolean expected) {
+ boolean got = dfs1.equals(dfs2);
+ if (got != expected) {
+ throw new RuntimeException("Test failed for DateFormatSymbols.equals(). Got: " + got + ", Expected: " + expected);
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/common/ChoiceFormat.ser.txt b/jdk/test/java/text/Format/common/ChoiceFormat.ser.txt
new file mode 100644
index 00000000000..4947d1936e7
--- /dev/null
+++ b/jdk/test/java/text/Format/common/ChoiceFormat.ser.txt
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2003, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Hex dump of a serialized ChoiceFormat for Bug4769840.
+
+aced0005737200166a6176612e746578742e43686f696365466f726d617418e9
+c6bee365b6040200025b000d63686f696365466f726d6174737400135b4c6a61
+76612f6c616e672f537472696e673b5b000c63686f6963654c696d6974737400
+025b44787200166a6176612e746578742e4e756d626572466f726d6174dff6b3
+bf137d07e80200065a000c67726f7570696e67557365644200116d6178467261
+6374696f6e4469676974734200106d6178496e74656765724469676974734200
+116d696e4672616374696f6e4469676974734200106d696e496e746567657244
+69676974735a00107061727365496e74656765724f6e6c79787200106a617661
+2e746578742e466f726d6174fbd8bc12e90f1843020000787001032800010075
+7200135b4c6a6176612e6c616e672e537472696e673badd256e7e91d7b470200
+0078700000000274000420666f6f74000420626172757200025b443ea68c14ab
+635a1e02000078700000000200000000000000003ff0000000000000
diff --git a/jdk/test/java/text/Format/common/DateFormat.Field.ser.txt b/jdk/test/java/text/Format/common/DateFormat.Field.ser.txt
new file mode 100644
index 00000000000..e78f24409e7
--- /dev/null
+++ b/jdk/test/java/text/Format/common/DateFormat.Field.ser.txt
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2003, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Hex dump of a serialized DateFormat.Field for Bug4769840.
+
+aced00057372001a6a6176612e746578742e44617465466f726d617424466965
+6c646744fc81f123e71002000149000d63616c656e6461724669656c64787200
+166a6176612e746578742e466f726d6174244669656c6403d7fbbd383b0f9b02
+00007872002f6a6176612e746578742e41747472696275746564436861726163
+7465724974657261746f7224417474726962757465811e7426cd47175c020001
+4c00046e616d657400124c6a6176612f6c616e672f537472696e673b78707400
+0974696d65207a6f6e65ffffffff
diff --git a/jdk/test/java/text/Format/common/FormatIteratorTest.java b/jdk/test/java/text/Format/common/FormatIteratorTest.java
new file mode 100644
index 00000000000..7102f59dec2
--- /dev/null
+++ b/jdk/test/java/text/Format/common/FormatIteratorTest.java
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 2000, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4018937
+ * @library /java/text/testlib
+ * @build FormatIteratorTest PParser IntlTest
+ * @run main FormatIteratorTest
+ * @summary Tests the formatToCharacterIterator method of SimpleDateFormat,
+ * MessageFormat and DecimalFormat.
+ */
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.text.*;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * FormatTester creates Formats, and tests the resulting FieldPositions
+ * and AttributedCharacterIterator based on a file. The file is a hierarchical
+ * set of key/value pairs, where each value can also be an array or map. The
+ * top map must contain a tests entry, which will be an array consisting
+ * of pairs of maps. The first map specifies the Format that
+ * should be created, and consists of:
+ *
+ * class = className
+ * args = (arg1 arg2 ...)
+ * valueClass = className
+ * valueArgs = (arg1 arg2 ...)
+ *
+ * The second map dictates what to test, and should consist of the following:
+ *
+ * length = lengthOfFormattedString
+ * text = Result of Formatting
+ * 0...lengthOfFormattedString = (arg1 arg2 ...)
+ * limits = ( range1 range2 ...)
+ * fieldPositions = ( fp1 fp2 ...)
+ *
+ * lengthOfFormattedString
indicate the total length of formatted
+ * string. text
indicates the resulting string.
+ * 0...x
where x == lengthOfFormattedString - 1
is
+ * an array of the attributes that should exist at the particular
+ * location. limits
is an array of maps, where each map
+ * can be used to test the bounds of a set of attributes. Each map will
+ * consist of:
+ *
+ * attributes = array of attributes
+ * begin = start location
+ * begin2 = second start location
+ * end = limit location
+ * end2 = second limit location
+ *
+ * These are tested by iterating from begin to end in the CharacterIterator
+ * and doing the following at each index:
+ *
+ * getRunStart() == begin
+ * getRunStart(attributes) == begin2
+ * getRunLimit() == end
+ * getRunLimit(attributes) == end2
+ *
+ * fieldPositions
is used to test the results of invoking
+ * format
with a FieldPosition
.
+ * fieldPositions
is an array of maps, where each map contains
+ * the following:
+ *
+ * field = Integer field reference (optional)
+ * fieldID = Object reference
+ * begin = begin index of FieldPosition after formatting
+ * end = end index of FieldPosition after formatting
+ *
+ * Any lines starting with {@code '#'} are comment lines and ignored.
+ */
+public class FormatIteratorTest extends IntlTest {
+ private static HashMap attrs;
+ private Format format;
+ private Object value;
+ private String text;
+
+ public static final Object ARG0_FIELD_ID = MessageFormat.
+ Field.ARGUMENT;
+ public static final Object ARG1_FIELD_ID = MessageFormat.
+ Field.ARGUMENT;
+ public static final Object ARG2_FIELD_ID = MessageFormat.
+ Field.ARGUMENT;
+ public static final Object ARG3_FIELD_ID = MessageFormat.
+ Field.ARGUMENT;
+
+ public static void main(String[] args) throws Exception {
+ Locale reservedLocale = Locale.getDefault();
+ TimeZone reservedTimeZone = TimeZone.getDefault();
+ try {
+ // The current tests are only appropriate for US. If tests are
+ // added for other locales are added, then a property should be
+ // added to each file (test) to be able to specify the locale.
+ Locale.setDefault(Locale.US);
+ TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
+ new FormatIteratorTest().run(args);
+ } finally {
+ // restore the reserved locale and time zone
+ Locale.setDefault(reservedLocale);
+ TimeZone.setDefault(reservedTimeZone);
+ }
+ }
+
+ public FormatIteratorTest() {
+ }
+
+ public void testDecimalFormat() {
+ _test(new File(System.getProperty("test.src", "."),
+ "decimalFormat.props"));
+ }
+
+ public void testMessageFormat() {
+ _test(new File(System.getProperty("test.src", "."),
+ "messageFormat.props"));
+ }
+
+ public void testDateFormat() {
+ _test(new File(System.getProperty("test.src", "."),
+ "dateFormat.props"));
+ }
+
+ private void _test(File file) {
+ try {
+ attrs = new HashMap();
+ logln("testing: " + file);
+ PParser parser = new PParser();
+ Hashtable contents = parser.parse(new BufferedReader(
+ new FileReader(file)));
+ Vector test = (Vector)contents.get("tests");
+
+ for (int counter = 0; counter < test.size(); counter++) {
+ logln("creating: " + (counter / 2));
+
+ AttributedCharacterIterator iterator =
+ create((Hashtable)test.get(counter));
+
+ logln("verifying: " + (counter / 2));
+ verify(iterator, (Hashtable)test.get(++counter));
+ }
+ } catch (IOException ioe) {
+ errln("Error reading: " + ioe);
+ }
+ }
+
+ public void verify(AttributedCharacterIterator iterator,Hashtable table) {
+ int length = Integer.parseInt((String)table.get("length"));
+
+ // Verify the text
+ if (!getText(iterator).equals(
+ escapeIfNecessary((String)table.get("text")))) {
+ String text = getText(iterator);
+
+ errln("text doesn't match, got: " + getText(iterator));
+ }
+ if (iterator.getBeginIndex() != 0) {
+ errln("Bogus start: " + iterator.getBeginIndex());
+ }
+ if (iterator.getEndIndex() != length) {
+ errln("Bogus end: " + iterator.getEndIndex());
+ }
+ for (int counter = 0; counter < length; counter++) {
+ iterator.setIndex(counter);
+ if (!verifyAttributes(iterator.getAttributes().keySet(),
+ makeAttributes((Vector)table.get(Integer.
+ toString(counter))))) {
+ errln("Attributes don't match at " + counter + " expecting " +
+ makeAttributes((Vector)table.get(Integer.toString
+ (counter))) + " got " +
+ iterator.getAttributes().keySet());
+ }
+ }
+ for (int counter = length - 1; counter >= 0; counter--) {
+ iterator.setIndex(counter);
+ if (!verifyAttributes(iterator.getAttributes().keySet(),
+ makeAttributes((Vector)table.get(Integer.
+ toString(counter))))) {
+ errln("Attributes don't match at " + counter + " expecting " +
+ makeAttributes((Vector)table.get(Integer.toString
+ (counter))) + " got " +
+ iterator.getAttributes().keySet());
+ }
+ }
+ verifyLimits(iterator, table);
+
+ text = escapeIfNecessary((String)table.get("text"));
+ Vector fps = (Vector)table.get("fieldPositions");
+
+ if (fps != null) {
+ for (int counter = 0; counter < fps.size(); counter++) {
+ verifyFieldPosition(counter, (Hashtable)fps.get(counter));
+ }
+ }
+ }
+
+ private void verifyLimits(AttributedCharacterIterator iterator,
+ Hashtable table) {
+ Vector limits = (Vector)table.get("limits");
+
+ if (limits != null) {
+ for (int counter = 0; counter < limits.size(); counter++) {
+ verifyLimit(iterator, (Hashtable)limits.get(counter));
+ }
+ }
+ }
+
+ private void verifyLimit(AttributedCharacterIterator iterator,
+ Hashtable table) {
+ int begin = Integer.parseInt((String)table.get("begin"));
+ int end = Integer.parseInt((String)table.get("end"));
+ Set attrs = makeAttributes((Vector)table.get("attributes"));
+ String begin2S = (String)table.get("begin2");
+ int begin2 = (begin2S != null) ? Integer.parseInt(begin2S) : begin;
+ String end2S = (String)table.get("end2");
+ int end2 = (end2S != null) ? Integer.parseInt(end2S) : end;
+
+ for (int counter = begin; counter < end; counter++) {
+ iterator.setIndex(counter);
+ if (iterator.getRunStart() != begin) {
+ errln("Begin doesn't match want " + begin + " got " +
+ iterator.getRunStart() + " at " + counter + " attrs " +
+ attrs);
+ }
+ if (iterator.getRunStart(attrs) != begin2) {
+ errln("Begin2 doesn't match want " + begin2 + " got " +
+ iterator.getRunStart(attrs) + " at " + counter +
+ " attrs " + attrs);
+ }
+ if (iterator.getRunLimit() != end) {
+ errln("End doesn't match want " + end + " got " +
+ iterator.getRunLimit() + " at " + counter + " attrs " +
+ attrs);
+ }
+ if (iterator.getRunLimit(attrs) != end2) {
+ errln("End2 doesn't match want " + end2 + " got " +
+ iterator.getRunLimit(attrs) + " at " + counter +
+ " attrs " + attrs);
+ }
+ }
+ }
+
+ private boolean verifyAttributes(Set a, Set b) {
+ boolean aEmpty = (a.size() == 0);
+ boolean bEmpty = (b.size() == 0);
+
+ if (aEmpty && bEmpty) {
+ return true;
+ }
+ else if (aEmpty || bEmpty) {
+ return false;
+ }
+ return a.equals(b);
+ }
+
+ private String getText(AttributedCharacterIterator iterator) {
+ StringBuffer buffer = new StringBuffer();
+
+ for (int counter = 0; counter < iterator.getEndIndex(); counter++) {
+ buffer.append(iterator.setIndex(counter));
+ }
+ return buffer.toString();
+ }
+
+ private void verifyFieldPosition(int index, Hashtable table) {
+ Object o = table.get("field");
+ int begin = Integer.parseInt((String)table.get("begin"));
+ int end = Integer.parseInt((String)table.get("end"));
+
+ if (o != null) {
+ FieldPosition fp = new FieldPosition(((Integer)
+ lookupField((String)o)).intValue());
+
+ verifyFieldPosition(fp, begin, end, index);
+ }
+ o = table.get("fieldID");
+ if (o != null) {
+ FieldPosition fp = new FieldPosition((Format.Field)
+ lookupField((String)o));
+ verifyFieldPosition(fp, begin, end, index);
+ }
+ }
+
+ private void verifyFieldPosition(FieldPosition fp, int begin, int end,
+ int index) {
+ StringBuffer buffer = new StringBuffer();
+
+ format.format(value, buffer, fp);
+ if (fp.getBeginIndex() != begin) {
+ errln("bogus begin want " + begin + " got " + fp.getBeginIndex() +
+ " for " + fp + " at " + index);
+ }
+ if (fp.getEndIndex() != end) {
+ errln("bogus end want " + end + " got " + fp.getEndIndex() +
+ " for " + fp + " at " + index);
+ }
+ if (!buffer.toString().equals(text)) {
+ errln("Text does not match, want !" + buffer.toString() +
+ "! got !" + text + "!");
+ }
+ }
+
+ public AttributedCharacterIterator create(Hashtable table) {
+ format = (Format)createInstance((String)table.get("class"),
+ ((Vector)table.get("args")).toArray());
+ value = createInstance((String)table.get("valueClass"),
+ ((Vector)table.get("valueArgs")).toArray());
+
+ logln("Created format: " + format + " value " + value);
+ AttributedCharacterIterator aci = format.
+ formatToCharacterIterator(value);
+
+ logln("Obtained Iterator: " + aci);
+ return aci;
+ }
+
+ public Format.Field makeAttribute(String name) {
+ return (Format.Field)lookupField(name);
+ }
+
+ private Object createInstance(String className, Object[] args) {
+ if (className.equals("java.lang.reflect.Array")) {
+ for (int counter = 0; counter < args.length; counter++) {
+ if (args[counter] instanceof Vector) {
+ Vector v = (Vector)args[counter];
+
+ args[counter] = createInstance((String)v.get(0),
+ ((Vector)v.get(1)).toArray());
+ }
+ }
+ return args;
+ }
+ for (int counter = 0; counter < args.length; counter++) {
+ args[counter] = escapeIfNecessary((String)args[counter]);
+ }
+ try {
+ if (className.equals("java.util.concurrent.atomic.AtomicInteger")) {
+ return new AtomicInteger(Integer.valueOf((String)args[0]));
+ } else if (className.equals("java.util.concurrent.atomic.AtomicLong")) {
+ return new AtomicLong(Long.valueOf((String)args[0]));
+ } else {
+ Class klass = lookupClass(className);
+ Constructor cons = klass.getConstructor(
+ new Class[] { String.class });
+ Object value = cons.newInstance(args);
+
+ return value;
+ }
+ } catch (Throwable th) {
+ errln("Error creating instance " + th);
+ return null;
+ }
+ }
+
+ private Class lookupClass(String name) throws ClassNotFoundException {
+ try {
+ Class klass = Class.forName(name);
+
+ return klass;
+ } catch (ClassNotFoundException e1) {}
+
+ try {
+ Class klass = Class.forName("java.lang." + name);
+
+ return klass;
+ } catch (ClassNotFoundException e1) {}
+
+ Class klass = Class.forName("java.text." + name);
+
+ return klass;
+ }
+
+ private Object lookupField(String name) {
+ Throwable error = null;
+
+ try {
+ int dotIndex = name.indexOf('.');
+ Class klass = lookupClass(name.substring(0, dotIndex));
+ String fieldName = name.substring(dotIndex + 1);
+ Field[] fields = klass.getFields();
+
+ for (int counter = fields.length - 1; counter >= 0; counter--) {
+ if (fields[counter].getName().equals(fieldName)) {
+ return fields[counter].get(null);
+ }
+ }
+ } catch (Throwable th) {
+ error = th;
+ }
+ errln("Could not lookup field " + name + " " + error);
+ return null;
+ }
+
+ protected String escapeIfNecessary(String string) {
+ if (string != null) {
+ int index;
+
+ if ((index = string.indexOf("\\u")) != -1) {
+ StringBuffer sb = new StringBuffer(string.substring(0, index));
+
+ sb.append((char)Integer.parseInt(
+ string.substring(index + 2, index + 6), 16));
+ sb.append(string.substring(index + 6));
+ string = sb.toString();
+ }
+ }
+ return string;
+ }
+
+ public Set makeAttributes(Vector names) {
+ HashSet set = new HashSet(Math.max(1, names.size()));
+
+ for (int counter = 0; counter < names.size(); counter++) {
+ set.add(makeAttribute((String)names.get(counter)));
+ }
+ return set;
+ }
+}
diff --git a/jdk/test/java/text/Format/common/MessageFormat.Field.ser.txt b/jdk/test/java/text/Format/common/MessageFormat.Field.ser.txt
new file mode 100644
index 00000000000..5428b76680c
--- /dev/null
+++ b/jdk/test/java/text/Format/common/MessageFormat.Field.ser.txt
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2003, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Hex dump of a serialized MessageFormat.Field for Bug4769840.
+
+aced00057372001d6a6176612e746578742e4d657373616765466f726d617424
+4669656c646da23d2c7b46bfaa020000787200166a6176612e746578742e466f
+726d6174244669656c6403d7fbbd383b0f9b0200007872002f6a6176612e7465
+78742e417474726962757465644368617261637465724974657261746f722441
+7474726962757465811e7426cd47175c0200014c00046e616d657400124c6a61
+76612f6c616e672f537472696e673b78707400166d6573736167652061726775
+6d656e74206669656c64
diff --git a/jdk/test/java/text/Format/common/NumberFormat.Field.ser.txt b/jdk/test/java/text/Format/common/NumberFormat.Field.ser.txt
new file mode 100644
index 00000000000..12851638adf
--- /dev/null
+++ b/jdk/test/java/text/Format/common/NumberFormat.Field.ser.txt
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2003, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Hex dump of a serialized NumberFormat.Field for Bug4769840.
+
+aced00057372001c6a6176612e746578742e4e756d626572466f726d61742446
+69656c646802a038193ff37a020000787200166a6176612e746578742e466f72
+6d6174244669656c6403d7fbbd383b0f9b0200007872002f6a6176612e746578
+742e417474726962757465644368617261637465724974657261746f72244174
+74726962757465811e7426cd47175c0200014c00046e616d657400124c6a6176
+612f6c616e672f537472696e673b7870740007696e7465676572
diff --git a/jdk/test/java/text/Format/common/PParser.java b/jdk/test/java/text/Format/common/PParser.java
new file mode 100644
index 00000000000..6ada76b1059
--- /dev/null
+++ b/jdk/test/java/text/Format/common/PParser.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2000, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.util.*;
+
+/*
+ * assignment : key = value;
+ * key : string
+ * value : string | array | dict
+ * nValue : , value
+ * array : ( value nValue )
+ * nAssignment: , assignment|value
+ * dict : { assignment* }
+ * string : "*" or anything but a ,(){}=
+ *
+ * special characters: ,(){}=
+ */
+
+public class PParser {
+ protected static final int OPEN_PAIR = 1;
+ protected static final int CLOSE_PAIR = 2;
+ protected static final int OPEN_ARRAY = 3;
+ protected static final int CLOSE_ARRAY = 4;
+ protected static final int MORE = 5;
+ protected static final int EQUAL = 6;
+ protected static final int STRING = 7;
+ protected static final int WS = 8;
+
+ protected Reader reader;
+ protected boolean bufferedToken;
+ protected StringBuffer stringBuffer = new StringBuffer();
+ protected int lastChar;
+ protected int lastToken;
+ protected int lineNumber;
+ protected int column;
+
+ public PParser() {
+ }
+
+ public Hashtable parse(Reader r) throws IOException {
+ this.reader = r;
+ bufferedToken = false;
+ lineNumber = 0;
+ column = 0;
+ if (getToken() != OPEN_PAIR) {
+ error("No initial open");
+ }
+ return parsePair();
+ }
+
+ protected Object parseValue(int lookAhead) throws IOException {
+ int token;
+
+ if (lookAhead == -1) {
+ token = getToken();
+ } else {
+ token = lookAhead;
+ }
+ switch (token) {
+ case STRING:
+ return stringBuffer.toString();
+ case OPEN_ARRAY:
+ return parseArray();
+ case OPEN_PAIR:
+ return parsePair();
+ default:
+ error("Expecting value");
+ }
+ return null;
+ }
+
+ protected Object parseArray() throws IOException {
+ Vector array = new Vector();
+ int token;
+
+ while ((token = getToken()) != CLOSE_ARRAY) {
+ if (token == MORE) {
+ token = getToken();
+ }
+ if (token != CLOSE_ARRAY) {
+ array.addElement(parseValue(token));
+ }
+ }
+ return array;
+ }
+
+ protected Hashtable parsePair() throws IOException {
+ Hashtable ht = new Hashtable(11);
+ int token;
+
+ while ((token = getToken()) != CLOSE_PAIR) {
+ if (token != STRING) {
+ error("Pair expecting string got");
+ }
+ String key = stringBuffer.toString();
+
+ if (getToken() != EQUAL) {
+ error("Expecting = ");
+ }
+
+ Object value = parseValue(-1);
+ ht.put(key, value);
+ }
+ return ht;
+ }
+
+ protected void ungetToken() {
+ if (bufferedToken) {
+ error("Can not buffer more than one token");
+ }
+ bufferedToken = true;
+ }
+
+ protected int getToken() throws IOException {
+ int token = getToken(false, false);
+
+ return token;
+ }
+
+ protected int getToken(boolean wantsWS, boolean inString)
+ throws IOException {
+ if (bufferedToken) {
+ bufferedToken = false;
+ if (lastToken != WS || wantsWS) {
+ return lastToken;
+ }
+ }
+ while ((lastChar = reader.read()) != -1) {
+ // If a line starts with '#', skip the line.
+ if (column == 0 && lastChar == '#') {
+ while ((lastChar = reader.read()) != -1
+ && lastChar != '\n') {
+ }
+ if (lastChar == -1) {
+ break;
+ }
+ }
+
+ column++;
+ switch(lastChar) {
+ case '\n':
+ lineNumber++;
+ column = 0;
+ case ' ':
+ case '\r':
+ case '\t':
+ if (wantsWS) {
+ lastToken = WS;
+ return WS;
+ }
+ break;
+ case ',':
+ lastToken = MORE;
+ return MORE;
+ case '(':
+ lastToken = OPEN_ARRAY;
+ return OPEN_ARRAY;
+ case ')':
+ lastToken = CLOSE_ARRAY;
+ return CLOSE_ARRAY;
+ case '{':
+ lastToken = OPEN_PAIR;
+ return OPEN_PAIR;
+ case '}':
+ lastToken = CLOSE_PAIR;
+ return CLOSE_PAIR;
+ case '=':
+ lastToken = EQUAL;
+ return EQUAL;
+ case '"':
+ lastToken = STRING;
+ if (!inString) {
+ stringBuffer.setLength(0);
+ while (true) {
+ getToken(true, true);
+ if (lastChar == '"') {
+ lastToken = STRING;
+ return STRING;
+ }
+ stringBuffer.append((char)lastChar);
+ }
+ }
+ return STRING;
+ default:
+ lastToken = STRING;
+ if (!inString) {
+ stringBuffer.setLength(0);
+ stringBuffer.append((char)lastChar);
+ while (getToken(true, true) == STRING) {
+ if (lastChar == '"') {
+ error("Unexpected quote");
+ }
+ stringBuffer.append((char)lastChar);
+ }
+ ungetToken();
+ }
+ return STRING;
+ }
+ }
+ return -1;
+ }
+
+ protected void error(String errorString) {
+ throw new RuntimeException(errorString + " at line " + lineNumber + " column " + column);
+ }
+
+ public static void dump(Object o) {
+ if (o instanceof String) {
+ System.out.print(o);
+ } else if(o instanceof Vector) {
+ Enumeration e = ((Vector)o).elements();
+
+ dump(" (");
+ while (e.hasMoreElements()) {
+ dump(e.nextElement());
+ dump(" -- ");
+ }
+ dump(" )");
+ } else {
+ Hashtable ht = (Hashtable)o;
+ Enumeration e = ht.keys();
+
+ dump(" {");
+ while (e.hasMoreElements()) {
+ Object key = e.nextElement();
+
+ dump(key);
+ dump(" = ");
+ dump(ht.get(key));
+ dump(";");
+ }
+ dump(" }");
+ }
+ }
+
+ public static void main(String[] args) {
+ if (args.length == 0) {
+ System.out.println("need filename");
+ } else {
+ try {
+ FileReader fr = new FileReader(args[0]);
+ PParser parser = new PParser();
+ Hashtable ht = parser.parse(fr);
+
+ dump(ht);
+ System.out.println();
+ }
+ catch (IOException ioe) {
+ System.out.println("Couldn't parse: " + ioe);
+ }
+ }
+ }
+}
diff --git a/jdk/test/java/text/Format/common/dateFormat.props b/jdk/test/java/text/Format/common/dateFormat.props
new file mode 100644
index 00000000000..22bb9a44d78
--- /dev/null
+++ b/jdk/test/java/text/Format/common/dateFormat.props
@@ -0,0 +1,333 @@
+#
+# Copyright (c) 2000, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Test data for FormatIteratorTest
+
+{
+ tests =
+ (
+ {
+ class = java.text.SimpleDateFormat
+ args = ("M/dd/yy")
+ valueClass = java.util.Date
+ valueArgs = ("7/10/71")
+ }
+ {
+ length = 7
+ text = "7/10/71"
+ 0 = (DateFormat$Field.MONTH)
+ 1 = ()
+ 2 = (DateFormat$Field.DAY_OF_MONTH)
+ 3 = (DateFormat$Field.DAY_OF_MONTH)
+ 4 = ()
+ 5 = (DateFormat$Field.YEAR)
+ 6 = (DateFormat$Field.YEAR)
+ limits = ( { attributes = (DateFormat$Field.MONTH)
+ begin = 0 end = 1}
+ { attributes = ()
+ begin = 1 begin2 = 0 end = 2 end2 = 7}
+ { attributes = (DateFormat$Field.DAY_OF_MONTH)
+ begin = 2 end = 4}
+ { attributes = ()
+ begin = 4 begin2 = 0 end = 5 end2 = 7}
+ { attributes = (DateFormat$Field.YEAR)
+ begin = 5 end = 7}
+ )
+ fieldPositions =
+ (
+ {
+ field = DateFormat.MONTH_FIELD
+ fieldID = DateFormat$Field.MONTH
+ begin = 0 end = 1
+ }
+ {
+ field = DateFormat.DATE_FIELD
+ fieldID = DateFormat$Field.DAY_OF_MONTH
+ begin = 2 end = 4
+ }
+ {
+ field = DateFormat.YEAR_FIELD
+ fieldID = DateFormat$Field.YEAR
+ begin = 5 end = 7
+ }
+ )
+ }
+
+ {
+ class = java.text.SimpleDateFormat
+ args = ("EEEEEEE MMMMMMMMMMMMM yyyy GG")
+ valueClass = java.util.Date
+ valueArgs = ("12/10/2020")
+ }
+ {
+ length = 25
+ text = "Thursday December 2020 AD"
+ 0 = (DateFormat$Field.DAY_OF_WEEK)
+ 1 = (DateFormat$Field.DAY_OF_WEEK)
+ 2 = (DateFormat$Field.DAY_OF_WEEK)
+ 3 = (DateFormat$Field.DAY_OF_WEEK)
+ 4 = (DateFormat$Field.DAY_OF_WEEK)
+ 5 = (DateFormat$Field.DAY_OF_WEEK)
+ 6 = (DateFormat$Field.DAY_OF_WEEK)
+ 7 = (DateFormat$Field.DAY_OF_WEEK)
+ 8 = ()
+ 9 = (DateFormat$Field.MONTH)
+ 10 = (DateFormat$Field.MONTH)
+ 11 = (DateFormat$Field.MONTH)
+ 12 = (DateFormat$Field.MONTH)
+ 13 = (DateFormat$Field.MONTH)
+ 14 = (DateFormat$Field.MONTH)
+ 15 = (DateFormat$Field.MONTH)
+ 16 = (DateFormat$Field.MONTH)
+ 17 = ()
+ 18 = (DateFormat$Field.YEAR)
+ 19 = (DateFormat$Field.YEAR)
+ 20 = (DateFormat$Field.YEAR)
+ 21 = (DateFormat$Field.YEAR)
+ 22 = ()
+ 23 = (DateFormat$Field.ERA)
+ 24 = (DateFormat$Field.ERA)
+ limits = ( { attributes = (DateFormat$Field.DAY_OF_WEEK)
+ begin = 0 end = 8}
+ { attributes = ()
+ begin = 8 begin2 = 0 end = 9 end2 = 25}
+ { attributes = (DateFormat$Field.MONTH)
+ begin = 9 end = 17}
+ { attributes = ()
+ begin = 17 begin2 = 0 end = 18 end2 = 25}
+ { attributes = (DateFormat$Field.YEAR)
+ begin = 18 end = 22}
+ { attributes = ()
+ begin = 22 begin2 = 0 end = 23 end2 = 25}
+ { attributes = (DateFormat$Field.ERA)
+ begin = 23 end = 25}
+ )
+ fieldPositions =
+ (
+ {
+ field = DateFormat.DAY_OF_WEEK_FIELD
+ fieldID = DateFormat$Field.DAY_OF_WEEK
+ begin = 0 end = 8
+ }
+ {
+ field = DateFormat.MONTH_FIELD
+ fieldID = DateFormat$Field.MONTH
+ begin = 9 end = 17
+ }
+ {
+ field = DateFormat.YEAR_FIELD
+ fieldID = DateFormat$Field.YEAR
+ begin = 18 end = 22
+ }
+ {
+ field = DateFormat.ERA_FIELD
+ fieldID = DateFormat$Field.ERA
+ begin = 23 end = 25
+ }
+ )
+ }
+
+ {
+ class = java.text.SimpleDateFormat
+ args = ("h HH:mm:ss:SSS aa")
+ valueClass = java.util.Date
+ valueArgs = ("1/1/2000 2:52:12 PM")
+ }
+ {
+ length = 17
+ text = "2 14:52:12:000 PM"
+ 0 = (DateFormat$Field.HOUR1)
+ 1 = ()
+ 2 = (DateFormat$Field.HOUR_OF_DAY0)
+ 3 = (DateFormat$Field.HOUR_OF_DAY0)
+ 4 = ()
+ 5 = (DateFormat$Field.MINUTE)
+ 6 = (DateFormat$Field.MINUTE)
+ 7 = ()
+ 8 = (DateFormat$Field.SECOND)
+ 9 = (DateFormat$Field.SECOND)
+ 10 = ()
+ 11 = (DateFormat$Field.MILLISECOND)
+ 12 = (DateFormat$Field.MILLISECOND)
+ 13 = (DateFormat$Field.MILLISECOND)
+ 14 = ()
+ 15 = (DateFormat$Field.AM_PM)
+ 16 = (DateFormat$Field.AM_PM)
+ limits = ( { attributes = (DateFormat$Field.HOUR1)
+ begin = 0 end = 1}
+ { attributes = ()
+ begin = 1 begin2 = 0 end = 2 end2 = 17}
+ { attributes = (DateFormat$Field.HOUR_OF_DAY0)
+ begin = 2 end = 4}
+ { attributes = ()
+ begin = 4 begin2 = 0 end = 5 end2 = 17}
+ { attributes = (DateFormat$Field.MINUTE)
+ begin = 5 end = 7}
+ { attributes = ()
+ begin = 7 begin2 = 0 end = 8 end2 = 17}
+ { attributes = (DateFormat$Field.SECOND)
+ begin = 8 end = 10}
+ { attributes = ()
+ begin = 10 begin2 = 0 end = 11 end2 = 17}
+ { attributes = (DateFormat$Field.MILLISECOND)
+ begin = 11 end = 14}
+ { attributes = ()
+ begin = 14 begin2 = 0 end = 15 end2 = 17}
+ { attributes = (DateFormat$Field.AM_PM)
+ begin = 15 end = 17}
+ )
+ fieldPositions =
+ (
+ {
+ field = DateFormat.HOUR1_FIELD
+ fieldID = DateFormat$Field.HOUR1
+ begin = 0 end = 1
+ }
+ {
+ field = DateFormat.HOUR_OF_DAY0_FIELD
+ fieldID = DateFormat$Field.HOUR_OF_DAY0
+ begin = 2 end = 4
+ }
+ {
+ field = DateFormat.MINUTE_FIELD
+ fieldID = DateFormat$Field.MINUTE
+ begin = 5 end = 7
+ }
+ {
+ field = DateFormat.SECOND_FIELD
+ fieldID = DateFormat$Field.SECOND
+ begin = 8 end = 10
+ }
+ {
+ field = DateFormat.MILLISECOND_FIELD
+ fieldID = DateFormat$Field.MILLISECOND
+ begin = 11 end = 14
+ }
+ {
+ field = DateFormat.AM_PM_FIELD
+ fieldID = DateFormat$Field.AM_PM
+ begin = 15 end = 17
+ }
+ )
+ }
+
+
+ {
+ class = java.text.SimpleDateFormat
+ args = ("kk KK DDD FF ww WW zz")
+ valueClass = java.util.Date
+ valueArgs = ("4/26/2031 2:02:52 AM")
+ }
+ {
+ length = 22
+ text = "02 02 116 04 17 04 PDT"
+ 0 = (DateFormat$Field.HOUR_OF_DAY1)
+ 1 = (DateFormat$Field.HOUR_OF_DAY1)
+ 2 = ()
+ 3 = (DateFormat$Field.HOUR0)
+ 4 = (DateFormat$Field.HOUR0)
+ 5 = ()
+ 6 = (DateFormat$Field.DAY_OF_YEAR)
+ 7 = (DateFormat$Field.DAY_OF_YEAR)
+ 8 = (DateFormat$Field.DAY_OF_YEAR)
+ 9 = ()
+ 10 = (DateFormat$Field.DAY_OF_WEEK_IN_MONTH)
+ 11 = (DateFormat$Field.DAY_OF_WEEK_IN_MONTH)
+ 12 = ()
+ 13 = (DateFormat$Field.WEEK_OF_YEAR)
+ 14 = (DateFormat$Field.WEEK_OF_YEAR)
+ 15 = ()
+ 16 = (DateFormat$Field.WEEK_OF_MONTH)
+ 17 = (DateFormat$Field.WEEK_OF_MONTH)
+ 18 = ()
+ 19 = (DateFormat$Field.TIME_ZONE)
+ 20 = (DateFormat$Field.TIME_ZONE)
+ 21 = (DateFormat$Field.TIME_ZONE)
+ limits = ( { attributes = (DateFormat$Field.HOUR_OF_DAY1)
+ begin = 0 end = 2}
+ { attributes = ()
+ begin = 2 begin2 = 0 end = 3 end2 = 22}
+ { attributes = (DateFormat$Field.HOUR0)
+ begin = 3 end = 5}
+ { attributes = ()
+ begin = 5 begin2 = 0 end = 6 end2 = 22}
+ { attributes = (DateFormat$Field.DAY_OF_YEAR)
+ begin = 6 end = 9}
+ { attributes = ()
+ begin = 9 begin2 = 0 end = 10 end2 = 22}
+ { attributes = (DateFormat$Field.DAY_OF_WEEK_IN_MONTH)
+ begin = 10 end = 12}
+ { attributes = ()
+ begin = 12 begin2 = 0 end = 13 end2 = 22}
+ { attributes = (DateFormat$Field.WEEK_OF_YEAR)
+ begin = 13 end = 15}
+ { attributes = ()
+ begin = 15 begin2 = 0 end = 16 end2 = 22}
+ { attributes = (DateFormat$Field.WEEK_OF_MONTH)
+ begin = 16 end = 18}
+ { attributes = ()
+ begin = 18 begin2 = 0 end = 19 end2 = 22}
+ { attributes = (DateFormat$Field.TIME_ZONE)
+ begin = 19 end = 22}
+ )
+ fieldPositions =
+ (
+ {
+ field = DateFormat.HOUR_OF_DAY1_FIELD
+ fieldID = DateFormat$Field.HOUR_OF_DAY1
+ begin = 0 end = 2
+ }
+ {
+ field = DateFormat.HOUR0_FIELD
+ fieldID = DateFormat$Field.HOUR0
+ begin = 3 end = 5
+ }
+ {
+ field = DateFormat.DAY_OF_YEAR_FIELD
+ fieldID = DateFormat$Field.DAY_OF_YEAR
+ begin = 6 end = 9
+ }
+ {
+ field = DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD
+ fieldID = DateFormat$Field.DAY_OF_WEEK_IN_MONTH
+ begin = 10 end = 12
+ }
+ {
+ field = DateFormat.WEEK_OF_YEAR_FIELD
+ fieldID = DateFormat$Field.WEEK_OF_YEAR
+ begin = 13 end = 15
+ }
+ {
+ field = DateFormat.WEEK_OF_MONTH_FIELD
+ fieldID = DateFormat$Field.WEEK_OF_MONTH
+ begin = 16 end = 18
+ }
+ {
+ field = DateFormat.TIMEZONE_FIELD
+ fieldID = DateFormat$Field.TIME_ZONE
+ begin = 19 end = 22
+ }
+ )
+ }
+ )
+}
diff --git a/jdk/test/java/text/Format/common/decimalFormat.props b/jdk/test/java/text/Format/common/decimalFormat.props
new file mode 100644
index 00000000000..e6d9adc7974
--- /dev/null
+++ b/jdk/test/java/text/Format/common/decimalFormat.props
@@ -0,0 +1,1280 @@
+#
+# Copyright (c) 2000, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Test data for FormatIteratorTest
+
+{
+ tests =
+ (
+ {
+ class = java.text.DecimalFormat
+ args = ("#,###")
+ valueClass = java.lang.Integer
+ valueArgs = ("1234567")
+ }
+ {
+ length = 9
+ text = "1,234,567"
+ 0 = (NumberFormat$Field.INTEGER)
+ 1 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 2 = (NumberFormat$Field.INTEGER)
+ 3 = (NumberFormat$Field.INTEGER)
+ 4 = (NumberFormat$Field.INTEGER)
+ 5 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 6 = (NumberFormat$Field.INTEGER)
+ 7 = (NumberFormat$Field.INTEGER)
+ 8 = (NumberFormat$Field.INTEGER)
+ limits = ( { attributes = (NumberFormat$Field.INTEGER)
+ begin = 0 end = 1 end2 = 9}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 1 end = 2}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 1 end = 2}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 5 end = 6}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 5 end = 6}
+ )
+ fieldPositions =
+ (
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 0 end = 9
+ }
+ {
+ fieldID = NumberFormat$Field.GROUPING_SEPARATOR
+ begin = 1 end = 2
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("#,###.##")
+ valueClass = java.lang.Float
+ valueArgs = ("567.78")
+ }
+ {
+ length = 6
+ text = "567.78"
+ 0 = (NumberFormat$Field.INTEGER)
+ 1 = (NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.INTEGER)
+ 3 = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ 4 = (NumberFormat$Field.FRACTION)
+ 5 = (NumberFormat$Field.FRACTION)
+ limits = ( { attributes = (NumberFormat$Field.INTEGER)
+ begin = 0 end = 3 }
+ { attributes = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ begin = 3 end = 4}
+ { attributes = (NumberFormat$Field.FRACTION)
+ begin = 4 end = 6}
+ )
+ fieldPositions =
+ (
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 0 end = 3
+ }
+ {
+ fieldID = NumberFormat$Field.DECIMAL_SEPARATOR
+ begin = 3 end = 4
+ }
+ {
+ field = NumberFormat.FRACTION_FIELD
+ fieldID = NumberFormat$Field.FRACTION
+ begin = 4 end = 6
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("0.#E00")
+ valueClass = java.lang.Float
+ valueArgs = ("1200")
+ }
+ {
+ length = 6
+ text = "1.2E03"
+ 0 = (NumberFormat$Field.INTEGER)
+ 1 = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ 2 = (NumberFormat$Field.FRACTION)
+ 3 = (NumberFormat$Field.EXPONENT_SYMBOL)
+ 4 = (NumberFormat$Field.EXPONENT)
+ 5 = (NumberFormat$Field.EXPONENT)
+ limits = ( { attributes = (NumberFormat$Field.INTEGER)
+ begin = 0 end = 1 }
+ { attributes = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ begin = 1 end = 2}
+ { attributes = (NumberFormat$Field.FRACTION)
+ begin = 2 end = 3}
+ { attributes = (NumberFormat$Field.EXPONENT_SYMBOL)
+ begin = 3 end = 4}
+ { attributes = (NumberFormat$Field.EXPONENT)
+ begin = 4 end = 6}
+ )
+ fieldPositions =
+ (
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 0 end = 1
+ }
+ {
+ fieldID = NumberFormat$Field.DECIMAL_SEPARATOR
+ begin = 1 end = 2
+ }
+ {
+ field = NumberFormat.FRACTION_FIELD
+ fieldID = NumberFormat$Field.FRACTION
+ begin = 2 end = 3
+ }
+ {
+ fieldID = NumberFormat$Field.EXPONENT_SYMBOL
+ begin = 3 end = 4
+ }
+ {
+ fieldID = NumberFormat$Field.EXPONENT
+ begin = 4 end = 6
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("0.#E00")
+ valueClass = java.lang.Float
+ valueArgs = ("-.0012")
+ }
+ {
+ length = 8
+ text = "-1.2E-03"
+ 0 = (NumberFormat$Field.SIGN)
+ 1 = (NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ 3 = (NumberFormat$Field.FRACTION)
+ 4 = (NumberFormat$Field.EXPONENT_SYMBOL)
+ 5 = (NumberFormat$Field.EXPONENT_SIGN)
+ 6 = (NumberFormat$Field.EXPONENT)
+ 7 = (NumberFormat$Field.EXPONENT)
+ limits = ( { attributes = (NumberFormat$Field.SIGN)
+ begin = 0 end = 1 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 1 end = 2}
+ { attributes = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ begin = 2 end = 3}
+ { attributes = (NumberFormat$Field.FRACTION)
+ begin = 3 end = 4}
+ { attributes = (NumberFormat$Field.EXPONENT_SYMBOL)
+ begin = 4 end = 5}
+ { attributes = (NumberFormat$Field.EXPONENT_SIGN)
+ begin = 5 end = 6}
+ { attributes = (NumberFormat$Field.EXPONENT)
+ begin = 6 end = 8}
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = NumberFormat$Field.SIGN
+ begin = 0 end = 1
+ }
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 1 end = 2
+ }
+ {
+ fieldID = NumberFormat$Field.DECIMAL_SEPARATOR
+ begin = 2 end = 3
+ }
+ {
+ field = NumberFormat.FRACTION_FIELD
+ fieldID = NumberFormat$Field.FRACTION
+ begin = 3 end = 4
+ }
+ {
+ fieldID = NumberFormat$Field.EXPONENT_SYMBOL
+ begin = 4 end = 5
+ }
+ {
+ fieldID = NumberFormat$Field.EXPONENT_SIGN
+ begin = 5 end = 6
+ }
+ {
+ fieldID = NumberFormat$Field.EXPONENT
+ begin = 6 end = 8
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("#,###;(#,###)")
+ valueClass = java.lang.Integer
+ valueArgs = ("-1234")
+ }
+ {
+ length = 7
+ text = "(1,234)"
+ 0 = ()
+ 1 = (NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 3 = (NumberFormat$Field.INTEGER)
+ 4 = (NumberFormat$Field.INTEGER)
+ 5 = (NumberFormat$Field.INTEGER)
+ 6 = ()
+ limits = ( { attributes = ()
+ begin = 0 end = 1 end2 = 7 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 1 end = 2 end2 = 6}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 2 end = 3}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 2 end = 3}
+ { attributes = ()
+ begin = 6 begin2 = 0 end = 7}
+ )
+ fieldPositions =
+ (
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 1 end = 6
+ }
+ {
+ fieldID = NumberFormat$Field.GROUPING_SEPARATOR
+ begin = 2 end = 3
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("#,###;-#,###")
+ valueClass = java.lang.Integer
+ valueArgs = ("-134")
+ }
+ {
+ length = 4
+ text = "-134"
+ 0 = (NumberFormat$Field.SIGN)
+ 1 = (NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.INTEGER)
+ 3 = (NumberFormat$Field.INTEGER)
+ limits = ( { attributes = (NumberFormat$Field.SIGN)
+ begin = 0 end = 1 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 1 end = 4 }
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = NumberFormat$Field.SIGN
+ begin = 0 end = 1
+ }
+ {
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 1 end = 4
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("+#,###")
+ valueClass = java.lang.Integer
+ valueArgs = ("134")
+ }
+ {
+ length = 4
+ text = "+134"
+ 0 = ()
+ 1 = (NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.INTEGER)
+ 3 = (NumberFormat$Field.INTEGER)
+ limits = ( { attributes = (NumberFormat$Field.SIGN)
+ begin = 0 end2 = 4 end = 1 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 1 end = 4 }
+ )
+ fieldPositions =
+ (
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 1 end = 4
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("##.0#%")
+ valueClass = java.lang.Float
+ valueArgs = (".1234")
+ }
+ {
+ length = 6
+ text = "12.34%"
+ 0 = (NumberFormat$Field.INTEGER)
+ 1 = (NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ 3 = (NumberFormat$Field.FRACTION)
+ 4 = (NumberFormat$Field.FRACTION)
+ 5 = (NumberFormat$Field.PERCENT)
+ limits = ( { attributes = (NumberFormat$Field.INTEGER)
+ begin = 0 end = 2 }
+ { attributes = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ begin = 2 end = 3 }
+ { attributes = (NumberFormat$Field.FRACTION)
+ begin = 3 end = 5 }
+ { attributes = (NumberFormat$Field.PERCENT)
+ begin = 5 end = 6 }
+ )
+ fieldPositions =
+ (
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 0 end = 2
+ }
+ {
+ fieldID = NumberFormat$Field.DECIMAL_SEPARATOR
+ begin = 2 end = 3
+ }
+ {
+ field = NumberFormat.FRACTION_FIELD
+ fieldID = NumberFormat$Field.FRACTION
+ begin = 3 end = 5
+ }
+ {
+ fieldID = NumberFormat$Field.PERCENT
+ begin = 5 end = 6
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("#,##.#\u2030")
+ valueClass = java.lang.Float
+ valueArgs = (".1234")
+ }
+ {
+ length = 7
+ text = "1,23.4\u2030"
+ 0 = (NumberFormat$Field.INTEGER)
+ 1 = (NumberFormat$Field.GROUPING_SEPARATOR
+ NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.INTEGER)
+ 3 = (NumberFormat$Field.INTEGER)
+ 4 = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ 5 = (NumberFormat$Field.FRACTION)
+ 6 = (NumberFormat$Field.PERMILLE)
+ limits = ( { attributes = (NumberFormat$Field.INTEGER)
+ begin = 0 end = 1 end2 = 4 }
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 1 end = 2 }
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 1 end = 2 }
+ { attributes = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ begin = 4 end = 5 }
+ { attributes = (NumberFormat$Field.FRACTION)
+ begin = 5 end = 6 }
+ { attributes = (NumberFormat$Field.PERMILLE)
+ begin = 6 end = 7 }
+ )
+ fieldPositions =
+ (
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 0 end = 4
+ }
+ {
+ fieldID = NumberFormat$Field.GROUPING_SEPARATOR
+ begin = 1 end = 2
+ }
+ {
+ fieldID = NumberFormat$Field.DECIMAL_SEPARATOR
+ begin = 4 end = 5
+ }
+ {
+ field = NumberFormat.FRACTION_FIELD
+ fieldID = NumberFormat$Field.FRACTION
+ begin = 5 end = 6
+ }
+ {
+ fieldID = NumberFormat$Field.PERMILLE
+ begin = 6 end = 7
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("\u00A40,000.00")
+ valueClass = java.lang.Float
+ valueArgs = ("12.51")
+ }
+ {
+ length = 9
+ text = "$0,012.51"
+ 0 = (NumberFormat$Field.CURRENCY)
+ 1 = (NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.GROUPING_SEPARATOR
+ NumberFormat$Field.INTEGER)
+ 3 = (NumberFormat$Field.INTEGER)
+ 4 = (NumberFormat$Field.INTEGER)
+ 5 = (NumberFormat$Field.INTEGER)
+ 6 = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ 7 = (NumberFormat$Field.FRACTION)
+ 8 = (NumberFormat$Field.FRACTION)
+ limits = ( { attributes = (NumberFormat$Field.CURRENCY)
+ begin = 0 end = 1 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 1 end = 2 end2 = 6 }
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 2 end = 3 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 3 begin2 = 1 end = 6 }
+ { attributes = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ begin = 6 end = 7 }
+ { attributes = (NumberFormat$Field.FRACTION)
+ begin = 7 end = 9 }
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = NumberFormat$Field.CURRENCY
+ begin = 0 end = 1
+ }
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 1 end = 6
+ }
+ {
+ fieldID = NumberFormat$Field.GROUPING_SEPARATOR
+ begin = 2 end = 3
+ }
+ {
+ fieldID = NumberFormat$Field.DECIMAL_SEPARATOR
+ begin = 6 end = 7
+ }
+ {
+ field = NumberFormat.FRACTION_FIELD
+ fieldID = NumberFormat$Field.FRACTION
+ begin = 7 end = 9
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("#,###")
+ valueClass = java.math.BigInteger
+ valueArgs = ("-12345678901234567890123456789012345")
+ }
+ {
+ length = 47
+ text = "-12,345,678,901,234,567,890,123,456,789,012,345"
+ 0 = (NumberFormat$Field.SIGN)
+ 1 = (NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.INTEGER)
+ 3 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 4 = (NumberFormat$Field.INTEGER)
+ 5 = (NumberFormat$Field.INTEGER)
+ 6 = (NumberFormat$Field.INTEGER)
+ 7 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 8 = (NumberFormat$Field.INTEGER)
+ 9 = (NumberFormat$Field.INTEGER)
+ 10 = (NumberFormat$Field.INTEGER)
+ 11 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 12 = (NumberFormat$Field.INTEGER)
+ 13 = (NumberFormat$Field.INTEGER)
+ 14 = (NumberFormat$Field.INTEGER)
+ 15 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 16 = (NumberFormat$Field.INTEGER)
+ 17 = (NumberFormat$Field.INTEGER)
+ 18 = (NumberFormat$Field.INTEGER)
+ 19 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 20 = (NumberFormat$Field.INTEGER)
+ 21 = (NumberFormat$Field.INTEGER)
+ 22 = (NumberFormat$Field.INTEGER)
+ 23 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 24 = (NumberFormat$Field.INTEGER)
+ 25 = (NumberFormat$Field.INTEGER)
+ 26 = (NumberFormat$Field.INTEGER)
+ 27 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 28 = (NumberFormat$Field.INTEGER)
+ 29 = (NumberFormat$Field.INTEGER)
+ 30 = (NumberFormat$Field.INTEGER)
+ 31 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 32 = (NumberFormat$Field.INTEGER)
+ 33 = (NumberFormat$Field.INTEGER)
+ 34 = (NumberFormat$Field.INTEGER)
+ 35 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 36 = (NumberFormat$Field.INTEGER)
+ 37 = (NumberFormat$Field.INTEGER)
+ 38 = (NumberFormat$Field.INTEGER)
+ 39 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 40 = (NumberFormat$Field.INTEGER)
+ 41 = (NumberFormat$Field.INTEGER)
+ 42 = (NumberFormat$Field.INTEGER)
+ 43 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 44 = (NumberFormat$Field.INTEGER)
+ 45 = (NumberFormat$Field.INTEGER)
+ 46 = (NumberFormat$Field.INTEGER)
+ limits = (
+ { attributes = (NumberFormat$Field.SIGN)
+ begin = 0 end = 1 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 1 end = 3 end2 = 47 }
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 3 end = 4 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 4 begin2 = 1 end = 7 end2 = 47}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 7 end = 8 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 8 begin2 = 1 end = 11 end2 = 47}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 11 end = 12 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 12 begin2 = 1 end = 15 end2 = 47}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 15 end = 16 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 16 begin2 = 1 end = 19 end2 = 47}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 19 end = 20 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 20 begin2 = 1 end = 23 end2 = 47}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 23 end = 24 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 24 begin2 = 1 end = 27 end2 = 47}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 27 end = 28 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 28 begin2 = 1 end = 31 end2 = 47}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 31 end = 32 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 32 begin2 = 1 end = 35 end2 = 47}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 35 end = 36 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 36 begin2 = 1 end = 39 end2 = 47}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 39 end = 40 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 40 begin2 = 1 end = 43 end2 = 47}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 43 begin2 = 43 end = 44 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 44 begin2 = 1 end = 47}
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = NumberFormat$Field.SIGN
+ begin = 0 end = 1
+ }
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 1 end = 47
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("#,###.#####################")
+ valueClass = java.math.BigDecimal
+ valueArgs = ("-123456789012345678901234567890.12345678901234567890")
+ }
+ {
+ length = 60
+ text = "-123,456,789,012,345,678,901,234,567,890.1234567890123456789"
+ 0 = (NumberFormat$Field.SIGN)
+ 1 = (NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.INTEGER)
+ 3 = (NumberFormat$Field.INTEGER)
+ 4 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 5 = (NumberFormat$Field.INTEGER)
+ 6 = (NumberFormat$Field.INTEGER)
+ 7 = (NumberFormat$Field.INTEGER)
+ 8 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 9 = (NumberFormat$Field.INTEGER)
+ 10 = (NumberFormat$Field.INTEGER)
+ 11 = (NumberFormat$Field.INTEGER)
+ 12 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 13 = (NumberFormat$Field.INTEGER)
+ 14 = (NumberFormat$Field.INTEGER)
+ 15 = (NumberFormat$Field.INTEGER)
+ 16 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 17 = (NumberFormat$Field.INTEGER)
+ 18 = (NumberFormat$Field.INTEGER)
+ 19 = (NumberFormat$Field.INTEGER)
+ 20 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 21 = (NumberFormat$Field.INTEGER)
+ 22 = (NumberFormat$Field.INTEGER)
+ 23 = (NumberFormat$Field.INTEGER)
+ 24 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 25 = (NumberFormat$Field.INTEGER)
+ 26 = (NumberFormat$Field.INTEGER)
+ 27 = (NumberFormat$Field.INTEGER)
+ 28 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 29 = (NumberFormat$Field.INTEGER)
+ 30 = (NumberFormat$Field.INTEGER)
+ 31 = (NumberFormat$Field.INTEGER)
+ 32 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 33 = (NumberFormat$Field.INTEGER)
+ 34 = (NumberFormat$Field.INTEGER)
+ 35 = (NumberFormat$Field.INTEGER)
+ 36 = (NumberFormat$Field.INTEGER NumberFormat$Field.GROUPING_SEPARATOR)
+ 37 = (NumberFormat$Field.INTEGER)
+ 38 = (NumberFormat$Field.INTEGER)
+ 39 = (NumberFormat$Field.INTEGER)
+ 40 = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ 41 = (NumberFormat$Field.FRACTION)
+ 42 = (NumberFormat$Field.FRACTION)
+ 43 = (NumberFormat$Field.FRACTION)
+ 44 = (NumberFormat$Field.FRACTION)
+ 45 = (NumberFormat$Field.FRACTION)
+ 45 = (NumberFormat$Field.FRACTION)
+ 45 = (NumberFormat$Field.FRACTION)
+ 45 = (NumberFormat$Field.FRACTION)
+ 45 = (NumberFormat$Field.FRACTION)
+ 45 = (NumberFormat$Field.FRACTION)
+ 45 = (NumberFormat$Field.FRACTION)
+ 45 = (NumberFormat$Field.FRACTION)
+ 46 = (NumberFormat$Field.FRACTION)
+ 47 = (NumberFormat$Field.FRACTION)
+ 48 = (NumberFormat$Field.FRACTION)
+ 49 = (NumberFormat$Field.FRACTION)
+ 50 = (NumberFormat$Field.FRACTION)
+ 51 = (NumberFormat$Field.FRACTION)
+ 52 = (NumberFormat$Field.FRACTION)
+ 53 = (NumberFormat$Field.FRACTION)
+ 54 = (NumberFormat$Field.FRACTION)
+ 55 = (NumberFormat$Field.FRACTION)
+ 56 = (NumberFormat$Field.FRACTION)
+ 57 = (NumberFormat$Field.FRACTION)
+ 58 = (NumberFormat$Field.FRACTION)
+ 59 = (NumberFormat$Field.FRACTION)
+ limits = (
+ { attributes = (NumberFormat$Field.SIGN)
+ begin = 0 end = 1 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 1 end = 4 end2 = 40 }
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 4 end = 5 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 5 begin2 = 1 end = 8 end2 = 40}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 8 end = 9 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 9 begin2 = 1 end = 12 end2 = 40}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 12 end = 13 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 13 begin2 = 1 end = 16 end2 = 40}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 16 end = 17 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 17 begin2 = 1 end = 20 end2 = 40}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 20 end = 21 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 21 begin2 = 1 end = 24 end2 = 40}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 24 end = 25 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 25 begin2 = 1 end = 28 end2 = 40}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 28 end = 29 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 29 begin2 = 1 end = 32 end2 = 40}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 32 end = 33 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 33 begin2 = 1 end = 36 end2 = 40}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 36 end = 37 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 37 begin2 = 1 end = 40 end2 = 40}
+ { attributes = (NumberFormat$Field.DECIMAL_SEPARATOR)
+ begin = 40 end = 41 }
+ { attributes = (NumberFormat$Field.FRACTION)
+ begin = 41 begin2 = 41 end = 60 }
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = NumberFormat$Field.SIGN
+ begin = 0 end = 1
+ }
+ {
+ fieldID = NumberFormat$Field.DECIMAL_SEPARATOR
+ begin = 40 end = 41
+ }
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 1 end = 40
+ }
+ {
+ field = NumberFormat.FRACTION_FIELD
+ fieldID = NumberFormat$Field.FRACTION
+ begin = 41 end = 60
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("#,###")
+ valueClass = java.lang.Long
+ valueArgs = ("9223372036854775807")
+ }
+ {
+ length = 25
+ text = "9,223,372,036,854,775,807"
+ 0 = (NumberFormat$Field.INTEGER)
+ 1 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 2 = (NumberFormat$Field.INTEGER)
+ 3 = (NumberFormat$Field.INTEGER)
+ 4 = (NumberFormat$Field.INTEGER)
+ 5 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 6 = (NumberFormat$Field.INTEGER)
+ 7 = (NumberFormat$Field.INTEGER)
+ 8 = (NumberFormat$Field.INTEGER)
+ 9 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 10 = (NumberFormat$Field.INTEGER)
+ 11 = (NumberFormat$Field.INTEGER)
+ 12 = (NumberFormat$Field.INTEGER)
+ 13 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 14 = (NumberFormat$Field.INTEGER)
+ 15 = (NumberFormat$Field.INTEGER)
+ 16 = (NumberFormat$Field.INTEGER)
+ 17 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 18 = (NumberFormat$Field.INTEGER)
+ 19 = (NumberFormat$Field.INTEGER)
+ 20 = (NumberFormat$Field.INTEGER)
+ 21 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 22 = (NumberFormat$Field.INTEGER)
+ 23 = (NumberFormat$Field.INTEGER)
+ 24 = (NumberFormat$Field.INTEGER)
+ limits = (
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 0 end = 1 end2 = 25}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 1 end = 2}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 1 end = 2}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 5 end = 6}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 5 end = 6}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 9 end = 10}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 9 end = 10}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 13 end = 14}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 13 end = 14}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 17 end = 18}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 17 end = 18}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 21 end = 22}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 21 end = 22}
+ )
+ fieldPositions =
+ (
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 0 end = 25
+ }
+ {
+ fieldID = NumberFormat$Field.GROUPING_SEPARATOR
+ begin = 1 end = 2
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("#,###")
+ valueClass = java.util.concurrent.atomic.AtomicLong
+ valueArgs = ("9223372036854775807")
+ }
+ {
+ length = 25
+ text = "9,223,372,036,854,775,807"
+ 0 = (NumberFormat$Field.INTEGER)
+ 1 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 2 = (NumberFormat$Field.INTEGER)
+ 3 = (NumberFormat$Field.INTEGER)
+ 4 = (NumberFormat$Field.INTEGER)
+ 5 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 6 = (NumberFormat$Field.INTEGER)
+ 7 = (NumberFormat$Field.INTEGER)
+ 8 = (NumberFormat$Field.INTEGER)
+ 9 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 10 = (NumberFormat$Field.INTEGER)
+ 11 = (NumberFormat$Field.INTEGER)
+ 12 = (NumberFormat$Field.INTEGER)
+ 13 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 14 = (NumberFormat$Field.INTEGER)
+ 15 = (NumberFormat$Field.INTEGER)
+ 16 = (NumberFormat$Field.INTEGER)
+ 17 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 18 = (NumberFormat$Field.INTEGER)
+ 19 = (NumberFormat$Field.INTEGER)
+ 20 = (NumberFormat$Field.INTEGER)
+ 21 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 22 = (NumberFormat$Field.INTEGER)
+ 23 = (NumberFormat$Field.INTEGER)
+ 24 = (NumberFormat$Field.INTEGER)
+ limits = (
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 0 end = 1 end2 = 25}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 1 end = 2}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 1 end = 2}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 5 end = 6}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 5 end = 6}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 9 end = 10}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 9 end = 10}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 13 end = 14}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 13 end = 14}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 17 end = 18}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 17 end = 18}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 21 end = 22}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 21 end = 22}
+ )
+ fieldPositions =
+ (
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 0 end = 25
+ }
+ {
+ fieldID = NumberFormat$Field.GROUPING_SEPARATOR
+ begin = 1 end = 2
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("#,###")
+ valueClass = java.lang.Long
+ valueArgs = ("-9223372036854775808")
+ }
+ {
+ length = 26
+ text = "-9,223,372,036,854,775,808"
+ 0 = (NumberFormat$Field.SIGN)
+ 1 = (NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 3 = (NumberFormat$Field.INTEGER)
+ 4 = (NumberFormat$Field.INTEGER)
+ 5 = (NumberFormat$Field.INTEGER)
+ 6 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 7 = (NumberFormat$Field.INTEGER)
+ 8 = (NumberFormat$Field.INTEGER)
+ 9 = (NumberFormat$Field.INTEGER)
+ 10 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 11 = (NumberFormat$Field.INTEGER)
+ 12 = (NumberFormat$Field.INTEGER)
+ 13 = (NumberFormat$Field.INTEGER)
+ 14 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 15 = (NumberFormat$Field.INTEGER)
+ 16 = (NumberFormat$Field.INTEGER)
+ 17 = (NumberFormat$Field.INTEGER)
+ 18 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 19 = (NumberFormat$Field.INTEGER)
+ 20 = (NumberFormat$Field.INTEGER)
+ 21 = (NumberFormat$Field.INTEGER)
+ 22 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 23 = (NumberFormat$Field.INTEGER)
+ 24 = (NumberFormat$Field.INTEGER)
+ 25 = (NumberFormat$Field.INTEGER)
+ limits = (
+ { attributes = (NumberFormat$Field.SIGN)
+ begin = 0 end = 1 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 1 end = 2 end2 = 26}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 2 end = 3}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 2 end = 3}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 6 end = 7}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 6 end = 7}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 10 end = 11}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 10 end = 11}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 14 end = 15}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 14 end = 15}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 18 end = 19}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 18 end = 19}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 22 end = 23}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 22 end = 23}
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = NumberFormat$Field.SIGN
+ begin = 0 end = 1
+ }
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 1 end = 26
+ }
+ {
+ fieldID = NumberFormat$Field.GROUPING_SEPARATOR
+ begin = 2 end = 3
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("#,###")
+ valueClass = java.util.concurrent.atomic.AtomicLong
+ valueArgs = ("-9223372036854775808")
+ }
+ {
+ length = 26
+ text = "-9,223,372,036,854,775,808"
+ 0 = (NumberFormat$Field.SIGN)
+ 1 = (NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 3 = (NumberFormat$Field.INTEGER)
+ 4 = (NumberFormat$Field.INTEGER)
+ 5 = (NumberFormat$Field.INTEGER)
+ 6 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 7 = (NumberFormat$Field.INTEGER)
+ 8 = (NumberFormat$Field.INTEGER)
+ 9 = (NumberFormat$Field.INTEGER)
+ 10 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 11 = (NumberFormat$Field.INTEGER)
+ 12 = (NumberFormat$Field.INTEGER)
+ 13 = (NumberFormat$Field.INTEGER)
+ 14 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 15 = (NumberFormat$Field.INTEGER)
+ 16 = (NumberFormat$Field.INTEGER)
+ 17 = (NumberFormat$Field.INTEGER)
+ 18 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 19 = (NumberFormat$Field.INTEGER)
+ 20 = (NumberFormat$Field.INTEGER)
+ 21 = (NumberFormat$Field.INTEGER)
+ 22 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 23 = (NumberFormat$Field.INTEGER)
+ 24 = (NumberFormat$Field.INTEGER)
+ 25 = (NumberFormat$Field.INTEGER)
+ limits = (
+ { attributes = (NumberFormat$Field.SIGN)
+ begin = 0 end = 1 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 1 end = 2 end2 = 26}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 2 end = 3}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 2 end = 3}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 6 end = 7}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 6 end = 7}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 10 end = 11}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 10 end = 11}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 14 end = 15}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 14 end = 15}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 18 end = 19}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 18 end = 19}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 22 end = 23}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 22 end = 23}
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = NumberFormat$Field.SIGN
+ begin = 0 end = 1
+ }
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 1 end = 26
+ }
+ {
+ fieldID = NumberFormat$Field.GROUPING_SEPARATOR
+ begin = 2 end = 3
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("#,###")
+ valueClass = java.util.concurrent.atomic.AtomicInteger
+ valueArgs = ("2147483647")
+ }
+ {
+ length = 13
+ text = "2,147,483,647"
+ 0 = (NumberFormat$Field.INTEGER)
+ 1 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 2 = (NumberFormat$Field.INTEGER)
+ 3 = (NumberFormat$Field.INTEGER)
+ 4 = (NumberFormat$Field.INTEGER)
+ 5 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 6 = (NumberFormat$Field.INTEGER)
+ 7 = (NumberFormat$Field.INTEGER)
+ 8 = (NumberFormat$Field.INTEGER)
+ 9 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 10 = (NumberFormat$Field.INTEGER)
+ 11 = (NumberFormat$Field.INTEGER)
+ 12 = (NumberFormat$Field.INTEGER)
+ limits = (
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 0 end = 1 end2 = 13}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 1 end = 2}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 1 end = 2}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 5 end = 6}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 5 end = 6}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 9 end = 10}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 9 end = 10}
+ )
+ fieldPositions =
+ (
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 0 end = 13
+ }
+ {
+ fieldID = NumberFormat$Field.GROUPING_SEPARATOR
+ begin = 1 end = 2
+ }
+ )
+ }
+
+ {
+ class = java.text.DecimalFormat
+ args = ("#,###")
+ valueClass = java.util.concurrent.atomic.AtomicInteger
+ valueArgs = ("-2147483648")
+ }
+ {
+ length = 14
+ text = "-2,147,483,648"
+ 0 = (NumberFormat$Field.SIGN)
+ 1 = (NumberFormat$Field.INTEGER)
+ 2 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 3 = (NumberFormat$Field.INTEGER)
+ 4 = (NumberFormat$Field.INTEGER)
+ 5 = (NumberFormat$Field.INTEGER)
+ 6 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 7 = (NumberFormat$Field.INTEGER)
+ 8 = (NumberFormat$Field.INTEGER)
+ 9 = (NumberFormat$Field.INTEGER)
+ 10 = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 11 = (NumberFormat$Field.INTEGER)
+ 12 = (NumberFormat$Field.INTEGER)
+ 13 = (NumberFormat$Field.INTEGER)
+ limits = (
+ { attributes = (NumberFormat$Field.SIGN)
+ begin = 0 end = 1 }
+ { attributes = (NumberFormat$Field.INTEGER)
+ begin = 1 end = 2 end2 = 14}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 2 end = 3}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 2 end = 3}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 6 end = 7}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 6 end = 7}
+ { attributes = (NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 10 end = 11}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 10 end = 11}
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = NumberFormat$Field.SIGN
+ begin = 0 end = 1
+ }
+ {
+ field = NumberFormat.INTEGER_FIELD
+ fieldID = NumberFormat$Field.INTEGER
+ begin = 1 end = 14
+ }
+ {
+ fieldID = NumberFormat$Field.GROUPING_SEPARATOR
+ begin = 2 end = 3
+ }
+ )
+ }
+ )
+}
diff --git a/jdk/test/java/text/Format/common/messageFormat.props b/jdk/test/java/text/Format/common/messageFormat.props
new file mode 100644
index 00000000000..c8aaeecfd32
--- /dev/null
+++ b/jdk/test/java/text/Format/common/messageFormat.props
@@ -0,0 +1,520 @@
+#
+# Copyright (c) 2000, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Test data for FormatIteratorTest
+
+{
+ tests =
+ (
+ {
+ class = java.text.MessageFormat
+ args = ("0={0} 1={1}")
+ valueClass = java.lang.reflect.Array
+ valueArgs = ("zero" "one")
+ }
+ {
+ length = 12
+ text = "0=zero 1=one"
+ 0 = ()
+ 1 = ()
+ 2 = (MessageFormat$Field.ARGUMENT)
+ 3 = (MessageFormat$Field.ARGUMENT)
+ 4 = (MessageFormat$Field.ARGUMENT)
+ 5 = (MessageFormat$Field.ARGUMENT)
+ 6 = ()
+ 7 = ()
+ 8 = ()
+ 9 = (MessageFormat$Field.ARGUMENT)
+ 10 = (MessageFormat$Field.ARGUMENT)
+ 11 = (MessageFormat$Field.ARGUMENT)
+ limits = ( { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 2 end = 6}
+ { attributes = ()
+ begin = 0 begin2 = 0 end = 2 end2 = 12}
+ { attributes = ()
+ begin = 6 begin2 = 0 end = 9 end2 = 12}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 9 end = 12}
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = MessageFormat$Field.ARGUMENT
+ begin = 2 end = 6
+ }
+ )
+ }
+
+ {
+ class = java.text.MessageFormat
+ args = ("0={0} 1={1} 0={0}")
+ valueClass = java.lang.reflect.Array
+ valueArgs = ("ze" "on")
+ }
+ {
+ length = 14
+ text = "0=ze 1=on 0=ze"
+ 0 = ()
+ 1 = ()
+ 2 = (MessageFormat$Field.ARGUMENT)
+ 3 = (MessageFormat$Field.ARGUMENT)
+ 4 = ()
+ 5 = ()
+ 6 = ()
+ 7 = (MessageFormat$Field.ARGUMENT)
+ 8 = (MessageFormat$Field.ARGUMENT)
+ 9 = ()
+ 10 = ()
+ 11 = ()
+ 12 = (MessageFormat$Field.ARGUMENT)
+ 13 = (MessageFormat$Field.ARGUMENT)
+ limits = (
+ { attributes = ()
+ begin = 0 end = 2 end2 = 14}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 2 end = 4}
+ { attributes = ()
+ begin = 4 begin2 = 0 end = 7 end2 = 14}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 7 end = 9}
+ { attributes = ()
+ begin = 9 begin2 = 0 end = 12 end2 = 14}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 12 end = 14}
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = MessageFormat$Field.ARGUMENT
+ begin = 2 end = 4
+ }
+ )
+ }
+
+ {
+ class = java.text.MessageFormat
+ args = ("0={0,date} 1={1,number}")
+ valueClass = java.lang.reflect.Array
+ valueArgs = ((java.util.Date ("5/23/2001")) (Integer ("20122")))
+ }
+ {
+ length = 23
+ text = "0=May 23, 2001 1=20,122"
+ 0 = ()
+ 1 = ()
+ 2 = (MessageFormat$Field.ARGUMENT DateFormat$Field.MONTH)
+ 3 = (MessageFormat$Field.ARGUMENT DateFormat$Field.MONTH)
+ 4 = (MessageFormat$Field.ARGUMENT DateFormat$Field.MONTH)
+ 5 = (MessageFormat$Field.ARGUMENT)
+ 6 = (MessageFormat$Field.ARGUMENT DateFormat$Field.DAY_OF_MONTH)
+ 7 = (MessageFormat$Field.ARGUMENT DateFormat$Field.DAY_OF_MONTH)
+ 8 = (MessageFormat$Field.ARGUMENT)
+ 9 = (MessageFormat$Field.ARGUMENT)
+ 10 = (MessageFormat$Field.ARGUMENT DateFormat$Field.YEAR)
+ 11 = (MessageFormat$Field.ARGUMENT DateFormat$Field.YEAR)
+ 12 = (MessageFormat$Field.ARGUMENT DateFormat$Field.YEAR)
+ 13 = (MessageFormat$Field.ARGUMENT DateFormat$Field.YEAR)
+ 14 = ()
+ 15 = ()
+ 16 = ()
+ 17 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 18 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 19 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 20 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 21 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 22 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ limits = (
+ { attributes = ()
+ begin = 0 end = 2 end2 = 23}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 2 end = 5 end2 = 14}
+ { attributes = (MessageFormat$Field.ARGUMENT
+ DateFormat$Field.MONTH)
+ begin = 2 end = 5}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 5 begin2 = 2 end = 6 end2 = 14}
+ { attributes = (DateFormat$Field.DAY_OF_MONTH)
+ begin = 6 end = 8}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 8 begin2 = 2 end = 10 end2 = 14}
+ { attributes = ()
+ begin = 14 begin2 = 0 end = 17 end2 = 23}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 17 end = 19 end2 = 23}
+ { attributes = (MessageFormat$Field.ARGUMENT
+ NumberFormat$Field.INTEGER)
+ begin = 17 end = 19 end2 = 23}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 19 end = 20 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 20 begin2 = 17 end = 23}
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = MessageFormat$Field.ARGUMENT
+ begin = 2 end = 14
+ }
+ )
+ }
+
+ {
+ class = java.text.MessageFormat
+ args = ("0={0,date} 1={1,number}")
+ valueClass = java.lang.reflect.Array
+ valueArgs = ((java.util.Date ("1/22/2003")) (java.math.BigInteger ("12345678901234567890123456789012345")))
+ }
+ {
+ length = 63
+ text = "0=Jan 22, 2003 1=12,345,678,901,234,567,890,123,456,789,012,345"
+ 0 = ()
+ 1 = ()
+ 2 = (MessageFormat$Field.ARGUMENT DateFormat$Field.MONTH)
+ 3 = (MessageFormat$Field.ARGUMENT DateFormat$Field.MONTH)
+ 4 = (MessageFormat$Field.ARGUMENT DateFormat$Field.MONTH)
+ 5 = (MessageFormat$Field.ARGUMENT)
+ 6 = (MessageFormat$Field.ARGUMENT DateFormat$Field.DAY_OF_MONTH)
+ 7 = (MessageFormat$Field.ARGUMENT DateFormat$Field.DAY_OF_MONTH)
+ 8 = (MessageFormat$Field.ARGUMENT)
+ 9 = (MessageFormat$Field.ARGUMENT)
+ 10 = (MessageFormat$Field.ARGUMENT DateFormat$Field.YEAR)
+ 11 = (MessageFormat$Field.ARGUMENT DateFormat$Field.YEAR)
+ 12 = (MessageFormat$Field.ARGUMENT DateFormat$Field.YEAR)
+ 13 = (MessageFormat$Field.ARGUMENT DateFormat$Field.YEAR)
+ 14 = ()
+ 15 = ()
+ 16 = ()
+ 17 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 18 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 19 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 20 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 21 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 22 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 23 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 24 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 25 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 26 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 27 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 28 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 29 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 30 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 31 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 32 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 33 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 34 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 35 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 36 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 37 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 38 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 39 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 40 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 41 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 42 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 43 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 44 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 45 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 46 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 47 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 48 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 49 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 50 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 51 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 52 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 53 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 54 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 55 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 56 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 57 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 58 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 59 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 60 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 61 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 62 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ limits = (
+ { attributes = ()
+ begin = 0 end = 2 end2 = 63}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 2 end = 5 end2 = 14}
+ { attributes = (MessageFormat$Field.ARGUMENT
+ DateFormat$Field.MONTH)
+ begin = 2 end = 5}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 5 begin2 = 2 end = 6 end2 = 14}
+ { attributes = (DateFormat$Field.DAY_OF_MONTH)
+ begin = 6 end = 8}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 8 begin2 = 2 end = 10 end2 = 14}
+ { attributes = ()
+ begin = 14 begin2 = 0 end = 17 end2 = 63}
+ { attributes = (MessageFormat$Field.ARGUMENT
+ NumberFormat$Field.INTEGER)
+ begin = 17 end = 19 end2 = 63}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 19 end = 20 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 20 begin2 = 17 end = 23 end2 = 63}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 23 end = 24 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 24 begin2 = 17 end = 27 end2 = 63}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 27 end = 28 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 28 begin2 = 17 end = 31 end2 = 63}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 31 end = 32 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 32 begin2 = 17 end = 35 end2 = 63}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 35 end = 36 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 36 begin2 = 17 end = 39 end2 = 63}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 39 end = 40 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 40 begin2 = 17 end = 43 end2 = 63}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 43 end = 44 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 44 begin2 = 17 end = 47 end2 = 63}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 47 end = 48 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 48 begin2 = 17 end = 51 end2 = 63}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 51 end = 52 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 52 begin2 = 17 end = 55 end2 = 63}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 55 end = 56 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 56 begin2 = 17 end = 59 end2 = 63}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 59 end = 60 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 60 begin2 = 17 end = 63}
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = MessageFormat$Field.ARGUMENT
+ begin = 2 end = 14
+ }
+ )
+ }
+
+ {
+ class = java.text.MessageFormat
+ args = ("0={0,date} 1={1,number}")
+ valueClass = java.lang.reflect.Array
+ valueArgs = ((java.util.Date ("1/26/2003")) (java.math.BigDecimal ("-12345678901234567890.1239")))
+ }
+ {
+ length = 48
+ text = "0=Jan 26, 2003 1=-12,345,678,901,234,567,890.124"
+ 0 = ()
+ 1 = ()
+ 2 = (MessageFormat$Field.ARGUMENT DateFormat$Field.MONTH)
+ 3 = (MessageFormat$Field.ARGUMENT DateFormat$Field.MONTH)
+ 4 = (MessageFormat$Field.ARGUMENT DateFormat$Field.MONTH)
+ 5 = (MessageFormat$Field.ARGUMENT)
+ 6 = (MessageFormat$Field.ARGUMENT DateFormat$Field.DAY_OF_MONTH)
+ 7 = (MessageFormat$Field.ARGUMENT DateFormat$Field.DAY_OF_MONTH)
+ 8 = (MessageFormat$Field.ARGUMENT)
+ 9 = (MessageFormat$Field.ARGUMENT)
+ 10 = (MessageFormat$Field.ARGUMENT DateFormat$Field.YEAR)
+ 11 = (MessageFormat$Field.ARGUMENT DateFormat$Field.YEAR)
+ 12 = (MessageFormat$Field.ARGUMENT DateFormat$Field.YEAR)
+ 13 = (MessageFormat$Field.ARGUMENT DateFormat$Field.YEAR)
+ 14 = ()
+ 15 = ()
+ 16 = ()
+ 17 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.SIGN)
+ 18 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 19 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 20 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 21 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 22 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 23 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 24 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 25 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 26 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 27 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 28 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 29 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 30 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 31 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 32 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 33 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 34 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 35 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 36 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 37 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 38 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 39 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 40 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER
+ NumberFormat$Field.GROUPING_SEPARATOR)
+ 41 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 42 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 43 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.INTEGER)
+ 44 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.DECIMAL_SEPARATOR)
+ 45 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.FRACTION)
+ 46 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.FRACTION)
+ 47 = (MessageFormat$Field.ARGUMENT NumberFormat$Field.FRACTION)
+ limits = (
+ { attributes = ()
+ begin = 0 end = 2 end2 = 48}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 2 end = 5 end2 = 14}
+ { attributes = (MessageFormat$Field.ARGUMENT
+ DateFormat$Field.MONTH)
+ begin = 2 end = 5}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 5 begin2 = 2 end = 6 end2 = 14}
+ { attributes = (DateFormat$Field.DAY_OF_MONTH)
+ begin = 6 end = 8}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 8 begin2 = 2 end = 10 end2 = 14}
+ { attributes = ()
+ begin = 14 begin2 = 0 end = 17 end2 = 48}
+
+ { attributes = (NumberFormat$Field.SIGN)
+ begin = 17 end = 18 }
+ { attributes = (MessageFormat$Field.ARGUMENT
+ NumberFormat$Field.INTEGER)
+ begin = 18 end = 20 end2 = 44}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 20 end = 21 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 21 begin2 = 18 end = 24 end2 = 44}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 24 end = 25 }
+
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 25 begin2 = 18 end = 28 end2 = 44}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 28 end = 29 }
+
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 29 begin2 = 18 end = 32 end2 = 44}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 32 end = 33 }
+
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 33 begin2 = 18 end = 36 end2 = 44}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 36 end = 37 }
+
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 37 begin2 = 18 end = 40 end2 = 44}
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 40 end = 41 }
+ { attributes = (NumberFormat$Field.INTEGER
+ MessageFormat$Field.ARGUMENT)
+ begin = 41 begin2 = 18 end = 44 end2 = 44}
+
+ { attributes = (NumberFormat$Field.GROUPING_SEPARATOR)
+ begin = 44 begin2 = 41 end = 45 end2 = 48}
+
+ { attributes = (NumberFormat$Field.FRACTION
+ MessageFormat$Field.ARGUMENT)
+ begin = 45 end = 48}
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = MessageFormat$Field.ARGUMENT
+ begin = 2 end = 14
+ }
+ )
+ }
+
+ {
+ class = java.text.MessageFormat
+ args = ("0={0,choice,-1#neg| 0#zero | 1#more}xx")
+ valueClass = java.lang.reflect.Array
+ valueArgs = ((Integer ("-11")))
+ }
+ {
+ length = 7
+ text = "0=negxx"
+ 0 = ()
+ 1 = ()
+ 2 = (MessageFormat$Field.ARGUMENT)
+ 3 = (MessageFormat$Field.ARGUMENT)
+ 4 = (MessageFormat$Field.ARGUMENT)
+ 5 = ()
+ 6 = ()
+ limits = (
+ { attributes = ()
+ begin = 0 end = 2 end2 = 7}
+ { attributes = (MessageFormat$Field.ARGUMENT)
+ begin = 2 end = 5}
+ { attributes = ()
+ begin = 5 begin2 = 0 end = 7}
+ )
+ fieldPositions =
+ (
+ {
+ fieldID = MessageFormat$Field.ARGUMENT
+ begin = 2 end = 5
+ }
+ )
+ }
+ )
+}
+
diff --git a/jdk/test/java/text/testlib/HexDumpReader.java b/jdk/test/java/text/testlib/HexDumpReader.java
new file mode 100644
index 00000000000..31a820d04d4
--- /dev/null
+++ b/jdk/test/java/text/testlib/HexDumpReader.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * HexDumpReader provides utility methods to read a hex dump text file
+ * and convert to an InputStream. The format supported by the methods
+ * can be generated by the following command.
+ *
+ * $ od -vw -t x1 foo | sed -r -e 's/^[0-9]+ ?//' -e 's/ //g' -e '/^$/d'
+ */
+public class HexDumpReader {
+ public static InputStream getStreamFromHexDump(String fileName) {
+ return getStreamFromHexDump(new File(System.getProperty("test.src", "."),
+ fileName));
+ }
+
+ public static InputStream getStreamFromHexDump(File hexFile) {
+ ByteArrayBuilder bab = new ByteArrayBuilder();
+ int lineNo = 0;
+ try (BufferedReader reader
+ = new BufferedReader(new InputStreamReader(new FileInputStream(hexFile),
+ "us-ascii"))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ lineNo++;
+ line = line.trim();
+ // Skip blank and comment lines.
+ if (line.length() == 0) {
+ continue;
+ }
+ int x = line.indexOf('#');
+ if (x == 0) {
+ continue;
+ }
+ if (x > 0) {
+ line = line.substring(0, x).trim();
+ }
+ int len = line.length();
+ for (int i = 0; i < len; i += 2) {
+ bab.put((byte)Integer.parseInt(line, i, i + 2, 16));
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(hexFile.getName() + ":error:" + lineNo + ": " + e, e);
+ }
+ return new ByteArrayInputStream(bab.toArray());
+ }
+
+
+ private static class ByteArrayBuilder {
+ private static final int BUFFER_SIZE = 4096;
+
+ private int size;
+ private List bytes;
+ private byte[] current;
+ private int offset;
+
+ ByteArrayBuilder() {
+ bytes = new ArrayList<>();
+ current = new byte[BUFFER_SIZE];
+ }
+
+ void put(byte b) {
+ if (offset == BUFFER_SIZE) {
+ bytes.add(current);
+ current = new byte[BUFFER_SIZE];
+ offset = 0;
+ }
+ current[offset++] = b;
+ size++;
+ }
+
+ byte[] toArray() {
+ byte[] buf = new byte[size];
+ int ptr = 0;
+ for (byte[] ba : bytes) {
+ System.arraycopy(ba, 0, buf, ptr, ba.length);
+ ptr += ba.length;
+ }
+ System.arraycopy(current, 0, buf, ptr, offset);
+ assert ptr + offset == size;
+ return buf;
+ }
+ }
+
+}
diff --git a/jdk/test/java/text/testlib/IntlTest.java b/jdk/test/java/text/testlib/IntlTest.java
new file mode 100644
index 00000000000..d8ae8572f30
--- /dev/null
+++ b/jdk/test/java/text/testlib/IntlTest.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 1998, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+/**
+ * IntlTest is a base class for tests that can be run conveniently from
+ * the command line as well as under the Java test harness.
+ *
+ * Sub-classes implement a set of public void methods named "Test*" or
+ * "test*" with no arguments. Each of these methods performs some
+ * test. Test methods should indicate errors by calling either err() or
+ * errln(). This will increment the errorCount field and may optionally
+ * print a message to the log. Debugging information may also be added to
+ * the log via the log and logln methods. These methods will add their
+ * arguments to the log only if the test is being run in verbose mode.
+ */
+public abstract class IntlTest {
+
+ //------------------------------------------------------------------------
+ // Everything below here is boilerplate code that makes it possible
+ // to add a new test by simply adding a method to an existing class.
+ //------------------------------------------------------------------------
+
+ protected IntlTest() {
+ // Populate testMethods with all the test methods.
+ Method[] methods = getClass().getDeclaredMethods();
+ for (Method method : methods) {
+ if (Modifier.isPublic(method.getModifiers())
+ && method.getReturnType() == void.class
+ && method.getParameterCount() == 0) {
+ String name = method.getName();
+ if (name.length() > 4) {
+ if (name.startsWith("Test") || name.startsWith("test")) {
+ testMethods.put(name, method);
+ }
+ }
+ }
+ }
+ }
+
+ protected void run(String[] args) throws Exception
+ {
+ // Set up the log and reference streams. We use PrintWriters in order to
+ // take advantage of character conversion. The JavaEsc converter will
+ // convert Unicode outside the ASCII range to Java's \\uxxxx notation.
+ log = new PrintWriter(System.out, true);
+
+ // Parse the test arguments. They can be either the flag
+ // "-verbose" or names of test methods. Create a list of
+ // tests to be run.
+ List testsToRun = new ArrayList<>(args.length);
+ for (String arg : args) {
+ switch (arg) {
+ case "-verbose":
+ verbose = true;
+ break;
+ case "-prompt":
+ prompt = true;
+ break;
+ case "-nothrow":
+ nothrow = true;
+ break;
+ default:
+ Method m = testMethods.get(arg);
+ if (m == null) {
+ System.out.println("Method " + arg + ": not found");
+ usage();
+ return;
+ }
+ testsToRun.add(m);
+ break;
+ }
+ }
+
+ // If no test method names were given explicitly, run them all.
+ if (testsToRun.isEmpty()) {
+ testsToRun.addAll(testMethods.values());
+ }
+
+ System.out.println(getClass().getName() + " {");
+ indentLevel++;
+
+ // Run the list of tests given in the test arguments
+ for (Method testMethod : testsToRun) {
+ int oldCount = errorCount;
+
+ writeTestName(testMethod.getName());
+
+ try {
+ testMethod.invoke(this, new Object[0]);
+ } catch (IllegalAccessException e) {
+ errln("Can't acces test method " + testMethod.getName());
+ } catch (InvocationTargetException e) {
+ errln("Uncaught exception thrown in test method "
+ + testMethod.getName());
+ e.getTargetException().printStackTrace(this.log);
+ }
+ writeTestResult(errorCount - oldCount);
+ }
+ indentLevel--;
+ writeTestResult(errorCount);
+
+ if (prompt) {
+ System.out.println("Hit RETURN to exit...");
+ try {
+ System.in.read();
+ } catch (IOException e) {
+ System.out.println("Exception: " + e.toString() + e.getMessage());
+ }
+ }
+ if (nothrow) {
+ System.exit(errorCount);
+ }
+ }
+
+ /**
+ * Adds the given message to the log if we are in verbose mode.
+ */
+ protected void log(String message) {
+ logImpl(message, false);
+ }
+
+ protected void logln(String message) {
+ logImpl(message, true);
+ }
+
+ protected void logln() {
+ logImpl(null, true);
+ }
+
+ private void logImpl(String message, boolean newline) {
+ if (verbose) {
+ if (message != null) {
+ indent(indentLevel + 1);
+ log.print(message);
+ }
+ if (newline) {
+ log.println();
+ }
+ }
+ }
+
+ protected void err(String message) {
+ errImpl(message, false);
+ }
+
+ protected void errln(String message) {
+ errImpl(message, true);
+ }
+
+ private void errImpl(String message, boolean newline) {
+ errorCount++;
+ indent(indentLevel + 1);
+ log.print(message);
+ if (newline) {
+ log.println();
+ }
+ log.flush();
+
+ if (!nothrow) {
+ throw new RuntimeException(message);
+ }
+ }
+
+ protected int getErrorCount() {
+ return errorCount;
+ }
+
+ protected void writeTestName(String testName) {
+ indent(indentLevel);
+ log.print(testName);
+ log.flush();
+ needLineFeed = true;
+ }
+
+ protected void writeTestResult(int count) {
+ if (!needLineFeed) {
+ indent(indentLevel);
+ log.print("}");
+ }
+ needLineFeed = false;
+
+ if (count != 0) {
+ log.println(" FAILED");
+ } else {
+ log.println(" Passed");
+ }
+ }
+
+ /*
+ * Returns a spece-delimited hex String.
+ */
+ protected static String toHexString(String s) {
+ StringBuilder sb = new StringBuilder(" ");
+
+ for (int i = 0; i < s.length(); i++) {
+ sb.append(Integer.toHexString(s.charAt(i)));
+ sb.append(' ');
+ }
+
+ return sb.toString();
+ }
+
+ private void indent(int distance) {
+ if (needLineFeed) {
+ log.println(" {");
+ needLineFeed = false;
+ }
+ log.print(SPACES.substring(0, distance * 2));
+ }
+
+ /**
+ * Print a usage message for this test class.
+ */
+ void usage() {
+ System.out.println(getClass().getName() +
+ ": [-verbose] [-nothrow] [-prompt] [test names]");
+
+ System.out.println(" Available test names:");
+ for (String methodName : testMethods.keySet()) {
+ System.out.println("\t" + methodName);
+ }
+ }
+
+ private boolean prompt;
+ private boolean nothrow;
+ protected boolean verbose;
+
+ private PrintWriter log;
+ private int indentLevel;
+ private boolean needLineFeed;
+ private int errorCount;
+
+ private final Map testMethods = new LinkedHashMap<>();
+
+ private static final String SPACES = " ";
+}
diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java b/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java
index d1092d15ee6..c86805f9bfe 100644
--- a/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java
+++ b/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java
@@ -442,28 +442,44 @@ public class TCKIsoFields {
}
//-----------------------------------------------------------------------
- // range refinedby
+ // rangeRefinedBy
//-----------------------------------------------------------------------
@DataProvider(name="isofields")
Object[][] data_isofields() {
return new Object[][] {
- {IsoFields.DAY_OF_QUARTER},
- {IsoFields.QUARTER_OF_YEAR},
- {IsoFields.WEEK_OF_WEEK_BASED_YEAR},
- {IsoFields.WEEK_BASED_YEAR},
+ {IsoFields.DAY_OF_QUARTER, 49, ValueRange.of(1, 91)},
+ {IsoFields.QUARTER_OF_YEAR, 2, ValueRange.of(1, 4)},
+ {IsoFields.WEEK_OF_WEEK_BASED_YEAR, 20, ValueRange.of(1, 52)},
+ {IsoFields.WEEK_BASED_YEAR, 2016, ValueRange.of(LocalDate.MIN.getYear(),
+ LocalDate.MAX.getYear())},
};
}
@Test(dataProvider = "isofields")
- public void test_isofields_rangerefinedby(TemporalField field) {
- field.rangeRefinedBy(LocalDate.now());
+ public void test_isofields_rangerefinedby(TemporalField field, int value, ValueRange valueRange) {
+ LocalDate date = LocalDate.of(2016, 5, 19);
+ assertEquals(field.rangeRefinedBy(date), valueRange);
}
@Test(dataProvider = "isofields", expectedExceptions = UnsupportedTemporalTypeException.class)
- public void test_nonisofields_rangerefinedby(TemporalField field) {
+ public void test_nonisofields_rangerefinedby(TemporalField field, int value, ValueRange valueRange) {
field.rangeRefinedBy(ThaiBuddhistDate.now());
}
+ //-----------------------------------------------------------------------
+ // getFrom
+ //-----------------------------------------------------------------------
+ @Test(dataProvider = "isofields")
+ public void test_isofields_getFrom(TemporalField field, int value, ValueRange valueRange) {
+ LocalDate date = LocalDate.of(2016, 5, 19);
+ assertEquals(field.getFrom(date), value);
+ }
+
+ @Test(dataProvider = "isofields", expectedExceptions = UnsupportedTemporalTypeException.class)
+ public void test_nonisofields_getFrom(TemporalField field, int value, ValueRange valueRange) {
+ field.getFrom(ThaiBuddhistDate.now());
+ }
+
//-----------------------------------------------------------------------
public void test_loop() {
// loop round at least one 400 year cycle, including before 1970
diff --git a/jdk/test/java/util/Calendar/BuddhistCalendarTest.java b/jdk/test/java/util/Calendar/BuddhistCalendarTest.java
new file mode 100644
index 00000000000..8d6a5fc3466
--- /dev/null
+++ b/jdk/test/java/util/Calendar/BuddhistCalendarTest.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4817812 4847186 4956227 4956479
+ * @summary Confirm that BuddhistCalendar's add(), roll() and toString() work correctly with Buddhist Era years.
+ */
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import static java.util.Calendar.*;
+
+public class BuddhistCalendarTest {
+
+ private static final Locale THAI_LOCALE = new Locale("th", "TH");
+
+ public static void main(String[] args) {
+ testAddRoll();
+ testToString();
+ testException();
+ testLeastMax();
+ }
+
+ /**
+ * 4817812
+ */
+ static void testAddRoll() {
+ Calendar cal;
+ int base, year;
+
+ /*
+ * Test: BuddhistCalendar.add(YEAR)
+ */
+ cal = getBuddhistCalendar();
+ base = cal.get(YEAR);
+ cal.add(YEAR, 1);
+ year = cal.get(YEAR);
+ check(year, base+1, "add(+YEAR)");
+
+ cal = getBuddhistCalendar();
+ base = cal.get(YEAR);
+ cal.add(YEAR, -3);
+ year = cal.get(YEAR);
+ check(year, base-3, "add(-YEAR)");
+
+ /*
+ * Test BuddhistCalendar.add(MONTH)
+ */
+ cal = getBuddhistCalendar();
+ base = cal.get(YEAR);
+ cal.set(MONTH, DECEMBER);
+ cal.add(MONTH, 2);
+ year = cal.get(YEAR);
+ check(year, base+1, "add(+MONTH)");
+
+ cal = getBuddhistCalendar();
+ base = cal.get(YEAR);
+ cal.set(MONTH, FEBRUARY);
+ cal.add(MONTH, -4);
+ year = cal.get(YEAR);
+ check(year, base-1, "add(-MONTH)");
+
+ /*
+ * Test BuddhistCalendar.roll(YEAR)
+ */
+ cal = getBuddhistCalendar();
+ base = cal.get(YEAR);
+ cal.roll(YEAR, 2);
+ year = cal.get(YEAR);
+ check(year, base+2, "roll(+YEAR)");
+
+ cal = getBuddhistCalendar();
+ base = cal.get(YEAR);
+ cal.roll(YEAR, -4);
+ year = cal.get(YEAR);
+ check(year, base-4, "roll(-YEAR)");
+
+ /*
+ * Test BuddhistCalendar.roll(WEEK_OF_YEAR)
+ */
+ cal = getBuddhistCalendar();
+ cal.set(YEAR, 2543); // A.D.2000
+ cal.set(MONTH, DECEMBER);
+ cal.set(DATE, 31);
+ base = cal.get(YEAR);
+ check(base, 2543, "roll(+WEEK_OF_YEAR)");
+ cal.roll(WEEK_OF_YEAR, 10);
+ year = cal.get(YEAR);
+ check(year, base, "roll(+WEEK_OF_YEAR)");
+
+ cal = getBuddhistCalendar();
+ cal.set(YEAR, 2543); // A.D.2000
+ cal.set(MONTH, JANUARY);
+ cal.set(DATE, 1);
+ base = cal.get(YEAR);
+ check(base, 2543, "roll(+WEEK_OF_YEAR)");
+ cal.roll(WEEK_OF_YEAR, -10);
+ year = cal.get(YEAR);
+ check(year, base, "roll(-WEEK_OF_YEAR)");
+
+ /*
+ * Test Calendar.set(year, month, date)
+ */
+ cal = getBuddhistCalendar();
+ base = cal.get(YEAR);
+ cal.set(3001, APRIL, 10);
+ year = cal.get(YEAR);
+ check(year, 3001, "set(year, month, date)");
+
+ /*
+ * Test Calendar.set(year, month, date, hour, minute)
+ */
+ cal = getBuddhistCalendar();
+ base = cal.get(YEAR);
+ cal.set(3020, MAY, 20, 9, 10);
+ year = cal.get(YEAR);
+ check(year, 3020, "set(year, month, date, hour, minute)");
+
+ /*
+ * Test Calendar.set(year, month, date, hour, minute, second)
+ */
+ cal = getBuddhistCalendar();
+ base = cal.get(YEAR);
+ cal.set(3120, MAY, 20, 9, 10, 52);
+ year = cal.get(YEAR);
+ check(year, 3120, "set(year, month, date, hour, minute, second)");
+
+ /*
+ * Test BuddhistCalendar.getActualMaximum(YEAR);
+ * set(YEAR)/get(YEAR) in this method doesn't affect the real
+ * YEAR value because a clone is used with set()&get().
+ */
+ cal = getBuddhistCalendar();
+ base = cal.get(YEAR);
+ int limit = cal.getActualMaximum(YEAR);
+ year = cal.get(YEAR);
+ check(year, base, "BuddhistCalendar.getActualMaximum(YEAR)");
+
+ /*
+ * Test BuddhistCalendar.getActualMinimum(YEAR);
+ * This doesn't call set(YEAR) nor get(YEAR), though.
+ */
+ cal = getBuddhistCalendar();
+ base = cal.get(YEAR);
+ limit = cal.getActualMinimum(YEAR);
+ year = cal.get(YEAR);
+ check(year, base, "BuddhistCalendar.getActualMinimum(YEAR)");
+ }
+
+ /**
+ * 4847186: BuddhistCalendar: toString() returns Gregorian year
+ */
+ static void testToString() {
+ Calendar cal = getBuddhistCalendar();
+ int year = cal.get(YEAR);
+ String s = cal.toString();
+ String y = s.replaceAll(".+,YEAR=(\\d+),.+", "$1");
+ if (Integer.parseInt(y) != year) {
+ throw new RuntimeException("toString(): wrong year value: got " + y
+ + ", expected " + year);
+ }
+ }
+
+ /**
+ * 4956479: BuddhistCalendar methods may return wrong values after exception
+ */
+ static void testException() {
+ Calendar cal = getBuddhistCalendar();
+ int year = cal.get(YEAR);
+ boolean exceptionOccurred = false;
+ try {
+ cal.add(100, +1); // cause exception
+ } catch (Exception e) {
+ exceptionOccurred = true;
+ }
+ if (!exceptionOccurred) {
+ throw new RuntimeException("testException: test case failed: no exception thrown");
+ }
+ int year2 = cal.get(YEAR);
+ if (year2 != year) {
+ throw new RuntimeException("wrong year value after exception: got " + year2
+ + ", expected " + year);
+ }
+ }
+
+ /**
+ * 4956227: getLeastMaximum(WEEK_OF_MONTH) return diff. val. for Greg. and Buddhist Calendar
+ */
+ static void testLeastMax() {
+ Calendar bc = getBuddhistCalendar();
+ // Specify THAI_LOCALE to get the same params for WEEK
+ // calculations (6904680).
+ Calendar gc = new GregorianCalendar(THAI_LOCALE);
+ for (int f = 0; f < Calendar.FIELD_COUNT; f++) {
+ if (f == ERA || f == YEAR) {
+ continue;
+ }
+ int bn = bc.getLeastMaximum(f);
+ int gn = gc.getLeastMaximum(f);
+ if (bn != gn) {
+ throw new RuntimeException("inconsistent Least Max value for " + Koyomi.getFieldName(f)
+ + ": Buddhist=" + bn
+ + ": Gregorian=" + gn);
+ }
+ }
+ }
+
+ /**
+ * @return a BuddhistCalendar
+ */
+ static Calendar getBuddhistCalendar() {
+ return Calendar.getInstance(THAI_LOCALE);
+ }
+
+ static void check(int got, int expected, String s) {
+ if (got != expected) {
+ throw new RuntimeException("Failed: " +
+ s + ": got:" + got + ", expected:" + expected);
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/Bug4302966.java b/jdk/test/java/util/Calendar/Bug4302966.java
new file mode 100644
index 00000000000..6c3b9c3d60e
--- /dev/null
+++ b/jdk/test/java/util/Calendar/Bug4302966.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2001, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4302966
+ * @summary In Czech Republic first day of week is Monday not Sunday
+ */
+
+import java.util.Calendar;
+import java.util.Locale;
+
+public class Bug4302966 {
+
+ public static void main(String[] args) {
+ Calendar czechCalendar = Calendar.getInstance(new Locale("cs"));
+ int firstDayOfWeek = czechCalendar.getFirstDayOfWeek();
+ if (firstDayOfWeek != Calendar.MONDAY) {
+ throw new RuntimeException();
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/Bug4766302.java b/jdk/test/java/util/Calendar/Bug4766302.java
new file mode 100644
index 00000000000..42df92b7e16
--- /dev/null
+++ b/jdk/test/java/util/Calendar/Bug4766302.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2002, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4766302
+ * @summary Make sure that computeTime call doesn't reset the isTimeSet value.
+ */
+
+import java.util.GregorianCalendar;
+
+public class Bug4766302 {
+
+ static class MyCalendar extends GregorianCalendar {
+ boolean isTimeStillSet() {
+ return isTimeSet;
+ }
+
+ protected void computeTime() {
+ super.computeTime();
+ }
+ }
+
+ public static void main(String[] args) {
+ MyCalendar cal = new MyCalendar();
+ cal.computeTime();
+ if (!cal.isTimeStillSet()) {
+ throw new RuntimeException("computeTime() call reset isTimeSet.");
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/Bug4851640.java b/jdk/test/java/util/Calendar/Bug4851640.java
new file mode 100644
index 00000000000..4f5add37679
--- /dev/null
+++ b/jdk/test/java/util/Calendar/Bug4851640.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4851640
+ * @summary Make sure not to set UNSET fields to COMPUTED after time calculation.
+ */
+
+import java.util.GregorianCalendar;
+import static java.util.Calendar.*;
+
+public class Bug4851640 {
+
+ public static void main(String args[]) {
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.clear();
+ cal.set(YEAR, 2003);
+ long t = cal.getTime().getTime();
+
+ // For the time calculation, the MONTH and DAY_OF_MONTH fields
+ // (with the default values) have been used for determining
+ // the date. However, both the MONTH and DAY_OF_MONTH fields
+ // should be kept UNSET after the time calculation.
+ if (cal.isSet(MONTH) || cal.isSet(DAY_OF_MONTH)) {
+ throw new RuntimeException("After getTime(): MONTH field=" + cal.isSet(MONTH)
+ + ", DAY_OF_MONTH field=" + cal.isSet(DAY_OF_MONTH));
+ }
+
+ // After calling get() for any field, all field values are
+ // recalculated and their field states are set to
+ // COMPUTED. isSet() must return true.
+ int y = cal.get(YEAR);
+ if (!(cal.isSet(MONTH) && cal.isSet(DAY_OF_MONTH))) {
+ throw new RuntimeException("After get(): MONTH field=" + cal.isSet(MONTH)
+ + ", DAY_OF_MONTH field=" + cal.isSet(DAY_OF_MONTH));
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/Bug4958050.java b/jdk/test/java/util/Calendar/Bug4958050.java
new file mode 100644
index 00000000000..dfd627cda6f
--- /dev/null
+++ b/jdk/test/java/util/Calendar/Bug4958050.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4958050
+ * @summary Make sure that add() and roll() handle time zone offset changes (both raw and DST) correctly.
+ */
+
+import java.util.Locale;
+import java.util.TimeZone;
+import static java.util.Calendar.*;
+
+public class Bug4958050 {
+ static int errorCount = 0;
+
+ public static void main(String[] args) {
+ // All the test cases depend on historical GMT offset changes
+ // of Asia/Novosibirsk.
+ Koyomi cal = new Koyomi(TimeZone.getTimeZone("Asia/Novosibirsk"), Locale.US);
+ System.out.println("Time zone = " + cal.getTimeZone().getID());
+
+ // Test the week fields
+ int[] weekFields = { WEEK_OF_YEAR, WEEK_OF_MONTH, DAY_OF_WEEK_IN_MONTH };
+ for (int i = 0; i < weekFields.length; i++) {
+ int field = weekFields[i];
+ // add()
+ cal.clear();
+ cal.set(1919, DECEMBER, 14-7, 23, 50, 00);
+ cal.add(weekFields[i], +1);
+ if (!cal.checkDate(1919, DECEMBER, 14)) {
+ error("1919/12/07: add("+cal.getFieldName(weekFields[i])+", +1)\n"
+ + cal.getMessage()+" " + cal.toDateTimeString());
+ }
+ cal.clear();
+ cal.set(1930, JUNE, 21-7);
+ cal.add(weekFields[i], +1);
+ if (!cal.checkDateTime(1930, JUNE, 21, 01, 00, 00, 000)) {
+ error("1930/6/14: add("+cal.getFieldName(weekFields[i])+", +1)\n"
+ + cal.getMessage()+" " + cal.toDateTimeString());
+ }
+
+ // roll()
+ cal.clear();
+ cal.set(1919, DECEMBER, 14-7, 23, 50, 00);
+ cal.roll(weekFields[i], +1);
+ if (!cal.checkDate(1919, DECEMBER, 14)) {
+ error("1919/12/07: roll("+cal.getFieldName(weekFields[i])+", +1)\n"
+ + cal.getMessage()+" " + cal.toDateTimeString());
+ }
+ cal.clear();
+ cal.set(1930, JUNE, 21-7);
+ cal.roll(weekFields[i], +1);
+ if (!cal.checkDateTime(1930, JUNE, 21, 01, 00, 00, 000)) {
+ error("1930/6/14: roll("+cal.getFieldName(weekFields[i])+", +1)\n"
+ + cal.getMessage()+" " + cal.toDateTimeString());
+ }
+ }
+
+ // Test the day fields
+ int[] dayFields = { DAY_OF_MONTH, DAY_OF_YEAR, DAY_OF_WEEK };
+ for (int i = 0; i < dayFields.length; i++) {
+ int field = dayFields[i];
+ // add()
+ cal.clear();
+ cal.set(1919, DECEMBER, 14-1, 23, 50, 00);
+ cal.add(field, +1);
+ if (!cal.checkDate(1919, DECEMBER, 14)) {
+ error("1919/12/13: add("+cal.getFieldName(field)+", +1)\n"
+ + cal.getMessage()+" " + cal.toDateTimeString());
+ }
+ cal.clear();
+ cal.set(1919, DECEMBER, 14, 00, 00, 00);
+ cal.add(field, -1);
+ if (!cal.checkDate(1919, DECEMBER, 13)) {
+ error("1919/12/14: add("+cal.getFieldName(field)+", -1)\n"
+ + cal.getMessage()+" " + cal.toDateTimeString());
+ }
+ cal.clear();
+ cal.set(1930, JUNE, 21-1);
+ cal.add(field, +1);
+ if (!cal.checkDateTime(1930, JUNE, 21, 01, 00, 00, 000)) {
+ error("1930/6/20: add("+cal.getFieldName(field)+", +1)\n"
+ + cal.getMessage() + cal.toDateTimeString());
+ }
+ cal.clear();
+ cal.set(1930, JUNE, 21, 01, 00, 00);
+ cal.add(field, -1);
+ if (!cal.checkDateTime(1930, JUNE, 20, 01, 00, 00, 000)) {
+ error("1930/6/21: add("+cal.getFieldName(field)+", -1)\n"
+ + cal.getMessage()+" " + cal.toDateTimeString());
+ }
+
+ // roll()
+ cal.clear();
+ cal.set(1930, JUNE, 21-1);
+ int amount = +1;
+ if (field == DAY_OF_WEEK) {
+ amount += 700;
+ }
+ cal.roll(field, amount);
+ if (!cal.checkDateTime(1930, JUNE, 21, 01, 00, 00, 000)) {
+ error("1930/6/20: roll("+cal.getFieldName(field)+", +"+amount+")\n"
+ + cal.getMessage() + " " + cal.toDateTimeString());
+ }
+ cal.clear();
+ cal.set(1930, JUNE, 21, 01, 00, 00);
+ amount = -1;
+ if (field == DAY_OF_WEEK) {
+ amount -= 700;
+ }
+ cal.roll(field, amount);
+ if (!cal.checkDateTime(1930, JUNE, 20, 01, 00, 00, 000)) {
+ error("1930/6/21: roll("+cal.getFieldName(field)+", "+amount+")\n"
+ + cal.getMessage()+" "+cal.toDateTimeString());
+ }
+ }
+
+ // Test the AM_PM field
+ // add()
+ cal.clear();
+ cal.set(1919, DECEMBER, 14-1, 23, 50, 00);
+ cal.add(AM_PM, +1);
+ if (!cal.checkDate(1919, DECEMBER, 14)
+ || !cal.checkFieldValue(AM_PM, AM)) {
+ error("1919/12/13: add(AM_PM, +1)\n"
+ + cal.getMessage()+" "+cal.toDateTimeString());
+ }
+
+ cal.clear();
+ cal.set(1930, JUNE, 21-1, 12, 00, 00);
+ cal.add(AM_PM, +1);
+ if (!cal.checkDate(1930, JUNE, 21)
+ || !cal.checkFieldValue(AM_PM, AM)) {
+ error("1930/6/20: add(AM_PM, +1)\n"
+ + cal.getMessage()+" "+cal.toDateTimeString());
+ }
+
+ cal.clear();
+ cal.set(1930, JUNE, 21-2, 12, 00, 00);
+ cal.add(AM_PM, +3);
+ if (!cal.checkDate(1930, JUNE, 21)
+ || !cal.checkFieldValue(AM_PM, AM)) {
+ error("1930/6/10: add(AM_PM, +3)\n"
+ + cal.getMessage()+" "+cal.toDateTimeString());
+ }
+
+ cal.clear();
+ cal.set(1919, DECEMBER, 14, 11, 50, 00);
+ cal.add(AM_PM, -1);
+ if (!cal.checkDateTime(1919, DECEMBER, 14-1, 23, 50, 00, 000)
+ || !cal.checkFieldValue(AM_PM, PM)) {
+ error("1919/12/14 11:50:00: add(AM_PM, -1)\n"
+ + cal.getMessage()+" "+cal.toDateTimeString());
+ }
+
+ cal.clear();
+ cal.set(1930, JUNE, 21, 01, 00, 00);
+ cal.add(AM_PM, -1);
+ if (!cal.checkDateTime(1930, JUNE, 21-1, 01+12, 00, 00, 000)
+ || !cal.checkFieldValue(AM_PM, PM)) {
+ error("1930/6/20: add(AM_PM, -1)\n"
+ + cal.getMessage()+" "+cal.toDateTimeString());
+ }
+
+ cal.clear();
+ cal.set(1930, JUNE, 21, 01, 00, 00);
+ cal.add(AM_PM, -3);
+ if (!cal.checkDateTime(1930, JUNE, 21-2, 01+12, 00, 00, 000)
+ || !cal.checkFieldValue(AM_PM, PM)) {
+ error("1930/6/10: add(AM_PM, -3)\n"
+ + cal.getMessage()+" "+cal.toDateTimeString());
+ }
+
+ // roll() (should NOT change the date)
+ cal.clear();
+ cal.set(1919, DECEMBER, 14-1, 23, 50, 00);
+ cal.roll(AM_PM, +1);
+ if (!cal.checkDateTime(1919, DECEMBER, 14-1, 23-12, 50, 00, 000)
+ || !cal.checkFieldValue(AM_PM, AM)) {
+ error("1919/12/13: roll(AM_PM, +1)\n"
+ + cal.getMessage()+" "+cal.toDateTimeString());
+ }
+
+ cal.clear();
+ cal.set(1930, JUNE, 21-1, 12, 00, 00);
+ cal.roll(AM_PM, +1);
+ if (!cal.checkDateTime(1930, JUNE, 21-1, 12-12, 00, 00, 000)
+ || !cal.checkFieldValue(AM_PM, AM)) {
+ error("1930/6/20: roll(AM_PM, +1)\n"
+ + cal.getMessage()+" "+cal.toDateTimeString());
+ }
+
+ cal.clear();
+ cal.set(1930, JUNE, 21-2, 12, 00, 00);
+ cal.roll(AM_PM, +3);
+ if (!cal.checkDateTime(1930, JUNE, 21-2, 12-12, 00, 00, 000)
+ || !cal.checkFieldValue(AM_PM, AM)) {
+ error("1930/6/10: roll(AM_PM, +3)\n"
+ + cal.getMessage()+" "+cal.toDateTimeString());
+ }
+
+ // Test the HOUR_OF_DAY field
+ // add()
+ cal.clear();
+ cal.set(1930, JUNE, 20, 23, 00, 00);
+ cal.add(HOUR_OF_DAY, +1);
+ if (!cal.checkDateTime(1930, JUNE, 21, 01, 00, 00, 000)) {
+ error("1930/6/20 23:00:00: add(HOUR_OF_DAY, +1)\n"
+ + cal.getMessage()+" "+cal.toDateTimeString());
+ }
+
+ // roll() (should NOT change the date)
+ cal.clear();
+ cal.set(1930, JUNE, 20, 23, 00, 00);
+ cal.roll(HOUR_OF_DAY, +1);
+ if (!cal.checkDateTime(1930, JUNE, 20, 00, 00, 00, 000)) {
+ error("1930/6/20 23:00:00: roll(HOUR_OF_DAY, +1)\n"
+ + cal.getMessage()+" "+cal.toDateTimeString());
+ }
+
+ checkErrors();
+ }
+
+ static void error(String s) {
+ System.out.println(s);
+ errorCount++;
+ }
+
+ static void checkErrors() {
+ if (errorCount > 0) {
+ throw new RuntimeException("Failed: " + errorCount + " error(s)");
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/Bug5078053.java b/jdk/test/java/util/Calendar/Bug5078053.java
new file mode 100644
index 00000000000..c6bb25bcf82
--- /dev/null
+++ b/jdk/test/java/util/Calendar/Bug5078053.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2004, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 5078053
+ * @summary Make sure that Calendar.complete() normalizes stamp[] to
+ * COMPUTED. This can be observed through add() and roll().
+ */
+
+import java.util.TimeZone;
+import static java.util.Calendar.*;
+
+public class Bug5078053 {
+ static int errorCount = 0;
+
+ public static void main(String[] args) {
+ TimeZone defaultTz = TimeZone.getDefault();
+
+ try {
+ TimeZone tz = TimeZone.getTimeZone("Australia/Adelaide");
+ TimeZone.setDefault(tz);
+ Koyomi cal = new Koyomi();
+ cal.setFirstDayOfWeek(2);
+ cal.setMinimalDaysInFirstWeek(4);
+
+ // test roll()
+ cal.clear();
+ // 2002-01-01T00:00:00 in Australia/Adelaide
+ cal.setTimeInMillis(1009805400000L);
+ System.out.println(cal.getTime());
+ // The following set calls shouldn't affect roll() and add()
+ cal.set(DAY_OF_WEEK, cal.get(DAY_OF_WEEK));
+ cal.set(WEEK_OF_YEAR, cal.get(WEEK_OF_YEAR));
+ cal.getTime();
+ cal.roll(MONTH, +1);
+ System.out.println("roll: " + cal.getTime());
+ if (!cal.checkDate(2002, FEBRUARY, 1)) {
+ error("roll(MONTH, +1): " + cal.getMessage());
+ }
+ cal.roll(MONTH, -1);
+ if (!cal.checkDate(2002, JANUARY, 1)) {
+ error("roll(MONTH, -1): " + cal.getMessage());
+ }
+
+ // test add()
+ cal.clear();
+ // 2002-01-01T00:00:00+0930 in Australia/Adelaide
+ cal.setTimeInMillis(1009805400000L);
+ cal.set(DAY_OF_WEEK, cal.get(DAY_OF_WEEK));
+ cal.set(WEEK_OF_YEAR, cal.get(WEEK_OF_YEAR));
+ cal.getTime();
+ cal.add(MONTH, +1);
+ System.out.println(" add: " + cal.getTime());
+ if (!cal.checkDate(2002, FEBRUARY, 1)) {
+ error("add(MONTH, +1): " + cal.getMessage());
+ }
+ cal.add(MONTH, -1);
+ if (!cal.checkDate(2002, JANUARY, 1)) {
+ error("add(MONTH, -1): " + cal.getMessage());
+ }
+ }
+ finally {
+ TimeZone.setDefault(defaultTz);
+ }
+
+ checkErrors();
+ }
+
+ static void error(String s) {
+ System.out.println(s);
+ errorCount++;
+ }
+
+ static void checkErrors() {
+ if (errorCount > 0) {
+ throw new RuntimeException("Failed: " + errorCount + " error(s)");
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/Bug6178071.java b/jdk/test/java/util/Calendar/Bug6178071.java
new file mode 100644
index 00000000000..8d361c76bcb
--- /dev/null
+++ b/jdk/test/java/util/Calendar/Bug6178071.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6178071 6440854
+ * @summary Make sure that setting HOUR right after a construction works
+ * as expected.
+ */
+
+import java.util.GregorianCalendar;
+import static java.util.Calendar.*;
+
+public class Bug6178071 {
+ public static void main(String[] args) {
+ GregorianCalendar cal = new GregorianCalendar(2004, JANUARY, 1);
+ cal.set(HOUR, 1);
+ if (cal.get(HOUR_OF_DAY) != 1 ||
+ cal.get(HOUR) != 1 || cal.get(AM_PM) != AM) {
+ throw new RuntimeException("Unexpected hour of day: " + cal.getTime());
+ }
+
+ // Test case for 6440854
+ GregorianCalendar gc = new GregorianCalendar(2006,5,16);
+ gc.setLenient(false);
+ gc.set(HOUR_OF_DAY, 10);
+ // The following line shouldn't throw an IllegalArgumentException.
+ gc.get(YEAR);
+ }
+}
diff --git a/jdk/test/java/util/Calendar/Bug6234795.java b/jdk/test/java/util/Calendar/Bug6234795.java
new file mode 100644
index 00000000000..d1b2bc55c01
--- /dev/null
+++ b/jdk/test/java/util/Calendar/Bug6234795.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6234795
+ * @summary Rolling of HOUR or HOUR_OF_SET must set the other hour field.
+ */
+
+import java.util.GregorianCalendar;
+import static java.util.Calendar.AM;
+import static java.util.Calendar.AM_PM;
+import static java.util.Calendar.HOUR;
+import static java.util.Calendar.HOUR_OF_DAY;
+import static java.util.Calendar.SEPTEMBER;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public class Bug6234795 {
+ public static void main(String[] args) {
+ testRoll(HOUR);
+ testRoll(HOUR_OF_DAY);
+ }
+
+ static void testRoll(int field) {
+ GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"), Locale.US);
+ cal.clear();
+ cal.set(2005, SEPTEMBER, 12);
+
+ int otherField = (field == HOUR) ? HOUR_OF_DAY : HOUR;
+ int unit = (field == HOUR) ? 12 : 24;
+ int h;
+ for (h = 0; h <= 72; h++) {
+ int hour = cal.get(otherField);
+ int expected = h % 12;
+ if (hour != expected) {
+ throw new RuntimeException((field == HOUR ? "HOUR" : "HOUR_OF_DAY")
+ + "+: h=" + h + ", got " + hour
+ + ", expected " + expected);
+ }
+ if (field == HOUR_OF_DAY) {
+ int ampm = cal.get(AM_PM);
+ expected = (h % unit) / 12;
+ if (ampm != expected) {
+ throw new RuntimeException((field == HOUR ? "HOUR" : "HOUR_OF_DAY")
+ + "+: h=" + h + ", got "
+ + toString(ampm)
+ + ", expected " + toString(expected));
+ }
+ }
+ cal.roll(field, +1);
+ }
+ for (; h >= 0; h--) {
+ int hour = cal.get(otherField);
+ int expected = h % 12;
+ if (hour != expected) {
+ throw new RuntimeException((field == HOUR ? "HOUR" : "HOUR_OF_DAY")
+ + "-: h=" + h + ", got " + hour
+ + ", expected " + expected);
+ }
+ if (field == HOUR_OF_DAY) {
+ int ampm = cal.get(AM_PM);
+ expected = (h % unit) / 12;
+ if (ampm != expected) {
+ throw new RuntimeException((field == HOUR ? "HOUR" : "HOUR_OF_DAY")
+ + "-: h=" + h + ", got " + toString(ampm)
+ + ", expected " + toString(expected));
+ }
+ }
+ cal.roll(field, -1);
+ }
+ }
+
+ static String toString(int ampm) {
+ return ampm == AM ? "AM" : "PM";
+ }
+}
diff --git a/jdk/test/java/util/Calendar/Bug6448234.java b/jdk/test/java/util/Calendar/Bug6448234.java
new file mode 100644
index 00000000000..16cf0fca1c4
--- /dev/null
+++ b/jdk/test/java/util/Calendar/Bug6448234.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2006, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6448234
+ * @summary Make sure indexing of DAY_OF_WEEK is correct in JapaneseImperialCalendar.getDisplayName.
+ */
+
+import java.util.Calendar;
+import java.util.Locale;
+import static java.util.Calendar.*;
+
+public class Bug6448234 {
+ public static void main(String[] args) {
+ Calendar jcal = Calendar.getInstance(new Locale("ja", "JP", "JP"));
+ Calendar gcal = Calendar.getInstance(Locale.US);
+
+ for (int i = SUNDAY; i <= SATURDAY; i++) {
+ jcal.set(DAY_OF_WEEK, i);
+ gcal.set(DAY_OF_WEEK, i);
+
+ // Test LONG
+ String j = jcal.getDisplayName(DAY_OF_WEEK, LONG, Locale.US);
+ String g = gcal.getDisplayName(DAY_OF_WEEK, LONG, Locale.US);
+ if (!j.equals(g)) {
+ throw new RuntimeException("Got " + j + ", expected " + g);
+ }
+
+ // Test SHORT
+ j = jcal.getDisplayName(DAY_OF_WEEK, SHORT, Locale.US);
+ g = gcal.getDisplayName(DAY_OF_WEEK, SHORT, Locale.US);
+ if (!j.equals(g)) {
+ throw new RuntimeException("Got " + j + ", expected " + g);
+ }
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/CalendarLimitTest.java b/jdk/test/java/util/Calendar/CalendarLimitTest.java
new file mode 100644
index 00000000000..69dcbb5efcf
--- /dev/null
+++ b/jdk/test/java/util/Calendar/CalendarLimitTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 1997, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4033662
+ * @library /java/text/testlib
+ * @summary test for limit on Calendar
+ * @run main CalendarLimitTest -verbose
+ */
+
+import java.util.*;
+import java.text.*;
+
+/**
+ * This test verifies the behavior of Calendar around the very earliest limits
+ * which it can handle. It also verifies the behavior for large values of millis.
+ *
+ * Note: There used to be a limit, due to a bug, for early times. There is
+ * currently no limit.
+ *
+ * March 17, 1998: Added code to make sure big + dates are big + AD years, and
+ * big - dates are big + BC years.
+ */
+public class CalendarLimitTest extends IntlTest
+{
+ // This number determined empirically; this is the old limit,
+ // which we test for to make sure it isn't there anymore.
+ static final long EARLIEST_SUPPORTED_MILLIS = -210993120000000L;
+
+ static final int EPOCH_JULIAN_DAY = 2440588; // Jaunary 1, 1970 (Gregorian)
+ static final int JAN_1_1_JULIAN_DAY = 1721426; // January 1, year 1 (Gregorian)
+
+ // Useful millisecond constants
+ static final int ONE_SECOND = 1000;
+ static final int ONE_MINUTE = 60*ONE_SECOND;
+ static final int ONE_HOUR = 60*ONE_MINUTE;
+ static final int ONE_DAY = 24*ONE_HOUR;
+ static final int ONE_WEEK = 7*ONE_DAY;
+ static final long ONE_YEAR = (long)(365.2425 * ONE_DAY);
+
+ static long ORIGIN; // This is the *approximate* point at which BC switches to AD
+
+ public static void main(String argv[]) throws Exception {
+ new CalendarLimitTest().run(argv);
+ }
+
+ /**
+ * Converts Julian day to time as milliseconds.
+ * @param julian the given Julian day number.
+ * @return time as milliseconds.
+ */
+ private static final long julianDayToMillis(long julian) {
+ return (julian - EPOCH_JULIAN_DAY) * ONE_DAY;
+ }
+
+ /**
+ * Verify that the given time is processed without problem.
+ * @return the adjust year, with 0 = 1 BC, -1 = 2 BC, etc.
+ */
+ int test(long millis, Calendar cal, DateFormat fmt)
+ {
+ Exception exception = null;
+ String theDate = "";
+ try {
+ Date d= new Date(millis);
+ cal.setTime(d);
+ theDate = fmt.format(d);
+ }
+ catch (IllegalArgumentException e) {
+ exception = e;
+ }
+ String s = "0x" + Long.toHexString(millis) + " " + theDate;
+
+ int era=cal.get(Calendar.ERA), year=cal.get(Calendar.YEAR),
+ dom=cal.get(Calendar.DATE), mon=cal.get(Calendar.MONTH);
+
+ cal.clear();
+ cal.set(year, mon, dom);
+ cal.set(Calendar.ERA, era);
+ Date rt = cal.getTime();
+
+ boolean ok = true;
+ if (exception != null) {
+ errln("FAIL: Exception " + s);
+ ok = false;
+ }
+ if (((millis >= ORIGIN) && (era != GregorianCalendar.AD)) ||
+ ((millis < ORIGIN) && (era != GregorianCalendar.BC)) ||
+ (year < 1)) {
+ errln("FAIL: Bad year/era " + s);
+ ok = false;
+ }
+ if (dom<1 || dom>31) {
+ errln("FAIL: Bad DOM " + s);
+ ok = false;
+ }
+ if (Math.abs(millis - rt.getTime()) > ONE_DAY) {
+ errln("FAIL: RT fail " + s + " -> 0x" +
+ Long.toHexString(rt.getTime()) + " " +
+ fmt.format(rt));
+ ok = false;
+ }
+ if (ok) logln(s);
+ if (era==GregorianCalendar.BC) year = 1-year;
+ return year;
+ }
+
+ public void TestCalendarLimit()
+ {
+ ORIGIN = julianDayToMillis(JAN_1_1_JULIAN_DAY);
+
+ Calendar cal = Calendar.getInstance();
+ // You must set the time zone to GMT+0 or the edge cases like
+ // Long.MIN_VALUE, Long.MAX_VALUE, and right around the threshold
+ // won't work, since before converting to fields the calendar code
+ // will add the offset for the zone.
+ cal.setTimeZone(TimeZone.getTimeZone("Africa/Casablanca"));
+
+ DateFormat dateFormat = DateFormat.getDateInstance();
+ dateFormat.setCalendar(cal); // Make sure you do this -- same reason as above
+ ((SimpleDateFormat)dateFormat).applyPattern("MMM d, yyyy G");
+
+ // Don't expect any failure for positive longs
+ int lastYear=0;
+ boolean first=true;
+ for (long m = Long.MAX_VALUE; m > 0; m >>= 1)
+ {
+ int y = test(m, cal, dateFormat);
+ if (!first && y > lastYear)
+ errln("FAIL: Years should be decreasing " + lastYear + " " + y);
+ first = false;
+ lastYear = y;
+ }
+
+ // Expect failures for negative millis below threshold
+ first = true;
+ for (long m = Long.MIN_VALUE; m < 0; m /= 2) // Don't use m >>= 1
+ {
+ int y = test(m, cal, dateFormat);
+ if (!first && y < lastYear)
+ errln("FAIL: Years should be increasing " + lastYear + " " + y);
+ first = false;
+ lastYear = y;
+ }
+
+ // Test right around the threshold
+ test(EARLIEST_SUPPORTED_MILLIS, cal, dateFormat);
+ test(EARLIEST_SUPPORTED_MILLIS-1, cal, dateFormat);
+
+ // Test a date that should work
+ test(Long.MIN_VALUE + ONE_DAY, cal, dateFormat);
+
+ // Try hours in the earliest day or two
+ // JUST FOR DEBUGGING:
+ if (false) {
+ ((SimpleDateFormat)dateFormat).applyPattern("H:mm MMM d, yyyy G");
+ for (int dom=2; dom<=3; ++dom) {
+ for (int h=0; h<24; ++h) {
+ cal.clear();
+ cal.set(Calendar.ERA, GregorianCalendar.BC);
+ cal.set(292269055, Calendar.DECEMBER, dom, h, 0);
+ Date d = cal.getTime();
+ cal.setTime(d);
+ logln("" + h + ":00 Dec "+dom+", 292269055 BC -> " +
+ Long.toHexString(d.getTime()) + " -> " +
+ dateFormat.format(cal.getTime()));
+ }
+ }
+ // Other way
+ long t = 0x80000000018c5c00L; // Dec 3, 292269055 BC
+ while (t<0) {
+ cal.setTime(new Date(t));
+ logln("0x" + Long.toHexString(t) + " -> " +
+ dateFormat.format(cal.getTime()));
+ t -= ONE_HOUR;
+ }
+ }
+ }
+}
+
+//eof
diff --git a/jdk/test/java/util/Calendar/CalendarRegression.java b/jdk/test/java/util/Calendar/CalendarRegression.java
new file mode 100644
index 00000000000..baae13f14fd
--- /dev/null
+++ b/jdk/test/java/util/Calendar/CalendarRegression.java
@@ -0,0 +1,2496 @@
+/*
+ * Copyright (c) 1998, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4031502 4035301 4040996 4051765 4059654 4061476 4070502 4071197 4071385
+ * 4073929 4083167 4086724 4092362 4095407 4096231 4096539 4100311 4103271
+ * 4106136 4108764 4114578 4118384 4125881 4125892 4136399 4141665 4142933
+ * 4145158 4145983 4147269 4149677 4162587 4165343 4166109 4167060 4173516
+ * 4174361 4177484 4197699 4209071 4288792 4328747 4413980 4546637 4623997
+ * 4685354 4655637 4683492 4080631 4080631 4167995 4340146 4639407
+ * 4652815 4652830 4740554 4936355 4738710 4633646 4846659 4822110 4960642
+ * 4973919 4980088 4965624 5013094 5006864 8152077
+ * @library /java/text/testlib
+ */
+
+import java.lang.reflect.*;
+import java.io.*;
+import java.util.*;
+import java.text.*;
+
+public class CalendarRegression extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new CalendarRegression().run(args);
+ }
+
+ /*
+ Synopsis: java.sql.Timestamp constructor works wrong on Windows 95
+
+ ==== Here is the test ====
+ public static void main (String args[]) {
+ java.sql.Timestamp t= new java.sql.Timestamp(0,15,5,5,8,13,123456700);
+ logln("expected=1901-04-05 05:08:13.1234567");
+ logln(" result="+t);
+ }
+
+ ==== Here is the output of the test on Solaris or NT ====
+ expected=1901-04-05 05:08:13.1234567
+ result=1901-04-05 05:08:13.1234567
+
+ ==== Here is the output of the test on Windows95 ====
+ expected=1901-04-05 05:08:13.1234567
+ result=1901-04-05 06:08:13.1234567
+ */
+
+ public void Test4031502() {
+ // This bug actually occurs on Windows NT as well, and doesn't
+ // require the host zone to be set; it can be set in Java.
+ String[] ids = TimeZone.getAvailableIDs();
+ boolean bad = false;
+ for (int i=0; i
+ * @param date The date to start from
+ */
+ public static Date getAssociatedDate(Date d) {
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.setTime(d);
+ //cal.add(field, amount); //<-- PROBLEM SEEN WITH field = DATE,MONTH
+ // cal.getTime(); // <--- REMOVE THIS TO SEE BUG
+ while (true) {
+ int wd = cal.get(Calendar.DAY_OF_WEEK);
+ if (wd == Calendar.SATURDAY || wd == Calendar.SUNDAY) {
+ cal.add(Calendar.DATE, 1);
+ // cal.getTime();
+ }
+ else
+ break;
+ }
+ return cal.getTime();
+ }
+
+ public void Test4071197() {
+ dowTest(false);
+ dowTest(true);
+ }
+
+ void dowTest(boolean lenient) {
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.set(1997, Calendar.AUGUST, 12); // Wednesday
+ // cal.getTime(); // Force update
+ cal.setLenient(lenient);
+ cal.set(1996, Calendar.DECEMBER, 1); // Set the date to be December 1, 1996
+ int dow = cal.get(Calendar.DAY_OF_WEEK);
+ int min = cal.getMinimum(Calendar.DAY_OF_WEEK);
+ int max = cal.getMaximum(Calendar.DAY_OF_WEEK);
+ logln(cal.getTime().toString());
+ if (min != Calendar.SUNDAY || max != Calendar.SATURDAY)
+ errln("FAIL: Min/max bad");
+ if (dow < min || dow > max)
+ errln("FAIL: Day of week " + dow + " out of range");
+ if (dow != Calendar.SUNDAY)
+ errln("FAIL: Day of week should be SUNDAY Got " + dow);
+ }
+
+ public void Test4071385() {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(new Date(98, Calendar.JUNE, 24));
+ cal.set(Calendar.MONTH, Calendar.NOVEMBER); // change a field
+ logln(cal.getTime().toString());
+ if (!cal.getTime().equals(new Date(98, Calendar.NOVEMBER, 24)))
+ errln("Fail");
+ }
+
+ public void Test4073929() {
+ GregorianCalendar foo1 = new GregorianCalendar(1997, 8, 27);
+ foo1.add(Calendar.DAY_OF_MONTH, +1);
+ int testyear = foo1.get(Calendar.YEAR);
+ int testmonth = foo1.get(Calendar.MONTH);
+ int testday = foo1.get(Calendar.DAY_OF_MONTH);
+ if (testyear != 1997 ||
+ testmonth != 8 ||
+ testday != 28)
+ errln("Fail: Calendar not initialized");
+ }
+
+ public void Test4083167() {
+ TimeZone saveZone = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+ Date firstDate = new Date();
+ Calendar cal = new GregorianCalendar();
+ cal.setTime(firstDate);
+ long firstMillisInDay = cal.get(Calendar.HOUR_OF_DAY) * 3600000L +
+ cal.get(Calendar.MINUTE) * 60000L +
+ cal.get(Calendar.SECOND) * 1000L +
+ cal.get(Calendar.MILLISECOND);
+
+ logln("Current time: " + firstDate.toString());
+
+ for (int validity=0; validity<30; validity++) {
+ Date lastDate = new Date(firstDate.getTime() +
+ (long)validity*1000*24*60*60);
+ cal.setTime(lastDate);
+ long millisInDay = cal.get(Calendar.HOUR_OF_DAY) * 3600000L +
+ cal.get(Calendar.MINUTE) * 60000L +
+ cal.get(Calendar.SECOND) * 1000L +
+ cal.get(Calendar.MILLISECOND);
+ if (firstMillisInDay != millisInDay) {
+ errln("Day has shifted " + lastDate);
+ }
+ }
+ }
+ finally {
+ TimeZone.setDefault(saveZone);
+ }
+ }
+
+ public void Test4086724() {
+ SimpleDateFormat date;
+ TimeZone saveZone = TimeZone.getDefault();
+ Locale saveLocale = Locale.getDefault();
+
+ String summerTime = "British Summer Time";
+ String standardTime = "Greenwich Mean Time";
+ try {
+ Locale.setDefault(Locale.UK);
+ TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
+ date = new SimpleDateFormat("zzzz");
+
+ Calendar cal=Calendar.getInstance();
+ cal.set(1997,Calendar.SEPTEMBER,30);
+ Date now=cal.getTime();
+ String formattedDate = date.format(now);
+ if (!formattedDate.equals(summerTime)) {
+ errln("Wrong display name \"" + formattedDate
+ + "\" for <" + now + ">");
+ }
+ int weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
+ if (weekOfYear != 40) {
+ errln("Wrong week-of-year " + weekOfYear
+ + " for <" + now + ">");
+ }
+
+ cal.set(1996,Calendar.DECEMBER,31);
+ now=cal.getTime();
+ formattedDate = date.format(now);
+ if (!formattedDate.equals(standardTime)) {
+ errln("Wrong display name \"" + formattedDate
+ + "\" for <" + now + ">");
+ }
+ weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
+ if (weekOfYear != 1) {
+ errln("Wrong week-of-year " + weekOfYear
+ + " for <" + now + ">");
+ }
+
+ cal.set(1997,Calendar.JANUARY,1);
+ now=cal.getTime();
+ formattedDate = date.format(now);
+ if (!formattedDate.equals(standardTime)) {
+ errln("Wrong display name \"" + formattedDate
+ + "\" for <" + now + ">");
+ }
+ weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
+ if (weekOfYear != 1) {
+ errln("Wrong week-of-year " + weekOfYear
+ + " for <" + now + ">");
+ }
+
+ cal.set(1997,Calendar.JANUARY,8);
+ now=cal.getTime();
+ formattedDate = date.format(now);
+ if (!formattedDate.equals(standardTime)) {
+ errln("Wrong display name \"" + formattedDate
+ + "\" for <" + now + ">");
+ }
+ weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
+ if (weekOfYear != 2) {
+ errln("Wrong week-of-year " + weekOfYear
+ + " for <" + now + ">");
+ }
+
+ }
+ finally {
+ Locale.setDefault(saveLocale);
+ TimeZone.setDefault(saveZone);
+ }
+ }
+
+ public void Test4092362() {
+ GregorianCalendar cal1 = new GregorianCalendar(1997, 10, 11, 10, 20, 40);
+ /*cal1.set( Calendar.YEAR, 1997 );
+ cal1.set( Calendar.MONTH, 10 );
+ cal1.set( Calendar.DATE, 11 );
+ cal1.set( Calendar.HOUR, 10 );
+ cal1.set( Calendar.MINUTE, 20 );
+ cal1.set( Calendar.SECOND, 40 ); */
+
+ logln( " Cal1 = " + cal1.getTime().getTime() );
+ logln( " Cal1 time in ms = " + cal1.get(Calendar.MILLISECOND) );
+ for( int k = 0; k < 100 ; k++ );
+
+ GregorianCalendar cal2 = new GregorianCalendar(1997, 10, 11, 10, 20, 40);
+ /*cal2.set( Calendar.YEAR, 1997 );
+ cal2.set( Calendar.MONTH, 10 );
+ cal2.set( Calendar.DATE, 11 );
+ cal2.set( Calendar.HOUR, 10 );
+ cal2.set( Calendar.MINUTE, 20 );
+ cal2.set( Calendar.SECOND, 40 ); */
+
+ logln( " Cal2 = " + cal2.getTime().getTime() );
+ logln( " Cal2 time in ms = " + cal2.get(Calendar.MILLISECOND) );
+ if( !cal1.equals( cal2 ) )
+ errln("Fail: Milliseconds randomized");
+ }
+
+ public void Test4095407() {
+ GregorianCalendar a = new GregorianCalendar(1997,Calendar.NOVEMBER, 13);
+ int dow = a.get(Calendar.DAY_OF_WEEK);
+ if (dow != Calendar.THURSDAY)
+ errln("Fail: Want THURSDAY Got " + dow);
+ }
+
+ public void Test4096231() {
+ TimeZone GMT = TimeZone.getTimeZone("GMT");
+ TimeZone PST = TimeZone.getTimeZone("PST");
+ int sec = 0, min = 0, hr = 0, day = 1, month = 10, year = 1997;
+
+ Calendar cal1 = new GregorianCalendar(PST);
+ cal1.setTime(new Date(880698639000L));
+ int p;
+ logln("PST 1 is: " + (p=cal1.get(cal1.HOUR_OF_DAY)));
+ cal1.setTimeZone(GMT);
+ // Issue 1: Changing the timezone doesn't change the
+ // represented time.
+ int h1,h2;
+ logln("GMT 1 is: " + (h1=cal1.get(cal1.HOUR_OF_DAY)));
+ cal1.setTime(new Date(880698639000L));
+ logln("GMT 2 is: " + (h2=cal1.get(cal1.HOUR_OF_DAY)));
+ // Note: This test had a bug in it. It wanted h1!=h2, when
+ // what was meant was h1!=p. Fixed this concurrent with fix
+ // to 4177484.
+ if (p == h1 || h1 != h2)
+ errln("Fail: Hour same in different zones");
+
+ Calendar cal2 = new GregorianCalendar(GMT);
+ Calendar cal3 = new GregorianCalendar(PST);
+ cal2.set(Calendar.MILLISECOND, 0);
+ cal3.set(Calendar.MILLISECOND, 0);
+
+ cal2.set(cal1.get(cal1.YEAR),
+ cal1.get(cal1.MONTH),
+ cal1.get(cal1.DAY_OF_MONTH),
+ cal1.get(cal1.HOUR_OF_DAY),
+ cal1.get(cal1.MINUTE),
+ cal1.get(cal1.SECOND));
+
+ long t1,t2,t3,t4;
+ logln("RGMT 1 is: " + (t1=cal2.getTime().getTime()));
+ cal3.set(year, month, day, hr, min, sec);
+ logln("RPST 1 is: " + (t2=cal3.getTime().getTime()));
+ cal3.setTimeZone(GMT);
+ logln("RGMT 2 is: " + (t3=cal3.getTime().getTime()));
+ cal3.set(cal1.get(cal1.YEAR),
+ cal1.get(cal1.MONTH),
+ cal1.get(cal1.DAY_OF_MONTH),
+ cal1.get(cal1.HOUR_OF_DAY),
+ cal1.get(cal1.MINUTE),
+ cal1.get(cal1.SECOND));
+ // Issue 2: Calendar continues to use the timezone in its
+ // constructor for set() conversions, regardless
+ // of calls to setTimeZone()
+ logln("RGMT 3 is: " + (t4=cal3.getTime().getTime()));
+ if (t1 == t2 ||
+ t1 != t4 ||
+ t2 != t3)
+ errln("Fail: Calendar zone behavior faulty");
+ }
+
+ public void Test4096539() {
+ int[] y = {31,28,31,30,31,30,31,31,30,31,30,31};
+
+ for (int x=0;x<12;x++) {
+ GregorianCalendar gc = new
+ GregorianCalendar(1997,x,y[x]);
+ int m1,m2;
+ log((m1=gc.get(Calendar.MONTH)+1)+"/"+
+ gc.get(Calendar.DATE)+"/"+gc.get(Calendar.YEAR)+
+ " + 1mo = ");
+
+ gc.add(Calendar.MONTH, 1);
+ logln((m2=gc.get(Calendar.MONTH)+1)+"/"+
+ gc.get(Calendar.DATE)+"/"+gc.get(Calendar.YEAR)
+ );
+ int m = (m1 % 12) + 1;
+ if (m2 != m)
+ errln("Fail: Want " + m + " Got " + m2);
+ }
+
+ }
+
+ public void Test4100311() {
+ GregorianCalendar cal = (GregorianCalendar)Calendar.getInstance();
+ cal.set(Calendar.YEAR, 1997);
+ cal.set(Calendar.DAY_OF_YEAR, 1);
+ Date d = cal.getTime(); // Should be Jan 1
+ logln(d.toString());
+ if (cal.get(Calendar.DAY_OF_YEAR) != 1)
+ errln("Fail: DAY_OF_YEAR not set");
+ }
+
+ public void Test4103271() {
+ if (Locale.getDefault().equals(new Locale("th", "TH"))) {
+ return;
+ }
+
+ SimpleDateFormat sdf = new SimpleDateFormat();
+ int numYears=40, startYear=1997, numDays=15;
+ String output, testDesc;
+ GregorianCalendar testCal = (GregorianCalendar)Calendar.getInstance();
+ testCal.clear();
+ sdf.setCalendar(testCal);
+ sdf.applyPattern("d MMM yyyy");
+ boolean fail = false;
+ for (int firstDay=1; firstDay<=2; firstDay++) {
+ for (int minDays=1; minDays<=7; minDays++) {
+ testCal.setMinimalDaysInFirstWeek(minDays);
+ testCal.setFirstDayOfWeek(firstDay);
+ testDesc = ("Test" + String.valueOf(firstDay) + String.valueOf(minDays));
+ logln(testDesc + " => 1st day of week=" +
+ String.valueOf(firstDay) +
+ ", minimum days in first week=" +
+ String.valueOf(minDays));
+ for (int j=startYear; j<=startYear+numYears; j++) {
+ testCal.set(j,11,25);
+ for(int i=0; i 53) {
+ Date d = testCal.getTime();
+ calWOY = String.valueOf(actWOY);
+ output = testDesc + " - " + sdf.format(d) + "\t";
+ output = output + "\t" + calWOY;
+ logln(output);
+ fail = true;
+ }
+ }
+ }
+ }
+ }
+
+ int[] DATA = {
+ 3, 52, 52, 52, 52, 52, 52, 52,
+ 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2,
+ 4, 52, 52, 52, 52, 52, 52, 52,
+ 53, 53, 53, 53, 53, 53, 53,
+ 1, 1, 1, 1, 1, 1, 1,
+ };
+ testCal.setFirstDayOfWeek(Calendar.SUNDAY);
+ for (int j=0; j " + testCal.getTime());
+ if (!after.equals(testCal.getTime())) {
+ logln("\tFAIL\n\t\texp: " + after);
+ fail = true;
+ } else
+ logln(" OK");
+
+ testCal.setTime(after);
+ if (ADDROLL[i] == ADD)
+ testCal.add(Calendar.WEEK_OF_YEAR, -amount);
+ else
+ testCal.roll(Calendar.WEEK_OF_YEAR, -amount);
+ log((ADDROLL[i]==ADD ? "add(WOY," : "roll(WOY,") +
+ (-amount) + ") " + after +
+ "\n\t\t => " + testCal.getTime());
+ if (!before.equals(testCal.getTime())) {
+ logln("\tFAIL\n\t\texp: " + before);
+ fail = true;
+ }
+ else logln("\tOK");
+ }
+
+ if (fail) {
+ errln("Fail: Week of year misbehaving");
+ }
+ }
+
+ public void Test4106136() {
+ Locale saveLocale = Locale.getDefault();
+ try {
+ Locale[] locales = { Locale.CHINESE, Locale.CHINA };
+ for (int i=0; i maxYear) {
+ errln("Failed for "+DATES[i].getTime()+" ms: year=" +
+ year + ", maxYear=" + maxYear);
+ }
+ }
+ }
+
+ /**
+ * This is a bug in the validation code of GregorianCalendar. As reported,
+ * the bug seems worse than it really is, due to a bug in the way the bug
+ * report test was written. In reality the bug is restricted to the DAY_OF_YEAR
+ * field. - liu 6/29/98
+ */
+ public void Test4147269() {
+ final String[] fieldName = {
+ "ERA",
+ "YEAR",
+ "MONTH",
+ "WEEK_OF_YEAR",
+ "WEEK_OF_MONTH",
+ "DAY_OF_MONTH",
+ "DAY_OF_YEAR",
+ "DAY_OF_WEEK",
+ "DAY_OF_WEEK_IN_MONTH",
+ "AM_PM",
+ "HOUR",
+ "HOUR_OF_DAY",
+ "MINUTE",
+ "SECOND",
+ "MILLISECOND",
+ "ZONE_OFFSET",
+ "DST_OFFSET"
+ };
+ GregorianCalendar calendar = new GregorianCalendar();
+ calendar.setLenient(false);
+ Date date = new Date(1996-1900, Calendar.JANUARY, 3); // Arbitrary date
+ for (int field = 0; field < Calendar.FIELD_COUNT; field++) {
+ calendar.setTime(date);
+ // Note: In the bug report, getActualMaximum() was called instead
+ // of getMaximum() -- this was an error. The validation code doesn't
+ // use getActualMaximum(), since that's too costly.
+ int max = calendar.getMaximum(field);
+ int value = max+1;
+ calendar.set(field, value);
+ try {
+ calendar.getTime(); // Force time computation
+ // We expect an exception to be thrown. If we fall through
+ // to the next line, then we have a bug.
+ errln("Test failed with field " + fieldName[field] +
+ ", date before: " + date +
+ ", date after: " + calendar.getTime() +
+ ", value: " + value + " (max = " + max +")");
+ } catch (IllegalArgumentException e) {}
+ }
+ }
+
+ /**
+ * Reported bug is that a GregorianCalendar with a cutover of Date(Long.MAX_VALUE)
+ * doesn't behave as a pure Julian calendar.
+ * CANNOT REPRODUCE THIS BUG
+ */
+ public void Test4149677() {
+ TimeZone[] zones = { TimeZone.getTimeZone("GMT"),
+ TimeZone.getTimeZone("PST"),
+ TimeZone.getTimeZone("EAT") };
+ for (int i=0; i0) logln("---");
+
+ cal.clear();
+ cal.set(1998, Calendar.APRIL, 5, i, 0);
+ d = cal.getTime();
+ String s0 = d.toString();
+ logln("0 " + i + ": " + s0);
+
+ cal.clear();
+ cal.set(1998, Calendar.APRIL, 4, i+24, 0);
+ d = cal.getTime();
+ String sPlus = d.toString();
+ logln("+ " + i + ": " + sPlus);
+
+ cal.clear();
+ cal.set(1998, Calendar.APRIL, 6, i-24, 0);
+ d = cal.getTime();
+ String sMinus = d.toString();
+ logln("- " + i + ": " + sMinus);
+
+ if (!s0.equals(sPlus) || !s0.equals(sMinus)) {
+ errln("Fail: All three lines must match");
+ }
+ }
+ }
+ finally {
+ TimeZone.setDefault(savedTz);
+ }
+ }
+
+ /**
+ * Adding 12 months behaves differently from adding 1 year
+ */
+ public void Test4165343() {
+ GregorianCalendar calendar = new GregorianCalendar(1996, Calendar.FEBRUARY, 29);
+ Date start = calendar.getTime();
+ logln("init date: " + start);
+ calendar.add(Calendar.MONTH, 12);
+ Date date1 = calendar.getTime();
+ logln("after adding 12 months: " + date1);
+ calendar.setTime(start);
+ calendar.add(Calendar.YEAR, 1);
+ Date date2 = calendar.getTime();
+ logln("after adding one year : " + date2);
+ if (date1.equals(date2)) {
+ logln("Test passed");
+ } else {
+ errln("Test failed");
+ }
+ }
+
+ /**
+ * GregorianCalendar.getActualMaximum() does not account for first day of week.
+ */
+ public void Test4166109() {
+ /* Test month:
+ *
+ * March 1998
+ * Su Mo Tu We Th Fr Sa
+ * 1 2 3 4 5 6 7
+ * 8 9 10 11 12 13 14
+ * 15 16 17 18 19 20 21
+ * 22 23 24 25 26 27 28
+ * 29 30 31
+ */
+ boolean passed = true;
+ int field = Calendar.WEEK_OF_MONTH;
+
+ GregorianCalendar calendar = new GregorianCalendar(Locale.US);
+ calendar.set(1998, Calendar.MARCH, 1);
+ calendar.setMinimalDaysInFirstWeek(1);
+ logln("Date: " + calendar.getTime());
+
+ int firstInMonth = calendar.get(Calendar.DAY_OF_MONTH);
+
+ for (int firstInWeek = Calendar.SUNDAY; firstInWeek <= Calendar.SATURDAY; firstInWeek++) {
+ calendar.setFirstDayOfWeek(firstInWeek);
+ int returned = calendar.getActualMaximum(field);
+ int expected = (31 + ((firstInMonth - firstInWeek + 7)% 7) + 6) / 7;
+
+ logln("First day of week = " + firstInWeek +
+ " getActualMaximum(WEEK_OF_MONTH) = " + returned +
+ " expected = " + expected +
+ ((returned == expected) ? " ok" : " FAIL"));
+
+ if (returned != expected) {
+ passed = false;
+ }
+ }
+ if (!passed) {
+ errln("Test failed");
+ }
+ }
+
+ /**
+ * Calendar.getActualMaximum(YEAR) works wrong.
+ *
+ * Note: Before 1.5, this test case assumed that
+ * setGregorianChange didn't change object's date. But it was
+ * changed. See 4928615.
+ */
+ public void Test4167060() {
+ int field = Calendar.YEAR;
+ DateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy G",
+ Locale.US);
+
+ int[][] dates = {
+ // year, month, day of month
+ { 100, Calendar.NOVEMBER, 1 },
+ { -99 /*100BC*/, Calendar.JANUARY, 1 },
+ { 1996, Calendar.FEBRUARY, 29 }};
+
+ String[] id = { "Hybrid", "Gregorian", "Julian" };
+
+ for (int k=0; k<3; ++k) {
+ logln("--- " + id[k] + " ---");
+
+ for (int j = 0; j < dates.length; ++j) {
+ GregorianCalendar calendar = new GregorianCalendar();
+ if (k == 1) {
+ calendar.setGregorianChange(new Date(Long.MIN_VALUE));
+ } else if (k == 2) {
+ calendar.setGregorianChange(new Date(Long.MAX_VALUE));
+ }
+ calendar.set(dates[j][0], dates[j][1], dates[j][2]);
+ format.setCalendar((Calendar)calendar.clone());
+
+ Date dateBefore = calendar.getTime();
+
+ int maxYear = calendar.getActualMaximum(field);
+ logln("maxYear: " + maxYear + " for " + format.format(calendar.getTime()));
+ logln("date before: " + format.format(dateBefore));
+
+ int years[] = {2000, maxYear-1, maxYear, maxYear+1};
+
+ for (int i = 0; i < years.length; i++) {
+ boolean valid = years[i] <= maxYear;
+ calendar.set(field, years[i]);
+ Date dateAfter = calendar.getTime();
+ int newYear = calendar.get(field);
+ calendar.setTime(dateBefore); // restore calendar for next use
+
+ logln(" Year " + years[i] + (valid? " ok " : " bad") +
+ " => " + format.format(dateAfter));
+ if (valid && newYear != years[i]) {
+ errln(" FAIL: " + newYear + " should be valid; date, month and time shouldn't change");
+ } else if (!valid && newYear == years[i]) {
+ errln(" FAIL: " + newYear + " should be invalid");
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Calendar.roll broken
+ * This bug relies on the TimeZone bug 4173604 to also be fixed.
+ */
+ public void Test4173516() {
+ if (Locale.getDefault().equals(new Locale("th", "TH"))) {
+ return;
+ }
+
+ int fieldsList[][] = {
+ { 1997, Calendar.FEBRUARY, 1, 10, 45, 15, 900 },
+ { 1999, Calendar.DECEMBER, 22, 23, 59, 59, 999 },
+ // test case for 4960642 with default cutover
+ { 1582, Calendar.OCTOBER, 4, 23, 59, 59, 999 },
+ };
+ String[] fieldNames = {
+ "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH",
+ "DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH",
+ "AM_PM", "HOUR", "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND",
+ "ZONE_OFFSET", "DST_OFFSET"
+ };
+
+ Locale savedLocale = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+ int limit = 40;
+
+ try {
+ GregorianCalendar cal = new GregorianCalendar();
+
+ cal.setTime(new Date(0));
+ cal.roll(Calendar.HOUR, 0x7F000000);
+ cal.roll(Calendar.HOUR, -0x7F000000);
+ if (cal.getTime().getTime() != 0) {
+ errln("Hour rolling broken. expected 0, got "+cal.getTime().getTime());
+ }
+
+ for (int op=0; op<2; ++op) {
+ logln("Testing GregorianCalendar " + (op==0 ? "add" : "roll"));
+
+ for (int field=0; field < Calendar.FIELD_COUNT; ++field) {
+ if (field != Calendar.ZONE_OFFSET &&
+ field != Calendar.DST_OFFSET) {
+ for (int j=0; j " +
+ cal.get(Calendar.YEAR) +
+ "/" + (cal.get(Calendar.MONTH) + 1) +
+ "/" + cal.get(Calendar.DATE) +
+ " " + cal.get(Calendar.HOUR_OF_DAY) +
+ ":" + cal.get(Calendar.MINUTE) +
+ ":" + cal.get(Calendar.SECOND) +
+ "." + cal.get(Calendar.MILLISECOND) +
+ " d=" + delta);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ finally {
+ Locale.setDefault(savedLocale);
+ }
+ }
+
+ public void Test4174361() {
+ GregorianCalendar calendar = new GregorianCalendar(1996, 1, 29);
+
+ calendar.add(Calendar.MONTH, 10);
+ Date date1 = calendar.getTime();
+ int d1 = calendar.get(Calendar.DAY_OF_MONTH);
+
+ calendar = new GregorianCalendar(1996, 1, 29);
+ calendar.add(Calendar.MONTH, 11);
+ Date date2 = calendar.getTime();
+ int d2 = calendar.get(Calendar.DAY_OF_MONTH);
+
+ if (d1 != d2) {
+ errln("adding months to Feb 29 broken");
+ }
+ }
+
+ /**
+ * Calendar does not update field values when setTimeZone is called.
+ */
+ public void Test4177484() {
+ TimeZone PST = TimeZone.getTimeZone("PST");
+ TimeZone EST = TimeZone.getTimeZone("EST");
+
+ Calendar cal = Calendar.getInstance(PST, Locale.US);
+ cal.clear();
+ cal.set(1999, 3, 21, 15, 5, 0); // Arbitrary
+ int h1 = cal.get(Calendar.HOUR_OF_DAY);
+ cal.setTimeZone(EST);
+ int h2 = cal.get(Calendar.HOUR_OF_DAY);
+ if (h1 == h2) {
+ errln("FAIL: Fields not updated after setTimeZone");
+ }
+
+ // getTime() must NOT change when time zone is changed.
+ // getTime() returns zone-independent time in ms.
+ cal.clear();
+ cal.setTimeZone(PST);
+ cal.set(Calendar.HOUR_OF_DAY, 10);
+ Date pst10 = cal.getTime();
+ cal.setTimeZone(EST);
+ Date est10 = cal.getTime();
+ if (!pst10.equals(est10)) {
+ errln("FAIL: setTimeZone changed time");
+ }
+ }
+
+ /**
+ * Week of year is wrong at the start and end of the year.
+ */
+ public void Test4197699() {
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.setFirstDayOfWeek(Calendar.MONDAY);
+ cal.setMinimalDaysInFirstWeek(4);
+ DateFormat fmt = new SimpleDateFormat("E dd MMM yyyy 'DOY='D 'WOY='w");
+ fmt.setCalendar(cal);
+
+ int[] DATA = {
+ 2000, Calendar.JANUARY, 1, 52,
+ 2001, Calendar.DECEMBER, 31, 1,
+ };
+
+ for (int i=0; i " + actual +
+ ", want " + DATA[i+1]);
+ }
+ }
+ }
+
+ public void Test4288792() throws Exception
+ {
+ TimeZone savedTZ = TimeZone.getDefault();
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ GregorianCalendar cal = new GregorianCalendar();
+ try {
+ for (int i = 1900; i < 2100; i++) {
+ for (int j1 = 1; j1 <= 7; j1++) {
+ // Loop for MinimalDaysInFirstWeek: 1..7
+ for (int j = Calendar.SUNDAY; j <= Calendar.SATURDAY; j++) {
+ // Loop for FirstDayOfWeek: SUNDAY..SATURDAY
+ cal.clear();
+ cal.setMinimalDaysInFirstWeek(j1);
+ cal.setFirstDayOfWeek(j);
+ cal.set(Calendar.YEAR, i);
+ int maxWeek = cal.getActualMaximum(Calendar.WEEK_OF_YEAR);
+ cal.set(Calendar.WEEK_OF_YEAR, maxWeek);
+ cal.set(Calendar.DAY_OF_WEEK, j);
+
+ for (int k = 1; k < 7; k++) {
+ cal.add(Calendar.DATE, 1);
+ int WOY = cal.get(Calendar.WEEK_OF_YEAR);
+ if (WOY != maxWeek) {
+ errln(cal.getTime() + ",got=" + WOY
+ + ",expected=" + maxWeek
+ + ",min=" + j1 + ",first=" + j);
+ }
+ }
+
+ cal.add(Calendar.DATE, 1);
+ int WOY = cal.get(Calendar.WEEK_OF_YEAR);
+ if (WOY != 1) {
+ errln(cal.getTime() + ",got=" + WOY
+ + ",expected=1,min=" + j1 + ",first" + j);
+ }
+ }
+ }
+ }
+ }
+ finally {
+ TimeZone.setDefault(savedTZ);
+ }
+ }
+
+ public void Test4328747() throws Exception {
+ Calendar c = (Calendar)Calendar.getInstance(Locale.US);
+ c.clear();
+ c.set(1966,0,1); // 1 jan 1966
+
+ // serialize
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ObjectOutputStream s = new ObjectOutputStream(out);
+ s.writeObject(c);
+ s.flush();
+
+ // deserialize
+ ObjectInputStream t = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));
+ Calendar result = (Calendar)t.readObject();
+
+ // let recalculate fields with the same UTC time
+ result.setTime(result.getTime());
+ // Bug gives 1965 11 19
+ if ((result.get(c.YEAR) != 1966) || (result.get(c.MONTH) != 0)
+ || (result.get(c.DATE) != 1)) {
+ errln("deserialized Calendar returned wrong date field(s): "
+ + result.get(c.YEAR) + "/" + result.get(c.MONTH) + "/" + result.get(c.DATE)
+ + ", expected 1966/0/1");
+ }
+ }
+
+ /**
+ * Test whether Calendar can be serialized/deserialized correctly
+ * even if invalid/customized TimeZone is used.
+ */
+ public void Test4413980() {
+ TimeZone savedTimeZone = TimeZone.getDefault();
+ try {
+ boolean pass = true;
+ String[] IDs = new String[] {"Undefined", "PST", "US/Pacific",
+ "GMT+3:00", "GMT-01:30"};
+ for (int i = 0; i < IDs.length; i++) {
+ TimeZone tz = TimeZone.getTimeZone(IDs[i]);
+ TimeZone.setDefault(tz);
+
+ Calendar c = (Calendar)Calendar.getInstance();
+
+ // serialize
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ObjectOutputStream s = new ObjectOutputStream(out);
+ s.writeObject(c);
+ s.flush();
+
+ // deserialize
+ ObjectInputStream t = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));
+
+ if (!c.equals(t.readObject())) {
+ pass = false;
+ logln("Calendar instance which uses TimeZone <" +
+ IDs[i] + "> is incorrectly serialized/deserialized.");
+ } else {
+ logln("Calendar instance which uses TimeZone <" +
+ IDs[i] + "> is correctly serialized/deserialized.");
+ }
+ }
+ if (!pass) {
+ errln("Fail: Calendar serialization/equality bug");
+ }
+ }
+ catch (IOException e) {
+ errln("Fail: " + e);
+ e.printStackTrace();
+ }
+ catch (ClassNotFoundException e) {
+ errln("Fail: " + e);
+ e.printStackTrace();
+ }
+ finally {
+ TimeZone.setDefault(savedTimeZone);
+ }
+ }
+
+ /**
+ * 4546637: Incorrect WEEK_OF_MONTH after changing First Day Of Week
+ */
+ public void Test4546637() {
+ GregorianCalendar day = new GregorianCalendar (2001, Calendar.NOVEMBER, 04);
+ day.setMinimalDaysInFirstWeek(1);
+ int wom = day.get(Calendar.WEEK_OF_MONTH);
+
+ day.setFirstDayOfWeek(Calendar.MONDAY);
+ if (day.get(Calendar.WEEK_OF_MONTH) != 1) {
+ errln("Fail: 2001/11/4 must be the first week of the month.");
+ }
+ }
+
+ /**
+ * 4623997: GregorianCalendar returns bad WEEK_OF_YEAR
+ */
+ public void Test4623997() {
+ GregorianCalendar cal = new GregorianCalendar(2000, GregorianCalendar.JANUARY, 1);
+
+ int dow = cal.get(GregorianCalendar.DAY_OF_WEEK);
+
+ cal.setFirstDayOfWeek(GregorianCalendar.MONDAY);
+ cal.setMinimalDaysInFirstWeek(4);
+
+ if (cal.get(GregorianCalendar.WEEK_OF_YEAR) != 52) {
+ errln("Fail: 2000/1/1 must be the 52nd week of the year.");
+ }
+ }
+
+ /**
+ * 4685354: Handling of Calendar fields setting state is broken
+ *
+ * Need to use SimpleDateFormat to test because a call to
+ * get(int) changes internal states of a Calendar.
+ */
+ public void Test4685354() {
+ if (Locale.getDefault().equals(new Locale("hi", "IN"))) {
+ return;
+ }
+
+ Calendar calendar = Calendar.getInstance(Locale.US);
+ DateFormat df = new SimpleDateFormat("yyyy/MM/dd", Locale.US);
+ String expected = "1999/12/31";
+ Date t;
+ String s;
+
+ try {
+ calendar.setTime(df.parse(expected));
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected parse exception", e);
+ }
+
+ t = calendar.getTime();
+ calendar.set(Calendar.DAY_OF_MONTH, 33);
+ t = calendar.getTime();
+ calendar.set(Calendar.DAY_OF_MONTH, 0);
+ s = df.format(calendar.getTime());
+ if (!expected.equals(s)) {
+ errln("DAY_OF_MONTH w/o ZONE_OFFSET: expected: " + expected + ", got: " + s);
+ }
+
+ // The same thing must work with ZONE_OFFSET set
+ try {
+ calendar.setTime(df.parse(expected));
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected parse exception", e);
+ }
+ t = calendar.getTime();
+ calendar.set(calendar.ZONE_OFFSET, calendar.get(calendar.ZONE_OFFSET));
+ calendar.set(Calendar.DAY_OF_MONTH, 33);
+ t = calendar.getTime();
+ calendar.set(Calendar.DAY_OF_MONTH, 0);
+ s = df.format(calendar.getTime());
+ if (!expected.equals(s)) {
+ errln("DAY_OF_MONTH: expected: " + expected + ", got: " + s);
+ }
+
+ expected = "1999/12/24"; // 0th week of 2000
+ calendar.clear();
+ Date initialDate = null;
+ try {
+ initialDate = df.parse(expected);
+ calendar.setTime(initialDate);
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected parse exception", e);
+ }
+ t = calendar.getTime();
+ calendar.set(calendar.ZONE_OFFSET, calendar.get(calendar.ZONE_OFFSET));
+ // jump to the next year
+ calendar.set(Calendar.WEEK_OF_YEAR, 100);
+ t = calendar.getTime();
+ calendar.set(Calendar.WEEK_OF_YEAR, 0);
+ s = df.format(calendar.getTime());
+ if (!expected.equals(s)) {
+ errln("WEEK_OF_YEAR: expected: " + expected + ", got: " + s);
+ }
+ // change the state back
+ calendar.clear();
+ calendar.setTime(initialDate);
+ calendar.set(calendar.ZONE_OFFSET, calendar.get(calendar.ZONE_OFFSET));
+ // jump to next month
+ calendar.set(Calendar.WEEK_OF_MONTH, 7);
+ t = calendar.getTime();
+ calendar.set(Calendar.WEEK_OF_MONTH, 0);
+ s = df.format(calendar.getTime());
+ if (!expected.equals(s)) {
+ errln("WEEK_OF_MONTH: expected: " + expected + ", got: " + s);
+ }
+
+ // Make sure the time fields work correctly.
+ calendar.clear();
+ df = new SimpleDateFormat("HH:mm:ss");
+ TimeZone tz = TimeZone.getTimeZone("GMT");
+ df.setTimeZone(tz);
+ calendar.setTimeZone(tz);
+ expected = "22:59:59";
+ try {
+ calendar.setTime(df.parse(expected));
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected parse exception", e);
+ }
+ t = calendar.getTime();
+ // time should be 22:59:59.
+ calendar.set(Calendar.MINUTE, 61);
+ // time should be 23:01:59.
+ t = calendar.getTime();
+ calendar.set(Calendar.MINUTE, -1);
+ // time should be back to 22:59:59.
+ s = df.format(calendar.getTime());
+ if (!expected.equals(s)) {
+ errln("MINUTE: expected: " + expected + ", got: " + s);
+ }
+ }
+
+ /**
+ * 4655637: Calendar.set() for DAY_OF_WEEK does not return the right value
+ *
+ *
Need to use SimpleDateFormat to test because a call to
+ * get(int) changes internal states of a Calendar.
+ */
+ public void Test4655637() {
+ // Skip this test case if it's Thai locale
+ if (Locale.getDefault().equals(new Locale("th", "TH"))) {
+ return;
+ }
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(new Date(1029814211523L));
+ cal.set(Calendar.YEAR, 2001);
+ Date t = cal.getTime();
+ cal.set(Calendar.MONTH, Calendar.JANUARY);
+ t = cal.getTime();
+
+ cal.set(Calendar.DAY_OF_MONTH, 8);
+ t = cal.getTime();
+
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ DateFormat df = new SimpleDateFormat("yyyy/MM/dd", Locale.US);
+ String expected = "2001/01/08";
+ String s = df.format(cal.getTime());
+ if (!expected.equals(s)) {
+ errln("expected: " + expected + ", got: " + s);
+ }
+ }
+
+ /**
+ * 4683492: Invalid value for MONTH in GregorianCalendar causes exception in getTime().
+ *
+ *
Need to use SimpleDateFormat to test because a call to
+ * get(int) changes internal states of a Calendar.
+ *
+ *
This test case throws ArrayIndexOutOfBoundsException without the fix.
+ */
+ public void Test4683492() {
+ Calendar cal = new GregorianCalendar(2002, 3, 29, 10, 0, 0);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
+ cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, -1);
+ cal.set(Calendar.MONTH, 12);
+ DateFormat df = new SimpleDateFormat("yyyy/MM/dd", Locale.US);
+ String expected = "2003/01/31";
+ String s = df.format(cal.getTime());
+ if (!expected.equals(s)) {
+ errln("expected: " + expected + ", got: " + s);
+ }
+ }
+
+ /**
+ * 4080631: Calendar.hashCode is amazingly bad
+ */
+ public void Test4080631() {
+ Calendar cal = Calendar.getInstance();
+ int h1 = cal.hashCode();
+ cal.add(cal.SECOND, +1);
+ int h2 = cal.hashCode();
+ Calendar cal2 = (Calendar) cal.clone();
+ cal.add(cal.MILLISECOND, +1);
+ int h3 = cal.hashCode();
+ logln("hash code: h1="+h1+", h2="+h2+", h3="+h3);
+ if (h1 == h2 || h1 == h3 || h2 == h3) {
+ errln("hash code is poor: hashCode="+h1);
+ }
+ h2 = cal2.hashCode();
+ cal.add(cal.MILLISECOND, -1);
+ int h4 = cal.hashCode();
+ logln("hash code: h2="+h2+", h4="+h4);
+ if (cal.equals(cal2) && h2 != h4) {
+ errln("broken hash code: h2="+h2+", h4="+h4);
+ }
+ int x = cal.getFirstDayOfWeek() + 3;
+ if (x > cal.SATURDAY) {
+ x -= 7;
+ }
+ cal.setFirstDayOfWeek(x);
+ int h5 = cal.hashCode();
+ logln("hash code: h4="+h4+", h5="+h5);
+ if (h4 == h5) {
+ errln("has code is poor with first day of week param: hashCode="+h4);
+ }
+ }
+
+ /**
+ * 4125161: RFE: GregorianCalendar needs more era names (BCE and CE)
+ */
+ /*
+ public void Test4125161() throws Exception {
+ Class gc = GregorianCalendar.class;
+ Field f;
+ int mod;
+ f = gc.getDeclaredField("BCE");
+ mod = f.getModifiers();
+ if (!Modifier.isStatic(mod) || !Modifier.isFinal(mod)) {
+ errln("BCE: wrong modifiers: " + mod);
+ }
+ f = gc.getDeclaredField("CE");
+ mod = f.getModifiers();
+ if (!Modifier.isStatic(mod) || !Modifier.isFinal(mod)) {
+ errln("CE: wrong modifiers: " + mod);
+ }
+ if (GregorianCalendar.BCE != GregorianCalendar.BC
+ || GregorianCalendar.CE != GregorianCalendar.AD) {
+ errln("Wrong BCE and/or CE values");
+ }
+ }
+ */
+
+ /**
+ * 4167995: GregorianCalendar.setGregorianChange() not to spec
+ */
+ public void Test4167995() {
+ Koyomi gc = new Koyomi(TimeZone.getTimeZone("GMT"));
+ logln("Hybrid: min date");
+ gc.setTime(new Date(Long.MIN_VALUE));
+ if (!gc.checkDate(292269055, gc.DECEMBER, 2, gc.SUNDAY)
+ || !gc.checkFieldValue(gc.ERA, gc.BC)) {
+ errln(gc.getMessage());
+ }
+ logln("Hybrid: max date");
+ gc.setTime(new Date(Long.MAX_VALUE));
+ if (!gc.checkDate(292278994, gc.AUGUST, 17, gc.SUNDAY)
+ || !gc.checkFieldValue(gc.ERA, gc.AD)) {
+ errln(gc.getMessage());
+ }
+
+ gc.setGregorianChange(new Date(Long.MIN_VALUE));
+ logln("Gregorian: min date");
+ gc.setTime(new Date(Long.MIN_VALUE));
+ if (!gc.checkDate(292275056, gc.MAY, 16, gc.SUNDAY)
+ || !gc.checkFieldValue(gc.ERA, gc.BC)) {
+ errln(gc.getMessage());
+ }
+ logln("Gregorian: max date");
+ gc.setTime(new Date(Long.MAX_VALUE));
+ if (!gc.checkDate(292278994, gc.AUGUST, 17, gc.SUNDAY)
+ || !gc.checkFieldValue(gc.ERA, gc.AD)) {
+ errln(gc.getMessage());
+ }
+
+ gc.setGregorianChange(new Date(Long.MAX_VALUE));
+ logln("Julian: min date");
+ gc.setTime(new Date(Long.MIN_VALUE));
+ if (!gc.checkDate(292269055, gc.DECEMBER, 2, gc.SUNDAY)
+ || !gc.checkFieldValue(gc.ERA, gc.BC)) {
+ errln(gc.getMessage());
+ }
+ logln("Julian: max date");
+ gc.setTime(new Date(Long.MAX_VALUE));
+ if (!gc.checkDate(292272993, gc.JANUARY, 4, gc.SUNDAY)
+ || !gc.checkFieldValue(gc.ERA, gc.AD)) {
+ errln(gc.getMessage());
+ }
+ }
+
+ /**
+ * 4340146: Calendar.equals modifies state
+ */
+ public void Test4340146() {
+ Koyomi cal = new Koyomi();
+ cal.clear();
+ cal.set(2003, cal.OCTOBER, 32);
+ cal.equals(new Koyomi());
+ if (!cal.checkInternalDate(2003, cal.OCTOBER, 32)) {
+ errln(cal.getMessage());
+ }
+ new Koyomi().equals(cal);
+ if (!cal.checkInternalDate(2003, cal.OCTOBER, 32)) {
+ errln(cal.getMessage());
+ }
+ }
+
+ /**
+ * 4639407: GregorianCalendar doesn't work in non-lenient due to timezone bounds checking
+ */
+ public void Test4639407() {
+ // The following operations in non-lenient mode shouldn't
+ // throw IllegalArgumentException.
+ Koyomi cal = new Koyomi(TimeZone.getTimeZone("Pacific/Kiritimati"));
+ cal.setLenient(false);
+ cal.set(2003, cal.OCTOBER, 10);
+ cal.getTime();
+ cal.setTimeZone(TimeZone.getTimeZone("Pacific/Tongatapu"));
+ cal.set(2003, cal.OCTOBER, 10);
+ cal.getTime();
+ }
+
+ /**
+ * 4652815: rolling week-of-year back hundreds of weeks changes year
+ */
+ public void Test4652815() {
+ Koyomi cal = new Koyomi(Locale.US);
+ testRoll(cal, 2003, cal.SEPTEMBER, 29);
+ testRoll(cal, 2003, cal.DECEMBER, 24);
+ testRoll(cal, 1582, cal.DECEMBER, 19);
+ testRoll(cal, 1582, cal.DECEMBER, 20);
+ }
+
+ private void testRoll(Koyomi cal, int year, int month, int dayOfMonth) {
+ cal.clear();
+ cal.set(year, month, dayOfMonth);
+ cal.getTime(); // normalize fields
+ logln("Roll backwards from " + cal.toDateString());
+ for (int i = 0; i < 1000; i++) {
+ cal.roll(cal.WEEK_OF_YEAR, -i);
+ if (!cal.checkFieldValue(cal.YEAR, year)) {
+ errln(cal.getMessage());
+ }
+ }
+ logln("Roll forewards from " + cal.toDateString());
+ for (int i = 0; i < 1000; i++) {
+ cal.roll(cal.WEEK_OF_YEAR, +i);
+ if (!cal.checkFieldValue(cal.YEAR, year)) {
+ errln(cal.getMessage());
+ }
+ }
+ }
+
+ /**
+ * 4652830: GregorianCalendar roll behaves unexpectedly for dates in BC era
+ */
+ public void Test4652830() {
+ Koyomi cal = new Koyomi(Locale.US);
+ cal.clear();
+ logln("BCE 9-2-28 (leap year) roll DAY_OF_MONTH++ twice");
+ cal.set(cal.ERA, cal.BC);
+ cal.set(9, cal.FEBRUARY, 28);
+ if (cal.getActualMaximum(cal.DAY_OF_YEAR) != 366) {
+ errln(" wrong actual max of DAY_OF_YEAR: got "
+ + cal.getActualMaximum(cal.DAY_OF_YEAR) + " expected " + 366);
+ }
+ cal.roll(cal.DAY_OF_MONTH, +1);
+ if (!cal.checkFieldValue(cal.ERA, cal.BC)
+ || !cal.checkDate(9, cal.FEBRUARY, 29)) {
+ errln(cal.getMessage());
+ }
+ cal.roll(cal.DAY_OF_MONTH, +1);
+ if (!cal.checkFieldValue(cal.ERA, cal.BC)
+ || !cal.checkDate(9, cal.FEBRUARY, 1)) {
+ errln(cal.getMessage());
+ }
+ }
+
+ /**
+ * 4740554: GregorianCalendar.getActualMaximum is inconsistent with normalization
+ */
+ public void Test4740554() {
+ logln("1999/(Feb+12)/1 should be normalized to 2000/Feb/1 for getActualMaximum");
+ Koyomi cal = new Koyomi(Locale.US);
+ cal.clear();
+ cal.set(1999, cal.FEBRUARY + 12, 1);
+ if (!cal.checkActualMaximum(cal.DAY_OF_YEAR, 366)) {
+ errln(cal.getMessage());
+ }
+ if (!cal.checkActualMaximum(cal.DAY_OF_MONTH, 29)) {
+ errln(cal.getMessage());
+ }
+ }
+
+ /**
+ * 4936355: GregorianCalendar causes overflow/underflow with time of day calculation
+ */
+ public void Test4936355() {
+ Koyomi cal = new Koyomi(TimeZone.getTimeZone("GMT"));
+ cal.clear();
+ cal.set(1970, cal.JANUARY, 1);
+ checkTimeCalculation(cal, cal.HOUR_OF_DAY, Integer.MAX_VALUE,
+ (long)Integer.MAX_VALUE * 60 * 60 * 1000);
+
+ cal.clear();
+ cal.set(1970, cal.JANUARY, 1);
+ checkTimeCalculation(cal, cal.HOUR, Integer.MAX_VALUE,
+ (long)Integer.MAX_VALUE * 60 * 60 * 1000);
+
+ cal.clear();
+ cal.set(1970, cal.JANUARY, 1);
+ checkTimeCalculation(cal, cal.MINUTE, Integer.MAX_VALUE,
+ (long)Integer.MAX_VALUE * 60 * 1000);
+
+ cal.clear();
+ // Make sure to use Gregorian dates (before and after the
+ // set() call) for testing
+ cal.set(250000, cal.JANUARY, 1);
+ checkTimeCalculation(cal, cal.HOUR_OF_DAY, Integer.MIN_VALUE,
+ (long)Integer.MIN_VALUE * 60 * 60 * 1000);
+
+ cal.clear();
+ cal.set(250000, cal.JANUARY, 1);
+ checkTimeCalculation(cal, cal.HOUR, Integer.MIN_VALUE,
+ (long)Integer.MIN_VALUE * 60 * 60 * 1000);
+
+ cal.clear();
+ cal.set(250000, cal.JANUARY, 1);
+ checkTimeCalculation(cal, cal.MINUTE, Integer.MIN_VALUE,
+ (long)Integer.MIN_VALUE * 60 * 1000);
+ }
+
+ private void checkTimeCalculation(Koyomi cal, int field, int value, long expectedDelta) {
+ long time = cal.getTimeInMillis();
+ cal.set(field, value);
+ long time2 = cal.getTimeInMillis();
+ if ((time + expectedDelta) != time2) {
+ String s = value == Integer.MAX_VALUE ? "Integer.MAX_VALUE" : "Integer.MIN_VALUE";
+ errln("set(" + Koyomi.getFieldName(field) + ", " + s + ") failed." + " got " + time2
+ + ", expected " + (time+expectedDelta));
+ }
+ }
+
+ /**
+ * 4722650: Calendar.equals can throw an exception in non-lenient
+ * (piggy-back tests for compareTo() which is new in 1.5)
+ */
+ public void Test4722650() {
+ Calendar cal1 = new GregorianCalendar();
+ cal1.clear();
+ Calendar cal2 = new GregorianCalendar();
+ cal2.clear();
+ cal2.setLenient(false);
+
+ cal1.set(2003, Calendar.OCTOBER, 31);
+ cal2.set(2003, Calendar.OCTOBER, 31);
+ try {
+ if (cal1.equals(cal2)) {
+ errln("lenient and non-lenient shouldn't be equal. (2003/10/31)");
+ }
+ if (cal1.compareTo(cal2) != 0) {
+ errln("cal1 and cal2 should represent the same time. (2003/10/31)");
+ }
+ } catch (IllegalArgumentException e) {
+ errln("equals threw IllegalArugumentException with non-lenient");
+ }
+
+ cal1.set(2003, Calendar.OCTOBER, 32);
+ cal2.set(2003, Calendar.OCTOBER, 32);
+ try {
+ if (cal1.equals(cal2)) {
+ errln("lenient and non-lenient shouldn't be equal. (2003/10/32)");
+ }
+ if (cal1.compareTo(cal2) != 0) {
+ errln("cal1 and cal2 should represent the same time. (2003/10/32)");
+ }
+ } catch (IllegalArgumentException e) {
+ errln("equals threw IllegalArugumentException with non-lenient");
+ }
+
+ cal1 = Calendar.getInstance(new Locale("th", "TH"));
+ cal1.setTimeInMillis(0L);
+ cal2 = Calendar.getInstance(Locale.US);
+ cal2.setTimeInMillis(0L);
+ if (cal1.equals(cal2)) {
+ errln("Buddhist.equals(Gregorian) shouldn't be true. (millis=0)");
+ }
+ if (cal1.compareTo(cal2) != 0) {
+ errln("cal1 (Buddhist) and cal2 (Gregorian) should represent the same time. (millis=0)");
+ }
+ }
+
+ /**
+ * 4738710: API: Calendar comparison methods should be improved
+ */
+ public void Test4738710() {
+ Calendar cal0 = new GregorianCalendar(2003, Calendar.SEPTEMBER, 30);
+ Comparable cal1 = new GregorianCalendar(2003, Calendar.OCTOBER, 1);
+ Calendar cal2 = new GregorianCalendar(2003, Calendar.OCTOBER, 2);
+ if (!(cal1.compareTo(cal0) > 0)) {
+ errln("!(cal1 > cal0)");
+ }
+ if (!(cal1.compareTo(cal2) < 0)) {
+ errln("!(cal1 < cal2)");
+ }
+ if (cal1.compareTo(new GregorianCalendar(2003, Calendar.OCTOBER, 1)) != 0) {
+ errln("cal1 != new GregorianCalendar(2003, Calendar.OCTOBER, 1)");
+ }
+
+ if (cal0.after(cal2)) {
+ errln("cal0 shouldn't be after cal2");
+ }
+ if (cal2.before(cal0)) {
+ errln("cal2 shouldn't be before cal0");
+ }
+
+ if (cal0.after(new Integer(0))) {
+ errln("cal0.after() returned true with an Integer.");
+ }
+ if (cal0.before(new Integer(0))) {
+ errln("cal0.before() returned true with an Integer.");
+ }
+ if (cal0.after(null)) {
+ errln("cal0.after() returned true with null.");
+ }
+ if (cal0.before(null)) {
+ errln("cal0.before() returned true with null.");
+ }
+ }
+
+ /**
+ * 4633646: Setting WEEK_OF_MONTH to 1 results in incorrect date
+ */
+ public void Test4633646() {
+ Koyomi cal = new Koyomi(Locale.US);
+ cal.setTime(new Date(2002-1900, 1-1, 28));
+ sub4633646(cal);
+
+ cal.setLenient(false);
+ cal.setTime(new Date(2002-1900, 1-1, 28));
+ sub4633646(cal);
+
+ cal = new Koyomi(Locale.US);
+ cal.clear();
+ cal.set(2002, cal.JANUARY, 28);
+ sub4633646(cal);
+
+ cal.clear();
+ cal.setLenient(false);
+ cal.set(2002, cal.JANUARY, 28);
+ sub4633646(cal);
+ }
+
+ void sub4633646(Koyomi cal) {
+ cal.getTime();
+ cal.set(cal.WEEK_OF_MONTH, 1);
+ if (cal.isLenient()) {
+ if (!cal.checkDate(2001, cal.DECEMBER, 31)) {
+ errln(cal.getMessage());
+ }
+ if (!cal.checkFieldValue(cal.WEEK_OF_MONTH, 6)) {
+ errln(cal.getMessage());
+ }
+ } else {
+ try {
+ Date d = cal.getTime();
+ errln("didn't throw IllegalArgumentException in non-lenient");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+ }
+
+ /**
+ * 4846659: Calendar: Both set() and roll() don't work for AM_PM time field
+ * (Partially fixed only roll as of 1.5)
+ */
+ public void Test4846659() {
+ Koyomi cal = new Koyomi();
+ cal.clear();
+ cal.set(2003, cal.OCTOBER, 31, 10, 30, 30);
+ cal.getTime();
+ // Test roll()
+ cal.roll(cal.AM_PM, +1); // should turn to PM
+ if (!cal.checkFieldValue(cal.HOUR_OF_DAY, 10+12)) {
+ errln("roll: AM_PM didn't change to PM");
+ }
+
+ cal.clear();
+ cal.set(2003, cal.OCTOBER, 31, 10, 30, 30);
+ cal.getTime();
+ // Test set()
+ cal.set(cal.AM_PM, cal.PM); // should turn to PM
+ if (!cal.checkFieldValue(cal.HOUR_OF_DAY, 10+12)) {
+ errln("set: AM_PM didn't change to PM");
+ }
+
+ cal.clear();
+ cal.set(2003, cal.OCTOBER, 31, 10, 30, 30);
+ cal.getTime();
+ cal.set(cal.AM_PM, cal.PM);
+ cal.set(cal.HOUR, 9);
+ if (!cal.checkFieldValue(cal.HOUR_OF_DAY, 9+12)) {
+ errln("set: both AM_PM and HOUT didn't change to PM");
+ }
+ }
+
+ /**
+ * 4822110: GregorianCalendar.get() returns an incorrect date after setFirstDayOfWeek()
+ */
+ public void Test4822110() {
+ Koyomi cal = new Koyomi(Locale.US);
+ // June 2003
+ // S M Tu W Th F S
+ // 1 2 3 4 5 6 7
+ // 8 9 10 11 12 13 14
+ // 15 16 17 18 19 20 21
+ // 22 23 24 25 26 27 28
+ // 29 30
+ cal.clear();
+ // 6/1 to 6/7 should be the 1st week of June.
+ cal.set(2003, cal.JUNE, 2);
+ cal.getTime(); // Let cal calculate time.
+ cal.setFirstDayOfWeek(cal.MONDAY);
+ // Now 6/2 to 6/8 should be the 2nd week of June. Sunday of
+ // that week is 6/8.
+ logln("1: " +cal.get(cal.WEEK_OF_MONTH)+", "+cal.get(cal.DAY_OF_MONTH));
+ cal.set(cal.DAY_OF_WEEK, cal.SUNDAY);
+ logln("1st Sunday of June 2003 with FirstDayOfWeek=MONDAY");
+ if (!cal.checkDate(2003, cal.JUNE, 8)) {
+ errln(cal.getMessage());
+ }
+ }
+
+ /**
+ * 4973919: Inconsistent GregorianCalendar hashCode before and after serialization
+ */
+ public void Test4966499() throws Exception {
+ GregorianCalendar date1 = new GregorianCalendar(2004, Calendar.JANUARY, 7);
+
+ // Serialize date1
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(date1);
+
+ byte[] buffer = baos.toByteArray();
+
+ // Deserialize it
+ ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ GregorianCalendar date2 = (GregorianCalendar)ois.readObject();
+
+ if (!date1.equals(date2)) {
+ errln("date1.equals(date2) != true");
+ }
+ if (date1.hashCode() != date2.hashCode()) {
+ errln("inconsistent hashCode() value (before=0x"
+ +Integer.toHexString(date1.hashCode())+
+ ", after=0x"+Integer.toHexString(date2.hashCode())+")");
+ }
+ }
+
+ /**
+ * 4980088: GregorianCalendar.getActualMaximum doesn't throw exception
+ */
+ public void Test4980088() {
+ GregorianCalendar cal = new GregorianCalendar();
+ try {
+ int x = cal.getMaximum(100);
+ errln("getMaximum(100) didn't throw an exception.");
+ } catch (IndexOutOfBoundsException e) {
+ logln("getMaximum: " + e.getClass().getName() + ": " + e.getMessage());
+ }
+
+ try {
+ int x = cal.getLeastMaximum(100);
+ errln("getLeastMaximum(100) didn't throw an exception.");
+ } catch (IndexOutOfBoundsException e) {
+ logln("getLeastMaximum: " + e.getClass().getName() + ": " + e.getMessage());
+ }
+
+ try {
+ int x = cal.getActualMaximum(100);
+ errln("getActualMaximum(100) didn't throw an exception.");
+ } catch (IndexOutOfBoundsException e) {
+ logln("getActualMaximum: " + e.getClass().getName() + ": " + e.getMessage());
+ }
+
+ try {
+ int x = cal.getMinimum(100);
+ errln("getMinimum(100) didn't throw an exception.");
+ } catch (IndexOutOfBoundsException e) {
+ logln("getMinimum: " + e.getClass().getName() + ": " + e.getMessage());
+ }
+
+ try {
+ int x = cal.getGreatestMinimum(100);
+ errln("getGreatestMinimum(100) didn't throw an exception.");
+ } catch (IndexOutOfBoundsException e) {
+ logln("getGreatestMinimum: " + e.getClass().getName() + ": " + e.getMessage());
+ }
+
+ try {
+ int x = cal.getActualMinimum(100);
+ errln("getActualMinimum(100) didn't throw an exception.");
+ } catch (IndexOutOfBoundsException e) {
+ logln("getActualMinimum: " + e.getClass().getName() + ": " + e.getMessage());
+ }
+ }
+
+ /**
+ * 4965624: GregorianCalendar.isLeapYear(1000) returns incorrect value
+ */
+ public void Test4965624() {
+ // 5013094: This test case needs to use "GMT" to specify
+ // Gregorian cutover dates.
+ TimeZone savedZone = TimeZone.getDefault();
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ try {
+ Map data = new HashMap();
+ data.put(getGregorianDate(999, Calendar.OCTOBER, 1), Boolean.FALSE);
+ data.put(getGregorianDate(1000, Calendar.JANUARY, 1), Boolean.FALSE);
+ data.put(getGregorianDate(1000, Calendar.FEBRUARY, 1), Boolean.FALSE);
+ data.put(getGregorianDate(1000, Calendar.FEBRUARY, 28), Boolean.FALSE);
+ data.put(getGregorianDate(1000, Calendar.MARCH, 1), Boolean.TRUE);
+ data.put(getGregorianDate(1001, Calendar.JANUARY, 1), Boolean.TRUE);
+ data.put(getGregorianDate(1001, Calendar.JANUARY, 6), Boolean.TRUE);
+ data.put(getGregorianDate(1001, Calendar.MARCH, 1), Boolean.TRUE);
+
+ Iterator itr = data.keySet().iterator();
+ while (itr.hasNext()) {
+ Date d = itr.next();
+ boolean expected = data.get(d).booleanValue();
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.setGregorianChange(d);
+ if (cal.isLeapYear(1000) != expected) {
+ errln("isLeapYear(1000) returned " + cal.isLeapYear(1000) +
+ " with cutover date (Julian) " + d);
+ }
+ }
+ }
+ finally {
+ TimeZone.setDefault(savedZone);
+ }
+ }
+
+ // Note that we can't use Date to produce Gregorian calendar dates
+ // before the default cutover date.
+ static Date getGregorianDate(int year, int month, int dayOfMonth) {
+ GregorianCalendar g = new GregorianCalendar();
+ // Make g a pure Gregorian calendar
+ g.setGregorianChange(new Date(Long.MIN_VALUE));
+ g.clear();
+ g.set(year, month, dayOfMonth);
+ return g.getTime();
+ }
+
+ /**
+ * 5006864: Define the minimum value of DAY_OF_WEEK_IN_MONTH as 1
+ */
+ public void Test5006864() {
+ GregorianCalendar cal = new GregorianCalendar();
+ int min = cal.getMinimum(cal.DAY_OF_WEEK_IN_MONTH);
+ if (min != 1) {
+ errln("GregorianCalendar.getMinimum(DAY_OF_WEEK_IN_MONTH) returned "
+ + min + ", expected 1.");
+ }
+ min = cal.getGreatestMinimum(cal.DAY_OF_WEEK_IN_MONTH);
+ if (min != 1) {
+ errln("GregorianCalendar.getGreatestMinimum(DAY_OF_WEEK_IN_MONTH) returned "
+ + min + ", expected 1.");
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/CalendarTest.java b/jdk/test/java/util/Calendar/CalendarTest.java
new file mode 100644
index 00000000000..d8320295a6d
--- /dev/null
+++ b/jdk/test/java/util/Calendar/CalendarTest.java
@@ -0,0 +1,1102 @@
+/*
+ * Copyright (c) 1997, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4064654 4374886 4984320 4984574 4944795
+ * @library /java/text/testlib
+ * @summary test for Calendar
+ * @key randomness
+ */
+
+import java.util.*;
+import java.text.*;
+import java.io.*;
+
+public class CalendarTest extends IntlTest {
+ static final int ONE_DAY = 24*60*60*1000;
+ static final int EPOCH_JULIAN = 2440588;
+
+ public static void main(String argv[]) throws Exception {
+ new CalendarTest().run(argv);
+ }
+
+ /**
+ * Test the behavior of the GregorianCalendar around the changeover.
+ */
+ public void TestGregorianChangeover() {
+ TimeZone savedZone = TimeZone.getDefault();
+ /*
+ Changeover -7 days: 1582/9/28 dow=6
+ Changeover -6 days: 1582/9/29 dow=7
+ Changeover -5 days: 1582/9/30 dow=1
+ Changeover -4 days: 1582/10/1 dow=2
+ Changeover -3 days: 1582/10/2 dow=3
+ Changeover -2 days: 1582/10/3 dow=4
+ Changeover -1 days: 1582/10/4 dow=5
+ Changeover +0 days: 1582/10/15 dow=6
+ Changeover +1 days: 1582/10/16 dow=7
+ Changeover +2 days: 1582/10/17 dow=1
+ Changeover +3 days: 1582/10/18 dow=2
+ Changeover +4 days: 1582/10/19 dow=3
+ Changeover +5 days: 1582/10/20 dow=4
+ Changeover +6 days: 1582/10/21 dow=5
+ Changeover +7 days: 1582/10/22 dow=6
+ */
+ int MON[] = { 9, 9, 9,10,10,10,10, 10, 10, 10, 10, 10, 10, 10, 10 };
+ int DOM[] = { 28, 29, 30, 1, 2, 3, 4, 15, 16, 17, 18, 19, 20, 21, 22 };
+ int DOW[] = { 6, 7, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6 };
+ // ^ <-Changeover Fri Oct 15 1582
+
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ Date co = new Date(1582-1900, Calendar.OCTOBER, 15);
+ GregorianCalendar cal = new GregorianCalendar();
+ int j = 0;
+ for (int i = -7; i <= 7; ++i, ++j) {
+ Date d = new Date(co.getTime() + i*ONE_DAY);
+ cal.setTime(d);
+ int y = cal.get(Calendar.YEAR);
+ int mon = cal.get(Calendar.MONTH)+1-Calendar.JANUARY;
+ int dom = cal.get(Calendar.DATE);
+ int dow = cal.get(Calendar.DAY_OF_WEEK);
+
+ logln("Changeover " + (i>=0?"+":"") + i +
+ " days: " + y + "/" + mon + "/" + dom + " dow=" + dow);
+ if (y != 1582 || mon != MON[j] || dom != DOM[j] || dow != DOW[j]) {
+ errln(" Fail: Above line is wrong");
+ }
+ }
+ }
+ finally {
+ TimeZone.setDefault(savedZone);
+ }
+ }
+
+ /**
+ * Test the mapping between millis and fields. For the purposes
+ * of this test, we don't care about timezones and week data
+ * (first day of week, minimal days in first week).
+ */
+ public void TestMapping() {
+ TimeZone saveZone = TimeZone.getDefault();
+ int[] DATA = {
+ // Julian# Year Month DOM JULIAN:Year, Month, DOM
+ 2440588, 1970, Calendar.JANUARY, 1, 1969, Calendar.DECEMBER, 19,
+ 2415080, 1900, Calendar.MARCH, 1, 1900, Calendar.FEBRUARY, 17,
+ 2451604, 2000, Calendar.FEBRUARY, 29, 2000, Calendar.FEBRUARY, 16,
+ 2452269, 2001, Calendar.DECEMBER, 25, 2001, Calendar.DECEMBER, 12,
+ 2416526, 1904, Calendar.FEBRUARY, 15, 1904, Calendar.FEBRUARY, 2,
+ 2416656, 1904, Calendar.JUNE, 24, 1904, Calendar.JUNE, 11,
+ 1721426, 1, Calendar.JANUARY, 1, 1, Calendar.JANUARY, 3,
+ 2000000, 763, Calendar.SEPTEMBER, 18, 763, Calendar.SEPTEMBER, 14,
+ 4000000, 6239, Calendar.JULY, 12, 6239, Calendar.MAY, 28,
+ 8000000, 17191, Calendar.FEBRUARY, 26, 17190, Calendar.OCTOBER, 22,
+ 10000000, 22666, Calendar.DECEMBER, 20, 22666, Calendar.JULY, 5,
+ };
+
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+ Date PURE_GREGORIAN = new Date(Long.MIN_VALUE);
+ Date PURE_JULIAN = new Date(Long.MAX_VALUE);
+ GregorianCalendar cal = new GregorianCalendar();
+ for (int i = 0; i < DATA.length; i += 7) {
+ int julian = DATA[i];
+ int year = DATA[i+1];
+ int month = DATA[i+2];
+ int dom = DATA[i+3];
+ int year2, month2, dom2;
+ long millis = ((long)julian - EPOCH_JULIAN) * ONE_DAY;
+ String s;
+
+ // Test Gregorian computation
+ cal.setGregorianChange(PURE_GREGORIAN);
+ cal.clear();
+ cal.set(year, month, dom);
+ long calMillis = cal.getTime().getTime();
+ long delta = calMillis - millis;
+ cal.setTime(new Date(millis));
+ year2 = cal.get(Calendar.YEAR);
+ month2 = cal.get(Calendar.MONTH);
+ dom2 = cal.get(Calendar.DAY_OF_MONTH);
+ s = "G " + year + "-" + (month+1-Calendar.JANUARY) + "-" + dom +
+ " => " + calMillis +
+ " (" + ((float)delta/ONE_DAY) + " day delta) => " +
+ year2 + "-" + (month2+1-Calendar.JANUARY) + "-" + dom2;
+ if (delta != 0 || year != year2 || month != month2 ||
+ dom != dom2) {
+ errln(s + " FAIL");
+ } else {
+ logln(s);
+ }
+
+ // Test Julian computation
+ year = DATA[i+4];
+ month = DATA[i+5];
+ dom = DATA[i+6];
+ cal.setGregorianChange(PURE_JULIAN);
+ cal.clear();
+ cal.set(year, month, dom);
+ calMillis = cal.getTime().getTime();
+ delta = calMillis - millis;
+ cal.setTime(new Date(millis));
+ year2 = cal.get(Calendar.YEAR);
+ month2 = cal.get(Calendar.MONTH);
+ dom2 = cal.get(Calendar.DAY_OF_MONTH);
+ s = "J " + year + "-" + (month+1-Calendar.JANUARY) + "-" + dom +
+ " => " + calMillis +
+ " (" + ((float)delta/ONE_DAY) + " day delta) => " +
+ year2 + "-" + (month2+1-Calendar.JANUARY) + "-" + dom2;
+ if (delta != 0 || year != year2 || month != month2 ||
+ dom != dom2) {
+ errln(s + " FAIL");
+ } else {
+ logln(s);
+ }
+ }
+
+ cal.setGregorianChange(new Date(1582-1900, Calendar.OCTOBER, 15));
+ auxMapping(cal, 1582, Calendar.OCTOBER, 4);
+ auxMapping(cal, 1582, Calendar.OCTOBER, 15);
+ auxMapping(cal, 1582, Calendar.OCTOBER, 16);
+ for (int y = 800; y < 3000; y += 1+(int)100*Math.random()) {
+ for (int m = Calendar.JANUARY; m <= Calendar.DECEMBER; ++m) {
+ auxMapping(cal, y, m, 15);
+ }
+ }
+ }
+ finally {
+ TimeZone.setDefault(saveZone);
+ }
+ }
+ private void auxMapping(Calendar cal, int y, int m, int d) {
+ cal.clear();
+ cal.set(y, m, d);
+ long millis = cal.getTime().getTime();
+ cal.setTime(new Date(millis));
+ int year2 = cal.get(Calendar.YEAR);
+ int month2 = cal.get(Calendar.MONTH);
+ int dom2 = cal.get(Calendar.DAY_OF_MONTH);
+ if (y != year2 || m != month2 || dom2 != d)
+ errln("Round-trip failure: " + y + "-" + (m+1) + "-"+d+" =>ms=> " +
+ year2 + "-" + (month2+1) + "-" + dom2);
+ }
+
+ public void TestGenericAPI() {
+ if (Locale.getDefault().equals(new Locale("th", "TH"))) {
+ return;
+ }
+
+ String str;
+
+ Date when = new Date(90, Calendar.APRIL, 15);
+
+ String tzid = "TestZone";
+ int tzoffset = 123400;
+
+ SimpleTimeZone zone = new SimpleTimeZone(tzoffset, tzid);
+ Calendar cal = (Calendar)Calendar.getInstance((SimpleTimeZone)zone.clone());
+
+ if (!zone.equals(cal.getTimeZone())) errln("FAIL: Calendar.getTimeZone failed");
+
+ Calendar cal2 = Calendar.getInstance(cal.getTimeZone());
+
+ cal.setTime(when);
+ cal2.setTime(when);
+
+ if (!(cal.equals(cal2))) errln("FAIL: Calendar.operator== failed");
+ // if ((*cal != *cal2)) errln("FAIL: Calendar.operator!= failed");
+ if (!cal.equals(cal2) ||
+ cal.before(cal2) ||
+ cal.after(cal2)) errln("FAIL: equals/before/after failed");
+
+ cal2.setTime(new Date(when.getTime() + 1000));
+ if (cal.equals(cal2) ||
+ cal2.before(cal) ||
+ cal.after(cal2)) errln("FAIL: equals/before/after failed");
+
+ cal.roll(Calendar.SECOND, true);
+ if (!cal.equals(cal2) ||
+ cal.before(cal2) ||
+ cal.after(cal2)) errln("FAIL: equals/before/after failed");
+
+ // Roll back to January
+ cal.roll(Calendar.MONTH, (int)(1 + Calendar.DECEMBER - cal.get(Calendar.MONTH)));
+ if (cal.equals(cal2) ||
+ cal2.before(cal) ||
+ cal.after(cal2)) errln("FAIL: equals/before/after failed");
+
+ // C++ only
+ /* TimeZone z = cal.orphanTimeZone();
+ if (z.getID(str) != tzid ||
+ z.getRawOffset() != tzoffset)
+ errln("FAIL: orphanTimeZone failed");
+ */
+
+ for (int i = 0; i < 2; ++i) {
+ boolean lenient = ( i > 0 );
+ cal.setLenient(lenient);
+ if (lenient != cal.isLenient()) errln("FAIL: setLenient/isLenient failed");
+ // Later: Check for lenient behavior
+ }
+
+ int i;
+ for (i = Calendar.SUNDAY; i <= Calendar.SATURDAY; ++i) {
+ cal.setFirstDayOfWeek(i);
+ if (cal.getFirstDayOfWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed");
+ }
+
+ for (i = 0; i <= 7; ++i) {
+ cal.setMinimalDaysInFirstWeek(i);
+ if (cal.getMinimalDaysInFirstWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed");
+ }
+
+ for (i = 0; i < Calendar.FIELD_COUNT; ++i) {
+ if (cal.getMinimum(i) != cal.getGreatestMinimum(i))
+ errln("FAIL: getMinimum doesn't match getGreatestMinimum for field " + i);
+ if (cal.getLeastMaximum(i) > cal.getMaximum(i))
+ errln("FAIL: getLeastMaximum larger than getMaximum for field " + i);
+ if (cal.getMinimum(i) >= cal.getMaximum(i))
+ errln("FAIL: getMinimum not less than getMaximum for field " + i);
+ }
+
+ cal.setTimeZone(TimeZone.getDefault());
+ cal.clear();
+ cal.set(1984, 5, 24);
+ if (cal.getTime().getTime() != new Date(84, 5, 24).getTime()) {
+ errln("FAIL: Calendar.set(3 args) failed");
+ logln(" Got: " + cal.getTime() + " Expected: " + new Date(84, 5, 24));
+ }
+
+ cal.clear();
+ cal.set(1985, 3, 2, 11, 49);
+ if (cal.getTime().getTime() != new Date(85, 3, 2, 11, 49).getTime()) {
+ errln("FAIL: Calendar.set(5 args) failed");
+ logln(" Got: " + cal.getTime() + " Expected: " + new Date(85, 3, 2, 11, 49));
+ }
+
+ cal.clear();
+ cal.set(1995, 9, 12, 1, 39, 55);
+ if (cal.getTime().getTime() != new Date(95, 9, 12, 1, 39, 55).getTime()) {
+ errln("FAIL: Calendar.set(6 args) failed");
+ logln(" Got: " + cal.getTime() + " Expected: " + new Date(95, 9, 12, 1, 39, 55));
+ }
+
+ cal.getTime();
+ for (i = 0; i < Calendar.FIELD_COUNT; ++i) {
+ switch(i) {
+ case Calendar.YEAR: case Calendar.MONTH: case Calendar.DATE:
+ case Calendar.HOUR_OF_DAY: case Calendar.MINUTE: case Calendar.SECOND:
+ if (!cal.isSet(i))
+ errln("FAIL: !Calendar.isSet test failed: " + calendarFieldNames[i]);
+ break;
+ default:
+ if (cal.isSet(i))
+ errln("FAIL: Calendar.isSet test failed: " + calendarFieldNames[i]);
+ }
+ cal.clear(i);
+ if (cal.isSet(i)) errln("FAIL: Calendar.clear/isSet failed");
+ }
+
+ // delete cal;
+ // delete cal2;
+
+ Locale[] loc = Calendar.getAvailableLocales();
+ long count = loc.length;
+ if (count < 1 || loc == null) {
+ errln("FAIL: getAvailableLocales failed");
+ }
+ else {
+ for (i = 0; i < count; ++i) {
+ cal = Calendar.getInstance(loc[i]);
+ // delete cal;
+ }
+ }
+
+ cal = Calendar.getInstance(TimeZone.getDefault(), Locale.ENGLISH);
+ // delete cal;
+
+ cal = Calendar.getInstance(zone, Locale.ENGLISH);
+ // delete cal;
+
+ GregorianCalendar gc = new GregorianCalendar(zone);
+ // delete gc;
+
+ gc = new GregorianCalendar(Locale.ENGLISH);
+ // delete gc;
+
+ gc = new GregorianCalendar(Locale.ENGLISH);
+ // delete gc;
+
+ gc = new GregorianCalendar(zone, Locale.ENGLISH);
+ // delete gc;
+
+ gc = new GregorianCalendar(zone);
+ // delete gc;
+
+ gc = new GregorianCalendar(1998, 10, 14, 21, 43);
+ if (gc.getTime().getTime() != new Date(98, 10, 14, 21, 43).getTime())
+ errln("FAIL: new GregorianCalendar(ymdhm) failed");
+ // delete gc;
+
+ gc = new GregorianCalendar(1998, 10, 14, 21, 43, 55);
+ if (gc.getTime().getTime() != new Date(98, 10, 14, 21, 43, 55).getTime())
+ errln("FAIL: new GregorianCalendar(ymdhms) failed");
+
+ // C++ only:
+ // GregorianCalendar gc2 = new GregorianCalendar(Locale.ENGLISH);
+ // gc2 = gc;
+ // if (gc2 != gc || !(gc2 == gc)) errln("FAIL: GregorianCalendar assignment/operator==/operator!= failed");
+ // delete gc;
+ // delete z;
+ }
+
+ // Verify Roger Webster's bug
+ public void TestRog() {
+ GregorianCalendar gc = new GregorianCalendar();
+
+ int year = 1997, month = Calendar.APRIL, date = 1;
+ gc.set(year, month, date); // April 1, 1997
+
+ gc.set(Calendar.HOUR_OF_DAY, 23);
+ gc.set(Calendar.MINUTE, 0);
+ gc.set(Calendar.SECOND, 0);
+ gc.set(Calendar.MILLISECOND, 0);
+
+ for (int i = 0; i < 9; i++, gc.add(Calendar.DATE, 1)) {
+ if (gc.get(Calendar.YEAR) != year ||
+ gc.get(Calendar.MONTH) != month ||
+ gc.get(Calendar.DATE) != (date + i))
+ errln("FAIL: Date " + gc.getTime() + " wrong");
+ }
+ }
+
+ // Verify DAY_OF_WEEK
+ public void TestDOW943() {
+ dowTest(false);
+ dowTest(true);
+ }
+
+ void dowTest(boolean lenient) {
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.set(1997, Calendar.AUGUST, 12); // Wednesday
+ cal.getTime(); // Force update
+ cal.setLenient(lenient);
+ cal.set(1996, Calendar.DECEMBER, 1); // Set the date to be December 1, 1996
+ int dow = cal.get(Calendar.DAY_OF_WEEK);
+ int min = cal.getMinimum(Calendar.DAY_OF_WEEK);
+ int max = cal.getMaximum(Calendar.DAY_OF_WEEK);
+ if (dow < min || dow > max) errln("FAIL: Day of week " + dow + " out of range");
+ if (dow != Calendar.SUNDAY) {
+ errln("FAIL2: Day of week should be SUNDAY; is " + dow + ": " + cal.getTime());
+ }
+ if (min != Calendar.SUNDAY || max != Calendar.SATURDAY) errln("FAIL: Min/max bad");
+ }
+
+ // Verify that the clone method produces distinct objects with no
+ // unintentionally shared fields.
+ public void TestClonesUnique908() {
+ Calendar c = Calendar.getInstance();
+ Calendar d = (Calendar)c.clone();
+ c.set(Calendar.MILLISECOND, 123);
+ d.set(Calendar.MILLISECOND, 456);
+ if (c.get(Calendar.MILLISECOND) != 123 ||
+ d.get(Calendar.MILLISECOND) != 456) {
+ errln("FAIL: Clones share fields");
+ }
+ }
+
+ // Verify effect of Gregorian cutoff value
+ public void TestGregorianChange768() {
+ boolean b;
+ GregorianCalendar c = new GregorianCalendar();
+ logln("With cutoff " + c.getGregorianChange());
+ logln(" isLeapYear(1800) = " + (b=c.isLeapYear(1800)));
+ logln(" (should be FALSE)");
+ if (b != false) errln("FAIL");
+ c.setGregorianChange(new Date(0, 0, 1)); // Jan 1 1900
+ logln("With cutoff " + c.getGregorianChange());
+ logln(" isLeapYear(1800) = " + (b=c.isLeapYear(1800)));
+ logln(" (should be TRUE)");
+ if (b != true) errln("FAIL");
+ }
+
+ // Test the correct behavior of the disambiguation algorithm.
+ public void TestDisambiguation765() throws Exception {
+ Locale savedLocale = Locale.getDefault();
+ try {
+ Locale.setDefault(Locale.US);
+ Calendar c = Calendar.getInstance();
+ c.setLenient(false);
+
+ c.clear();
+ c.set(Calendar.YEAR, 1997);
+ c.set(Calendar.MONTH, Calendar.JUNE);
+ c.set(Calendar.DATE, 3);
+
+ verify765("1997 third day of June = ", c, 1997, Calendar.JUNE, 3);
+
+ c.clear();
+ c.set(Calendar.YEAR, 1997);
+ c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ c.set(Calendar.MONTH, Calendar.JUNE);
+ c.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
+ verify765("1997 first Tuesday in June = ", c, 1997, Calendar.JUNE, 3);
+
+ c.setLenient(true); // for 4944795
+ c.clear();
+ c.set(Calendar.YEAR, 1997);
+ c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ c.set(Calendar.MONTH, Calendar.JUNE);
+ c.set(Calendar.DAY_OF_WEEK_IN_MONTH, -1);
+ verify765("1997 last Tuesday in June = ", c, 1997, Calendar.JUNE, 24);
+
+ c.setLenient(false);
+ IllegalArgumentException e = null;
+ try {
+ c.clear();
+ c.set(Calendar.YEAR, 1997);
+ c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ c.set(Calendar.MONTH, Calendar.JUNE);
+ c.set(Calendar.DAY_OF_WEEK_IN_MONTH, 0);
+ c.getTime();
+ }
+ catch (IllegalArgumentException ex) {
+ e = ex;
+ }
+ verify765("1997 zero-th Tuesday in June = ", e);
+
+ c.clear();
+ c.set(Calendar.YEAR, 1997);
+ c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ c.set(Calendar.MONTH, Calendar.JUNE);
+ c.set(Calendar.WEEK_OF_MONTH, 1);
+ verify765("1997 Tuesday in week 1 of June = ", c, 1997, Calendar.JUNE, 3);
+
+ c.clear();
+ c.set(Calendar.YEAR, 1997);
+ c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ c.set(Calendar.MONTH, Calendar.JUNE);
+ c.set(Calendar.WEEK_OF_MONTH, 4);
+ verify765("1997 Tuesday in week 4 of June = ", c, 1997, Calendar.JUNE, 24);
+
+ try {
+ c.clear();
+ c.set(Calendar.YEAR, 1997);
+ c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ c.set(Calendar.MONTH, Calendar.JUNE);
+ c.set(Calendar.WEEK_OF_MONTH, 1);
+ verify765("1997 Tuesday in week 0 of June = ", c, 1997, Calendar.JUNE, 3);
+ }
+ catch (IllegalArgumentException ex) {
+ errln("FAIL: Exception seen: " + ex.getMessage());
+ // ex.printStackTrace(log);
+ }
+
+ c.clear();
+ c.set(Calendar.YEAR, 1997);
+ c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ c.set(Calendar.WEEK_OF_YEAR, 2);
+ verify765("1997 Tuesday in week 2 of year = ", c, 1997, Calendar.JANUARY, 7);
+
+ c.clear();
+ c.set(Calendar.YEAR, 1997);
+ c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ c.set(Calendar.WEEK_OF_YEAR, 10);
+ verify765("1997 Tuesday in week 10 of year = ", c, 1997, Calendar.MARCH, 4);
+
+ try {
+ c.clear();
+ c.set(Calendar.YEAR, 1997);
+ c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+ c.set(Calendar.WEEK_OF_YEAR, 0);
+ verify765("1997 Tuesday in week 0 of year = ", c, 1996, Calendar.DECEMBER, 24);
+ throw new Exception("Fail: WEEK_OF_YEAR 0 should be illegal");
+ }
+ catch (IllegalArgumentException ex) {}
+ }
+ finally {
+ Locale.setDefault(savedLocale);
+ }
+ }
+ void verify765(String msg, Calendar c, int year, int month, int day) {
+ if (c.get(Calendar.YEAR) == year &&
+ c.get(Calendar.MONTH) == month &&
+ c.get(Calendar.DATE) == day) {
+ logln("PASS: " + msg + c.getTime());
+ }
+ else {
+ errln("FAIL: " + msg + c.getTime() +
+ "; expected " +
+ year + "/" + (month+1) + "/" + day);
+ }
+ }
+ // Called when e expected to be non-null
+ void verify765(String msg, IllegalArgumentException e) {
+ if (e == null) errln("FAIL: No IllegalArgumentException for " + msg);
+ else logln("PASS: " + msg + "IllegalArgument as expected");
+ }
+
+ // Test the behavior of GMT vs. local time
+ public void TestGMTvsLocal4064654() {
+ if (Locale.getDefault().equals(new Locale("th", "TH"))) {
+ return;
+ }
+
+ // Sample output 1:
+ // % /usr/local/java/jdk1.1.3/solaris/bin/java test 1997 1 1 12 0 0
+ // date = Wed Jan 01 04:00:00 PST 1997
+ // offset for Wed Jan 01 04:00:00 PST 1997= -8hr
+ test4064654(1997, 1, 1, 12, 0, 0);
+
+ // Sample output 2:
+ // % /usr/local/java/jdk1.1.3/solaris/bin/java test 1997 4 16 18 30 0
+ // date = Wed Apr 16 10:30:00 PDT 1997
+ // offset for Wed Apr 16 10:30:00 PDT 1997= -7hr
+
+ // Note that in sample output 2 according to the offset, the gmt time
+ // of the result would be 1997 4 16 17 30 0 which is different from the
+ // input of 1997 4 16 18 30 0.
+ test4064654(1997, 4, 16, 18, 30, 0);
+ }
+ void test4064654(int yr, int mo, int dt, int hr, int mn, int sc) {
+ Date date;
+ Calendar gmtcal = Calendar.getInstance();
+ gmtcal.setTimeZone(TimeZone.getTimeZone("Africa/Casablanca"));
+ gmtcal.set(yr, mo-1, dt, hr, mn, sc);
+ gmtcal.set(Calendar.MILLISECOND, 0);
+
+ date = gmtcal.getTime();
+ logln("date = "+date);
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
+ cal.setTime(date);
+
+ int offset = cal.getTimeZone().getOffset(cal.get(Calendar.ERA),
+ cal.get(Calendar.YEAR),
+ cal.get(Calendar.MONTH),
+ cal.get(Calendar.DATE),
+ cal.get(Calendar.DAY_OF_WEEK),
+ cal.get(Calendar.MILLISECOND));
+
+ logln("offset for "+date+"= "+(offset/1000/60/60.0) + "hr");
+
+ int utc = ((cal.get(Calendar.HOUR_OF_DAY) * 60 +
+ cal.get(Calendar.MINUTE)) * 60 +
+ cal.get(Calendar.SECOND)) * 1000 +
+ cal.get(Calendar.MILLISECOND) - offset;
+
+ int expected = ((hr * 60 + mn) * 60 + sc) * 1000;
+
+ if (utc != expected)
+ errln("FAIL: Discrepancy of " +
+ (utc - expected) + " millis = " +
+ ((utc-expected)/1000/60/60.0) + " hr");
+ }
+
+ // Verify that add and set work regardless of the order in which
+ // they are called.
+ public void TestAddSetOrder621() {
+ Date d = new Date(97, 4, 14, 13, 23, 45);
+
+ Calendar cal = Calendar.getInstance ();
+ cal.setTime (d);
+ cal.add (Calendar.DATE, -5);
+ cal.set (Calendar.HOUR_OF_DAY, 0);
+ cal.set (Calendar.MINUTE, 0);
+ cal.set (Calendar.SECOND, 0);
+ // ma feb 03 00:00:00 GMT+00:00 1997
+ String s = cal.getTime ().toString ();
+
+ cal = Calendar.getInstance ();
+ cal.setTime (d);
+ cal.set (Calendar.HOUR_OF_DAY, 0);
+ cal.set (Calendar.MINUTE, 0);
+ cal.set (Calendar.SECOND, 0);
+ cal.add (Calendar.DATE, -5);
+ // ma feb 03 13:11:06 GMT+00:00 1997
+ String s2 = cal.getTime ().toString ();
+
+ if (s.equals(s2))
+ logln("Pass: " + s + " == " + s2);
+ else
+ errln("FAIL: " + s + " != " + s2);
+ }
+
+ // Verify that add works.
+ public void TestAdd520() {
+ int y = 1997, m = Calendar.FEBRUARY, d = 1;
+ GregorianCalendar temp = new GregorianCalendar( y, m, d );
+ check520(temp, y, m, d);
+
+ temp.add( temp.YEAR, 1 );
+ y++;
+ check520(temp, y, m, d);
+
+ temp.add( temp.MONTH, 1 );
+ m++;
+ check520(temp, y, m, d);
+
+ temp.add( temp.DATE, 1 );
+ d++;
+ check520(temp, y, m, d);
+
+ temp.add( temp.DATE, 2 );
+ d += 2;
+ check520(temp, y, m, d);
+
+ temp.add( temp.DATE, 28 );
+ d = 1; ++m;
+ check520(temp, y, m, d);
+ }
+ void check520(Calendar c, int y, int m, int d) {
+ if (c.get(Calendar.YEAR) != y ||
+ c.get(Calendar.MONTH) != m ||
+ c.get(Calendar.DATE) != d) {
+ errln("FAILURE: Expected YEAR/MONTH/DATE of " +
+ y + "/" + (m+1) + "/" + d +
+ "; got " +
+ c.get(Calendar.YEAR) + "/" +
+ (c.get(Calendar.MONTH)+1) + "/" +
+ c.get(Calendar.DATE));
+ }
+ else logln("Confirmed: " +
+ y + "/" + (m+1) + "/" + d);
+ }
+
+ // Verify that setting fields works. This test fails when an exception is thrown.
+ public void TestFieldSet4781() {
+ try {
+ GregorianCalendar g = new GregorianCalendar();
+ GregorianCalendar g2 = new GregorianCalendar();
+ // At this point UTC value is set, various fields are not.
+ // Now set to noon.
+ g2.set(Calendar.HOUR, 12);
+ g2.set(Calendar.MINUTE, 0);
+ g2.set(Calendar.SECOND, 0);
+ // At this point the object thinks UTC is NOT set, but fields are set.
+ // The following line will result in IllegalArgumentException because
+ // it thinks the YEAR is set and it is NOT.
+ if (g2.equals(g))
+ logln("Same");
+ else
+ logln("Different");
+ }
+ catch (IllegalArgumentException e) {
+ errln("Unexpected exception seen: " + e);
+ }
+ }
+
+ // Test serialization of a Calendar object
+ public void TestSerialize337() {
+ Calendar cal = Calendar.getInstance();
+
+ boolean ok = false;
+
+ try {
+ FileOutputStream f = new FileOutputStream(FILENAME);
+ ObjectOutput s = new ObjectOutputStream(f);
+ s.writeObject(PREFIX);
+ s.writeObject(cal);
+ s.writeObject(POSTFIX);
+ f.close();
+
+ FileInputStream in = new FileInputStream(FILENAME);
+ ObjectInputStream t = new ObjectInputStream(in);
+ String pre = (String)t.readObject();
+ Calendar c = (Calendar)t.readObject();
+ String post = (String)t.readObject();
+ in.close();
+
+ ok = pre.equals(PREFIX) &&
+ post.equals(POSTFIX) &&
+ cal.equals(c);
+
+ File fl = new File(FILENAME);
+ fl.delete();
+ }
+ catch (IOException e) {
+ errln("FAIL: Exception received:");
+ // e.printStackTrace(log);
+ }
+ catch (ClassNotFoundException e) {
+ errln("FAIL: Exception received:");
+ // e.printStackTrace(log);
+ }
+
+ if (!ok) errln("Serialization of Calendar object failed.");
+ }
+ static final String PREFIX = "abc";
+ static final String POSTFIX = "def";
+ static final String FILENAME = "tmp337.bin";
+
+ // Try to zero out the seconds field
+ public void TestSecondsZero121() {
+ Calendar cal = new GregorianCalendar();
+ // Initialize with current date/time
+ cal.setTime(new Date());
+ // Round down to minute
+ cal.set(Calendar.SECOND, 0);
+ Date d = cal.getTime();
+ String s = d.toString();
+ if (s.indexOf(":00 ") < 0) errln("Expected to see :00 in " + s);
+ }
+
+ // Try various sequences of add, set, and get method calls.
+ public void TestAddSetGet0610() {
+ //
+ // Error case 1:
+ // - Upon initialization calendar fields, millis = System.currentTime
+ // - After set is called fields are initialized, time is not
+ // - Addition uses millis which are still *now*
+ //
+ {
+ Calendar calendar = new GregorianCalendar( ) ;
+ calendar.set( 1993, Calendar.JANUARY, 4 ) ;
+ logln( "1A) " + value( calendar ) ) ;
+ calendar.add( Calendar.DATE, 1 ) ;
+ String v = value(calendar);
+ logln( "1B) " + v );
+ logln( "--) 1993/0/5" ) ;
+ if (!v.equals(EXPECTED_0610)) errln("Expected " + EXPECTED_0610 +
+ "; saw " + v);
+ }
+
+ //
+ // Error case 2:
+ // - Upon initialization calendar fields set, millis = 0
+ // - Addition uses millis which are still 1970, 0, 1
+ //
+
+ {
+ Calendar calendar = new GregorianCalendar( 1993, Calendar.JANUARY, 4 ) ;
+ logln( "2A) " + value( calendar ) ) ;
+ calendar.add( Calendar.DATE, 1 ) ;
+ String v = value(calendar);
+ logln( "2B) " + v );
+ logln( "--) 1993/0/5" ) ;
+ if (!v.equals(EXPECTED_0610)) errln("Expected " + EXPECTED_0610 +
+ "; saw " + v);
+ }
+
+ //
+ // Error case 3:
+ // - Upon initialization calendar fields, millis = 0
+ // - getTime( ) is called which forces the millis to be set
+ // - Addition uses millis which are correct
+ //
+
+ {
+ Calendar calendar = new GregorianCalendar( 1993, Calendar.JANUARY, 4 ) ;
+ logln( "3A) " + value( calendar ) ) ;
+ calendar.getTime( ) ;
+ calendar.add( Calendar.DATE, 1 ) ;
+ String v = value(calendar);
+ logln( "3B) " + v ) ;
+ logln( "--) 1993/0/5" ) ;
+ if (!v.equals(EXPECTED_0610)) errln("Expected " + EXPECTED_0610 +
+ "; saw " + v);
+ }
+ }
+ static String value( Calendar calendar ) {
+ return( calendar.get( Calendar.YEAR ) + "/" +
+ calendar.get( Calendar.MONTH ) + "/" +
+ calendar.get( Calendar.DATE ) ) ;
+ }
+ static String EXPECTED_0610 = "1993/0/5";
+
+ // Test that certain fields on a certain date are as expected.
+ public void TestFields060() {
+ int year = 1997;
+ int month = java.util.Calendar.OCTOBER; //october
+ int dDate = 22; //DAYOFWEEK should return 3 for Wednesday
+ GregorianCalendar calendar = null;
+
+ calendar = new GregorianCalendar( year, month, dDate);
+ for (int i = 0; i < EXPECTED_FIELDS.length; ) {
+ int field = EXPECTED_FIELDS[i++];
+ int expected = EXPECTED_FIELDS[i++];
+ if (calendar.get(field) != expected) {
+ errln("Expected field " + field + " to have value " + expected +
+ "; received " + calendar.get(field) + " instead");
+ }
+ }
+ }
+ static int EXPECTED_FIELDS[] = {
+ Calendar.YEAR, 1997,
+ Calendar.MONTH, Calendar.OCTOBER,
+ Calendar.DAY_OF_MONTH, 22,
+ Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY,
+ Calendar.DAY_OF_WEEK_IN_MONTH, 4,
+ Calendar.DAY_OF_YEAR, 295
+ };
+
+ static final String[] calendarFieldNames = {
+ /* 0 */ "ERA",
+ /* 1 */ "YEAR",
+ /* 2 */ "MONTH",
+ /* 3 */ "WEEK_OF_YEAR",
+ /* 4 */ "WEEK_OF_MONTH",
+ /* 5 */ "DAY_OF_MONTH",
+ /* 6 */ "DAY_OF_YEAR",
+ /* 7 */ "DAY_OF_WEEK",
+ /* 8 */ "DAY_OF_WEEK_IN_MONTH",
+ /* 9 */ "AM_PM",
+ /* 10 */ "HOUR",
+ /* 11 */ "HOUR_OF_DAY",
+ /* 12 */ "MINUTE",
+ /* 13 */ "SECOND",
+ /* 14 */ "MILLISECOND",
+ /* 15 */ "ZONE_OFFSET",
+ /* 16 */ "DST_OFFSET"
+ };
+
+ // Verify that the fields are as expected (mostly zero) at the epoch start.
+ // Note that we adjust for the default timezone to get most things to zero.
+ public void TestEpochStartFields() {
+ if (Locale.getDefault().equals(new Locale("th", "TH"))) {
+ return;
+ }
+
+ String[][] lt = {
+ {"en", "US", "US/Pacific"}, /* First day = 1, Minimum day = 1 */
+ {"en", "US", "America/Anchorage"}, /* First day = 1, Minimum day = 1 */
+ {"en", "TO", "Pacific/Tongatapu"}, /* First day = 1, Minimum day = 1 */
+ {"en", "MH", "Pacific/Majuro"}, /* First day = 1, Minimum day = 1 */
+ {"ja", "JP", "Asia/Tokyo"}, /* First day = 1, Minimum day = 1 */
+ {"iw", "IL", "Asia/Jerusalem"}, /* First day = 1, Minimum day = 1 */
+ {"hi", "IN", "Asia/Jakarta"}, /* First day = 1, Minimum day = 1 */
+ {"en", "GB", "Europe/London"}, /* First day = 2, Minimum day = 1 */
+ {"en", "GB", "GMT"}, /* First day = 2, Minimum day = 1 */
+ {"de", "DE", "Europe/Berlin"}, /* First day = 2, Minimum day = 4 */
+ {"ar", "EG", "Africa/Cairo"}, /* First day = 7, Minimum day = 1 */
+ };
+
+ int[][] goldenData = {
+ {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, -28800000, 0},
+ {1, 1969, 11, 1, 5, 31, 365, 4, 5, 1, 11, 23, 0, 0, 0, -36000000, 0},
+ {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 46800000, 0},
+ {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 43200000, 0},
+ {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 32400000, 0},
+ {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 7200000, 0},
+ {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 25200000, 0},
+ {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 1, 1, 0, 0, 0, 3600000, 0},
+ {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 3600000, 0},
+ {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 7200000, 0},
+ };
+
+ Locale savedLocale = Locale.getDefault();
+ TimeZone savedTimeZone = TimeZone.getDefault();
+
+ try {
+ for (int j = 0; j < lt.length; j++) {
+ Locale l = new Locale(lt[j][0], lt[j][1]);
+ TimeZone z = TimeZone.getTimeZone(lt[j][2]);
+ Locale.setDefault(l);
+ TimeZone.setDefault(z);
+ Calendar c = Calendar.getInstance();
+ Date d = new Date(-z.getRawOffset());
+
+ int val;
+ int[] EPOCH_FIELDS = goldenData[j];
+ c.setTime(d);
+
+ boolean err = false;
+ for (int i = 0; i < calendarFieldNames.length; ++i) {
+ if ((val = c.get(i)) != EPOCH_FIELDS[i]) {
+ errln("Wrong value: " + val +
+ " for field(" + calendarFieldNames[i] +
+ "), expected: " + EPOCH_FIELDS[i]);
+ err = true;
+ }
+ }
+ if (err) {
+ errln("Failed: \n\tDate=" + d + "\n\tTimeZone=" + z +
+ "\n\tLocale=" + l + "\n\tCalendar=" + c);
+ }
+ }
+ }
+ finally {
+ Locale.setDefault(savedLocale);
+ TimeZone.setDefault(savedTimeZone);
+ }
+ }
+
+ // Verify that as you add days to the calendar (e.g., 24 day periods),
+ // the day of the week shifts in the expected pattern.
+ public void TestDOWProgression() {
+ Calendar cal =
+ new GregorianCalendar(1972, Calendar.OCTOBER, 26);
+ marchByDelta(cal, 24); // Last parameter must be != 0 modulo 7
+ }
+
+ // Supply a delta which is not a multiple of 7.
+ void marchByDelta(Calendar cal, int delta) {
+ Calendar cur = (Calendar)cal.clone();
+ int initialDOW = cur.get(Calendar.DAY_OF_WEEK);
+ int DOW, newDOW = initialDOW;
+ do {
+ DOW = newDOW;
+ logln("DOW = " + DOW + " " + cur.getTime());
+
+ cur.add(Calendar.DAY_OF_WEEK, delta);
+ newDOW = cur.get(Calendar.DAY_OF_WEEK);
+ int expectedDOW = 1 + (DOW + delta - 1) % 7;
+ if (newDOW != expectedDOW) {
+ errln("Day of week should be " + expectedDOW +
+ " instead of " + newDOW + " on " + cur.getTime());
+ return;
+ }
+ }
+ while (newDOW != initialDOW);
+ }
+
+ public void TestActualMinMax() {
+ Calendar cal = new GregorianCalendar(1967, Calendar.MARCH, 10);
+ cal.setFirstDayOfWeek(Calendar.SUNDAY);
+ cal.setMinimalDaysInFirstWeek(3);
+
+ if (cal.getActualMinimum(Calendar.DAY_OF_MONTH) != 1)
+ errln("Actual minimum date for 3/10/1967 should have been 1; got " +
+ cal.getActualMinimum(Calendar.DAY_OF_MONTH));
+ if (cal.getActualMaximum(Calendar.DAY_OF_MONTH) != 31)
+ errln("Actual maximum date for 3/10/1967 should have been 31; got " +
+ cal.getActualMaximum(Calendar.DAY_OF_MONTH));
+
+ cal.set(Calendar.MONTH, Calendar.FEBRUARY);
+ if (cal.getActualMaximum(Calendar.DAY_OF_MONTH) != 28)
+ errln("Actual maximum date for 2/10/1967 should have been 28; got " +
+ cal.getActualMaximum(Calendar.DAY_OF_MONTH));
+ if (cal.getActualMaximum(Calendar.DAY_OF_YEAR) != 365)
+ errln("Number of days in 1967 should have been 365; got " +
+ cal.getActualMaximum(Calendar.DAY_OF_YEAR));
+
+ cal.set(Calendar.YEAR, 1968);
+ if (cal.getActualMaximum(Calendar.DAY_OF_MONTH) != 29)
+ errln("Actual maximum date for 2/10/1968 should have been 29; got " +
+ cal.getActualMaximum(Calendar.DAY_OF_MONTH));
+ if (cal.getActualMaximum(Calendar.DAY_OF_YEAR) != 366)
+ errln("Number of days in 1968 should have been 366; got " +
+ cal.getActualMaximum(Calendar.DAY_OF_YEAR));
+ // Using week settings of SUNDAY/3 (see above)
+ if (cal.getActualMaximum(Calendar.WEEK_OF_YEAR) != 52)
+ errln("Number of weeks in 1968 should have been 52; got " +
+ cal.getActualMaximum(Calendar.WEEK_OF_YEAR));
+
+ cal.set(Calendar.YEAR, 1976);
+ // Using week settings of SUNDAY/3 (see above)
+ if (cal.getActualMaximum(Calendar.WEEK_OF_YEAR) != 53)
+ errln("Number of weeks in 1976 should have been 53; got " +
+ cal.getActualMaximum(Calendar.WEEK_OF_YEAR));
+ }
+
+ public void TestRoll() {
+ Calendar cal = new GregorianCalendar(1997, Calendar.JANUARY, 31);
+
+ int[] dayValues = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31 };
+
+ for (int i = 0; i < dayValues.length; i++) {
+ Calendar cal2 = (Calendar)cal.clone();
+ cal2.roll(Calendar.MONTH, i);
+ if (cal2.get(Calendar.DAY_OF_MONTH) != dayValues[i])
+ errln("Rolling the month in 1/31/1997 up by " + i + " should have yielded "
+ + ((i + 1) % 12) + "/" + dayValues[i] + "/1997, but actually yielded "
+ + ((i + 1) % 12) + "/" + cal2.get(Calendar.DAY_OF_MONTH) + "/1997.");
+ }
+
+ cal.set(1996, Calendar.FEBRUARY, 29);
+
+ int[] monthValues = { 1, 2, 2, 2, 1, 2, 2, 2, 1, 2 };
+ int[] dayValues2 = { 29, 1, 1, 1, 29, 1, 1, 1, 29, 1 };
+
+ for (int i = 0; i < dayValues2.length; i++) {
+ Calendar cal2 = (Calendar)cal.clone();
+ cal2.roll(Calendar.YEAR, i);
+ if (cal2.get(Calendar.DAY_OF_MONTH) != dayValues2[i] || cal2.get(Calendar.MONTH)
+ != monthValues[i])
+ errln("Rolling the year in 2/29/1996 up by " + i + " should have yielded "
+ + (monthValues[i] + 1) + "/" + dayValues2[i] + "/"
+ + (1996 + i) + ", but actually yielded "
+ + (cal2.get(Calendar.MONTH) + 1) + "/" +
+ cal2.get(Calendar.DAY_OF_MONTH) + "/" + (1996 + i) + ".");
+ }
+
+ // Test rolling hour of day
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.roll(Calendar.HOUR_OF_DAY, -2);
+ int f = cal.get(Calendar.HOUR_OF_DAY);
+ if (f != 22) errln("Rolling HOUR_OF_DAY=0 delta=-2 gave " + f + " Wanted 22");
+ cal.roll(Calendar.HOUR_OF_DAY, 5);
+ f = cal.get(Calendar.HOUR_OF_DAY);
+ if (f != 3) errln("Rolling HOUR_OF_DAY=22 delta=5 gave " + f + " Wanted 3");
+ cal.roll(Calendar.HOUR_OF_DAY, 21);
+ f = cal.get(Calendar.HOUR_OF_DAY);
+ if (f != 0) errln("Rolling HOUR_OF_DAY=3 delta=21 gave " + f + " Wanted 0");
+
+ // Test rolling hour
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.roll(Calendar.HOUR, -2);
+ f = cal.get(Calendar.HOUR);
+ if (f != 10) errln("Rolling HOUR=0 delta=-2 gave " + f + " Wanted 10");
+ cal.roll(Calendar.HOUR, 5);
+ f = cal.get(Calendar.HOUR);
+ if (f != 3) errln("Rolling HOUR=10 delta=5 gave " + f + " Wanted 3");
+ cal.roll(Calendar.HOUR, 9);
+ f = cal.get(Calendar.HOUR);
+ if (f != 0) errln("Rolling HOUR=3 delta=9 gave " + f + " Wanted 0");
+ }
+
+ /*
+ * Confirm that multiple calls to Calendar.set() works correctly.
+ */
+ public void Test4374886() {
+ Locale savedLocale = Locale.getDefault();
+ TimeZone savedTimeZone = TimeZone.getDefault();
+
+ try {
+ Locale.setDefault(Locale.US);
+ TimeZone.setDefault(TimeZone.getTimeZone("PST"));
+
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.YEAR, 2001);
+ cal.set(Calendar.MONTH, Calendar.OCTOBER);
+ cal.set(Calendar.WEEK_OF_YEAR, 4);
+ cal.set(Calendar.DAY_OF_WEEK, 2);
+
+ if (cal.get(Calendar.YEAR) != 2001 ||
+ cal.get(Calendar.MONTH) != Calendar.JANUARY ||
+ cal.get(Calendar.DATE) != 22 ||
+ cal.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
+ errln("Failed : got " + cal.getTime() + ", expected Mon Jan 22, 2001");
+ }
+ }
+ finally {
+ Locale.setDefault(savedLocale);
+ TimeZone.setDefault(savedTimeZone);
+ }
+ }
+}
+
+//eof
diff --git a/jdk/test/java/util/Calendar/FieldStateTest.java b/jdk/test/java/util/Calendar/FieldStateTest.java
new file mode 100644
index 00000000000..caa6f219a24
--- /dev/null
+++ b/jdk/test/java/util/Calendar/FieldStateTest.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4860664 4916815 4867075
+ * @library /java/text/testlib
+ * @build Koyomi
+ * @run main FieldStateTest
+ * @summary Unit tests for internal fields states.
+ */
+
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import static java.util.Calendar.*;
+
+public class FieldStateTest extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ Locale reservedLocale = Locale.getDefault();
+ TimeZone reservedTimeZone = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ Locale.setDefault(Locale.US);
+
+ new FieldStateTest().run(args);
+ } finally {
+ // restore the reserved locale and time zone
+ Locale.setDefault(reservedLocale);
+ TimeZone.setDefault(reservedTimeZone);
+ }
+ }
+
+ public void TestFieldState() {
+ Koyomi cal = new Koyomi();
+ logln("Right after instantialtion:");
+ if (!cal.checkAllSet()) {
+ errln(cal.getMessage());
+ }
+
+ logln("Set date to 2003/10/31 after the instantiation:");
+ cal.set(2003, OCTOBER, 31);
+ // let cal calculate the time
+ cal.getTime();
+ // At this point, all fields have to be recalculated and
+ // happen to have the set-state from the instantiation. The
+ // three fields should have "externally set" and the rest of
+ // the fields have "computed". But we can't distinguish them
+ // outside the package.
+ if (!cal.checkAllSet()) {
+ errln(cal.getMessage());
+ }
+ // Make sure that the correct date was produced.
+ if (!cal.checkInternalDate(2003, OCTOBER, 31, FRIDAY)) {
+ errln(cal.getMessage());
+ }
+
+ logln("Change to Monday of the week, which is 2003/10/27:");
+ cal.set(DAY_OF_WEEK, MONDAY);
+ cal.getTime();
+ if (!cal.checkDate(2003, OCTOBER, 27)) {
+ errln(cal.getMessage());
+ }
+
+ // The same operation didn't work after calling clear() before
+ // 1.5 because the set-state was just depends on its previous
+ // operations. After the instantiation, all the fields are set
+ // to "computed". But after calling clear(), the state becomes
+ // "unset".
+ logln("Set to 2003/10/31 after clear():");
+ cal.clear();
+ cal.set(2003, OCTOBER, 31);
+ cal.getTime();
+ cal.set(DAY_OF_WEEK, MONDAY);
+ if (!cal.checkDate(2003, OCTOBER, 27, MONDAY)) {
+ errln(cal.getMessage());
+ }
+
+ logln("Set to 2003/10/31 after clear(), then to the 51st week of year (12/19):");
+ cal.clear();
+ cal.set(2003, OCTOBER, 31);
+ cal.getTime();
+ cal.set(WEEK_OF_YEAR, 51);
+ if (!cal.checkFieldValue(WEEK_OF_YEAR, 51)) {
+ errln(cal.getMessage());
+ }
+ if (!cal.checkDate(2003, DECEMBER, 19, FRIDAY)) {
+ errln(cal.getMessage());
+ }
+
+ logln("Set to 2003/10 Mon of 4th week (10/20: 43rd week of year, 293rd day):");
+ cal.clear();
+ cal.set(YEAR, 2003);
+ cal.set(MONTH, OCTOBER);
+ cal.set(DAY_OF_WEEK, MONDAY);
+ cal.set(WEEK_OF_MONTH, 4);
+ cal.getTime();
+ if (!cal.checkFieldValue(DAY_OF_MONTH, 20)) {
+ errln(cal.getMessage());
+ }
+ if (!cal.checkFieldValue(DAY_OF_YEAR, 293)) {
+ errln(cal.getMessage());
+ }
+ if (!cal.checkFieldValue(WEEK_OF_YEAR, 43)) {
+ errln(cal.getMessage());
+ }
+
+ logln("Set to 2003/10 Mon of 43rd week of year (10/20: 4th week of month, 293rd day):");
+ cal.clear();
+ cal.set(YEAR, 2003);
+ cal.set(DAY_OF_WEEK, MONDAY);
+ cal.set(WEEK_OF_YEAR, 43);
+ cal.getTime();
+ if (!cal.checkDate(2003, OCTOBER, 20, MONDAY)) {
+ errln(cal.getMessage());
+ }
+ if (!cal.checkFieldValue(WEEK_OF_MONTH, 4)) {
+ errln(cal.getMessage());
+ }
+ if (!cal.checkFieldValue(DAY_OF_YEAR, 293)) {
+ errln(cal.getMessage());
+ }
+
+ logln("Set day of week to SUNDAY and date to 2003/10/31. "
+ + "Then, getTime and set week of year to 43.");
+ cal.setTime(new Date(2003-1990, OCTOBER, 31));
+ cal.set(DAY_OF_WEEK, SUNDAY);
+ cal.set(2003, OCTOBER, 31); // 2003/10/31 is Friday.
+ cal.set(ZONE_OFFSET, 0);
+ cal.set(DST_OFFSET, 0);
+
+ // This call should change the day of week to FRIDAY since the
+ // selected field combination should be YEAR, MONTH and
+ // DAY_OF_MONTH. The other calendar fields must be normalized
+ // with the selected date.
+ cal.getTime();
+ cal.set(WEEK_OF_YEAR, 43);
+ if (!cal.checkDate(2003, OCTOBER, 24, FRIDAY)) {
+ errln(cal.getMessage());
+ }
+ }
+
+ /*
+ * 4916815: REGRESSION: Problem with java.util.Calendar VM 1.4.2-b28
+ */
+ public void Test4916815() {
+ logln("Set date to 2003/9/26 (Fri). Roll to Aug and back to Sep. "+
+ "Set dayofweek to Sunday which should be 2003/9/21.");
+ Koyomi cal = new Koyomi();
+ cal.clear();
+ // 2003/9/26 (Fri)
+ cal.set(2003, SEPTEMBER, 26);
+ // Go to August then back to September
+ cal.roll(MONTH, -1);
+ cal.roll(MONTH, +1);
+ Koyomi cal2 = (Koyomi) cal.clone();
+ cal2.getTime();
+ // Sunday of the week should be 2003/9/21.
+ cal2.set(DAY_OF_WEEK, SUNDAY);
+ if (!cal2.checkDate(2003, SEPTEMBER, 21, SUNDAY)) {
+ errln(cal2.getMessage());
+ }
+ }
+
+ /*
+ * 4867075: GregorianCalendar get() calls complete() internally, should getTime() too?
+ */
+ public void Test4867075() {
+ Koyomi cal = new Koyomi(Locale.US);
+ cal.clear();
+ cal.set(YEAR, 2004);
+ cal.set(WEEK_OF_YEAR, 1);
+ checkDate(cal, SUNDAY, 2003, DECEMBER, 28);
+ checkDate(cal, MONDAY, 2003, DECEMBER, 29);
+ checkDate(cal, TUESDAY, 2003, DECEMBER, 30);
+ checkDate(cal, WEDNESDAY, 2003, DECEMBER, 31);
+ checkDate(cal, THURSDAY, 2004, JANUARY, 1);
+ checkDate(cal, FRIDAY, 2004, JANUARY, 2);
+ checkDate(cal, SATURDAY, 2004, JANUARY, 3);
+ }
+
+ private void checkDate(Koyomi cal, int dayOfWeek,
+ int expectedYear, int expectedMonth, int expectedDayOfMonth) {
+ cal.set(DAY_OF_WEEK, dayOfWeek);
+ cal.getTime();
+ if (!cal.checkInternalDate(expectedYear, expectedMonth, expectedDayOfMonth, dayOfWeek)) {
+ errln(cal.getMessage());
+ }
+ }
+
+ static String toHexString(int x) {
+ return Integer.toHexString(x);
+ }
+}
diff --git a/jdk/test/java/util/Calendar/GregorianCutoverTest.java b/jdk/test/java/util/Calendar/GregorianCutoverTest.java
new file mode 100644
index 00000000000..bd743ae19f6
--- /dev/null
+++ b/jdk/test/java/util/Calendar/GregorianCutoverTest.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4359204 4928615 4743587 4956232 6459836 6549953
+ * @library /java/text/testlib
+ * @build Koyomi
+ * @run main GregorianCutoverTest
+ * @summary Unit tests related to the Gregorian cutover support.
+ */
+
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import static java.util.GregorianCalendar.*;
+
+public class GregorianCutoverTest extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ TimeZone tz = TimeZone.getDefault();
+ Locale lc = Locale.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ Locale.setDefault(Locale.US);
+
+ new GregorianCutoverTest().run(args);
+ } finally {
+ TimeZone.setDefault(tz);
+ Locale.setDefault(lc);
+ }
+ }
+
+ /**
+ * 4359204: GregorianCalendar.get(cal.DAY_OF_YEAR) is inconsistent for year 1582
+ */
+ public void Test4359204() {
+ Koyomi cal = new Koyomi();
+
+ cal.set(1582, JANUARY, 1);
+ checkContinuity(cal, DAY_OF_YEAR);
+ checkContinuity(cal, WEEK_OF_YEAR);
+ cal.set(1582, OCTOBER, 1);
+ checkContinuity(cal, WEEK_OF_MONTH);
+
+ // JCK tests the cutover date 1970-1-1 (Epoch)
+ cal.setGregorianChange(new Date(0));
+ cal.set(1969, JANUARY, 1);
+ checkContinuity(cal, DAY_OF_YEAR);
+ checkContinuity(cal, WEEK_OF_YEAR);
+ cal.set(1969, DECEMBER, 1);
+ checkContinuity(cal, WEEK_OF_MONTH);
+ cal.set(1970, JANUARY, 1);
+ checkContinuity(cal, DAY_OF_YEAR);
+ checkContinuity(cal, WEEK_OF_YEAR);
+
+ // Use large date (year >= 50000)
+ cal.setGregorianChange(new Date(50000-1900, JANUARY, 20));
+ cal.set(49998, JANUARY, 1);
+ checkContinuity(cal, DAY_OF_YEAR);
+ checkContinuity(cal, WEEK_OF_YEAR);
+ cal.set(49999, JANUARY, 1);
+ checkContinuity(cal, DAY_OF_YEAR);
+ checkContinuity(cal, WEEK_OF_YEAR);
+ cal.set(50000, JANUARY, 20);
+ checkContinuity(cal, DAY_OF_YEAR);
+ checkContinuity(cal, WEEK_OF_YEAR);
+
+ // Handling of "overlapping" dates may still be incorrect as
+ // of 1.5. Also, there's no way to disambiguate "overlapping"
+ // dates.
+ // millis=-112033929600000: date=-1581-10-15T00:00:00.000Z
+ cal.setGregorianChange(new Date(-112033929600000L));
+ cal.set(ERA, AD);
+ cal.set(-1581, JANUARY, 1);
+ // The year should have 379 days.
+ checkContinuity(cal, DAY_OF_YEAR);
+ checkContinuity(cal, WEEK_OF_YEAR);
+
+ logln("Default cutover");
+ cal = new Koyomi();
+ cal.set(1582, OCTOBER, 1);
+ logln(" roll --DAY_OF_MONTH from 1582/10/01");
+ cal.roll(DAY_OF_MONTH, -1);
+ if (!cal.checkDate(1582, OCTOBER, 31)) {
+ errln(cal.getMessage());
+ }
+ logln(" roll DAY_OF_MONTH+10 from 1582/10/31");
+ cal.roll(DAY_OF_MONTH, +10);
+ if (!cal.checkDate(1582, OCTOBER, 20)) {
+ errln(cal.getMessage());
+ }
+ logln(" roll DAY_OF_MONTH-10 from 1582/10/20");
+ cal.roll(DAY_OF_MONTH, -10);
+ if (!cal.checkDate(1582, OCTOBER, 31)) {
+ errln(cal.getMessage());
+ }
+ logln(" roll back one day further");
+ cal.roll(DAY_OF_MONTH, +1);
+ if (!cal.checkDate(1582, OCTOBER, 1)) {
+ errln(cal.getMessage());
+ }
+
+ // should handle the gap between 1969/12/22 (Julian) to 1970/1/5 (Gregorian)
+ logln("Cutover date is 1970/1/5");
+ cal.setGregorianChange(new Date(1970-1900, JANUARY, 5));
+ cal.set(ERA, AD);
+ cal.set(YEAR, 1970);
+ logln(" Set DAY_OF_YEAR to the 28th day of 1970");
+ cal.set(DAY_OF_YEAR, 28);
+ if (!cal.checkDate(1970, FEBRUARY, 1)) {
+ errln(cal.getMessage());
+ }
+ if (!cal.checkFieldValue(WEEK_OF_YEAR, 5)) {
+ errln(cal.getMessage());
+ }
+ logln(" 1969/12/22 should be the 356th day of the year.");
+ cal.set(1969, DECEMBER, 22);
+ if (!cal.checkFieldValue(DAY_OF_YEAR, 356)) {
+ errln(cal.getMessage());
+ }
+ logln(" Set DAY_OF_YEAR to autual maximum.");
+ int actualMaxDayOfYear = cal.getActualMaximum(DAY_OF_YEAR);
+ if (actualMaxDayOfYear != 356) {
+ errln("actual maximum of DAY_OF_YEAR: got " + actualMaxDayOfYear + ", expected 356");
+ }
+ cal.set(DAY_OF_YEAR, actualMaxDayOfYear);
+ if (!cal.checkDate(1969, DECEMBER, 22)) {
+ errln(cal.getMessage());
+ }
+ cal.set(1969, DECEMBER, 22);
+ cal.roll(DAY_OF_YEAR, +1);
+ logln(" Set to 1969/12/22 and roll DAY_OF_YEAR++");
+ if (!cal.checkDate(1969, JANUARY, 1)) {
+ errln(cal.getMessage());
+ }
+ logln(" 1970/1/5 should be the first day of the year.");
+ cal.set(1970, JANUARY, 5);
+ if (!cal.checkFieldValue(DAY_OF_YEAR, 1)) {
+ errln(cal.getMessage());
+ }
+ logln(" roll --DAY_OF_MONTH from 1970/1/5");
+ cal.roll(DAY_OF_MONTH, -1);
+ if (!cal.checkDate(1970, JANUARY, 31)) {
+ errln(cal.getMessage());
+ }
+ logln(" roll back one day of month");
+ cal.roll(DAY_OF_MONTH, +1);
+ if (!cal.checkDate(1970, JANUARY, 5)) {
+ errln(cal.getMessage());
+ }
+
+ // Test "missing" dates in non-lenient.
+ cal = new Koyomi(); // new instance for the default cutover
+ cal.setLenient(false);
+ try {
+ // the next day of 1582/10/4 (Julian) is 1582/10/15 (Gregorian)
+ logln("1582/10/10 doesn't exit with the default cutover.");
+ cal.set(1582, OCTOBER, 10);
+ cal.getTime();
+ errln(" Didn't throw IllegalArgumentException in non-lenient.");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ private void checkContinuity(Koyomi cal, int field) {
+ cal.getTime();
+ logln(Koyomi.getFieldName(field) + " starting on " + cal.toDateString());
+ int max = cal.getActualMaximum(field);
+ for (int i = 1; i <= max; i++) {
+ logln(i + " " + cal.toDateString());
+ if (!cal.checkFieldValue(field, i)) {
+ errln(" " + cal.toDateString() + ":\t" + cal.getMessage());
+ }
+ cal.add(field, +1);
+ }
+ }
+
+ /**
+ * 4928615: GregorianCalendar returns wrong dates after setGregorianChange
+ */
+ public void Test4928615() {
+ Koyomi cal = new Koyomi();
+ logln("Today is 2003/10/1 Gregorian.");
+ Date x = new Date(2003-1900, 10-1, 1);
+ cal.setTime(x);
+
+ logln(" Changing the cutover date to yesterday...");
+ cal.setGregorianChange(new Date(x.getTime() - (24*3600*1000)));
+ if (!cal.checkDate(2003, OCTOBER, 1)) {
+ errln(" " + cal.getMessage());
+ }
+ logln(" Changing the cutover date to tomorrow...");
+ cal.setGregorianChange(new Date(x.getTime() + (24*3600*1000)));
+ if (!cal.checkDate(2003, SEPTEMBER, 18)) {
+ errln(" " + cal.getMessage());
+ }
+ }
+
+ /**
+ * 4743587: GregorianCalendar.getLeastMaximum() returns wrong values
+ */
+ public void Test4743587() {
+ Koyomi cal = new Koyomi();
+ Koyomi cal2 = (Koyomi) cal.clone();
+ logln("getLeastMaximum should handle cutover year.\n"
+ +" default cutover date");
+ if (!cal.checkLeastMaximum(DAY_OF_YEAR, 365-10)) {
+ errln(" " + cal.getMessage());
+ }
+ if (!cal.checkLeastMaximum(WEEK_OF_YEAR, 52-((10+6)/7))) {
+ errln(" " + cal.getMessage());
+ }
+ // Corrected for 4956232
+ if (!cal.checkLeastMaximum(DAY_OF_MONTH, 28)) {
+ errln(" " + cal.getMessage());
+ }
+ if (!cal.checkLeastMaximum(WEEK_OF_MONTH, 3)) {
+ errln(" " + cal.getMessage());
+ }
+ if (!cal.checkLeastMaximum(DAY_OF_WEEK_IN_MONTH, 3)) {
+ errln(" " + cal.getMessage());
+ }
+ // make sure that getLeastMaximum calls didn't affect the date
+ if (!cal.equals(cal2)) {
+ errln(" getLeastMaximum calls modified the object.");
+ }
+ if (!cal.checkGreatestMinimum(DAY_OF_MONTH, 1)) {
+ errln(" " + cal.getMessage());
+ }
+
+ logln(" changing the date to 1582/10/20 for actual min/max tests");
+ cal.set(1582, OCTOBER, 20);
+ if (!cal.checkActualMinimum(DAY_OF_MONTH, 1)) {
+ errln(" " + cal.getMessage());
+ }
+ if (!cal.checkActualMaximum(DAY_OF_MONTH, 31)) {
+ errln(" " + cal.getMessage());
+ }
+
+ cal = new Koyomi();
+ logln("Change the cutover date to 1970/1/5.");
+ cal.setGregorianChange(new Date(1970-1900, 0, 5));
+ if (!cal.checkLeastMaximum(DAY_OF_YEAR, 356)) {
+ errln(" " + cal.getMessage());
+ }
+ if (!cal.checkLeastMaximum(DAY_OF_MONTH, 22)) {
+ errln(" " + cal.getMessage());
+ }
+ if (!cal.checkGreatestMinimum(DAY_OF_MONTH, 5)) {
+ errln(" " + cal.getMessage());
+ }
+ cal.set(1970, JANUARY, 10);
+ if (!cal.checkActualMinimum(DAY_OF_MONTH, 5)) {
+ errln(" " + cal.getMessage());
+ }
+ if (!cal.checkActualMaximum(DAY_OF_MONTH, 31)) {
+ errln(" " + cal.getMessage());
+ }
+ }
+
+ /**
+ * 6459836: (cal) GregorianCalendar set method provides wrong result
+ */
+ public void Test6459836() {
+ int hour = 13865672;
+ Koyomi gc1 = new Koyomi();
+ gc1.clear();
+ gc1.set(1, gc1.JANUARY, 1, 0, 0, 0);
+ gc1.set(gc1.HOUR_OF_DAY, hour);
+ if (!gc1.checkDate(1582, gc1.OCTOBER, 4)) {
+ errln("test case 1: " + gc1.getMessage());
+ }
+ gc1.clear();
+ gc1.set(1, gc1.JANUARY, 1, 0, 0, 0);
+ gc1.set(gc1.HOUR_OF_DAY, hour + 24);
+ if (!gc1.checkDate(1582, gc1.OCTOBER, 15)) {
+ errln("test case 2: " + gc1.getMessage());
+ }
+ }
+
+ /**
+ * 6549953 (cal) WEEK_OF_YEAR and DAY_OF_YEAR calculation problems around Gregorian cutover
+ */
+ public void Test6549953() {
+ Koyomi cal = new Koyomi();
+
+ cal.set(YEAR, 1582);
+ cal.set(WEEK_OF_YEAR, 42);
+ cal.set(DAY_OF_WEEK, FRIDAY);
+ cal.checkFieldValue(WEEK_OF_YEAR, 42);
+ cal.checkFieldValue(DAY_OF_WEEK, FRIDAY);
+ if (!cal.checkDate(1582, OCTOBER, 29)) {
+ errln(cal.getMessage());
+ }
+ cal.clear();
+ cal.set(1582, OCTOBER, 1);
+ cal.set(DAY_OF_YEAR, 292);
+ if (!cal.checkDate(1582, OCTOBER, 29)) {
+ errln(cal.getMessage());
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/JulianTest.java b/jdk/test/java/util/Calendar/JulianTest.java
new file mode 100644
index 00000000000..bd7105bce89
--- /dev/null
+++ b/jdk/test/java/util/Calendar/JulianTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2004, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 5029449
+ * @summary Tests for the Julian calendar system (before the Gregorian cutover)
+ * @library /java/text/testlib
+ */
+
+import static java.util.GregorianCalendar.*;
+
+public class JulianTest extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new JulianTest().run(args);
+ }
+
+ /*
+ * 5029449: Regression: GregorianCalendar produces wrong Julian calendar dates in BC 1
+ */
+ public void Test5029449() {
+ Koyomi cal = new Koyomi();
+ cal.clear();
+ cal.set(1, JANUARY, 0);
+ // Date should be BC 1/12/31
+ if (!cal.checkFieldValue(ERA, BC)
+ || !cal.checkDate(1, DECEMBER, 31)) {
+ errln(cal.getMessage());
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/Koyomi.java b/jdk/test/java/util/Calendar/Koyomi.java
new file mode 100644
index 00000000000..8eec03b5de4
--- /dev/null
+++ b/jdk/test/java/util/Calendar/Koyomi.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static java.util.Calendar.*;
+
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * GregorianCalendar subclass for testing.
+ */
+public class Koyomi extends GregorianCalendar {
+ static final String[] FIELD_NAMES = {
+ "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH",
+ "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR",
+ "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET",
+ "DST_OFFSET"
+ };
+
+ static final int ALL_FIELDS = (1 << FIELD_COUNT) - 1;
+
+ public Koyomi() {
+ }
+
+ public Koyomi(TimeZone tz) {
+ super(tz);
+ }
+
+ public Koyomi(Locale loc) {
+ super(loc);
+ }
+
+ public Koyomi(TimeZone tz, Locale loc) {
+ super(tz, loc);
+ }
+
+ @Override
+ public void computeTime() {
+ super.computeTime();
+ }
+
+ @Override
+ public void computeFields() {
+ super.computeFields();
+ }
+
+ @Override
+ public void complete() {
+ super.complete();
+ }
+
+ static String getFieldName(int field) {
+ return FIELD_NAMES[field];
+ }
+
+ String toDateString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(internalGet(ERA) == 0 ? "BCE " : "");
+ sb.append(internalGet(YEAR)).append('-');
+ sb.append(internalGet(MONTH)+1).append('-');
+ sb.append(internalGet(DAY_OF_MONTH));
+ return sb.toString();
+ }
+
+ String toTimeString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(internalGet(HOUR_OF_DAY)).append(':');
+ sb.append(internalGet(MINUTE)).append(':');
+ sb.append(internalGet(SECOND)).append('.');
+ int ms = internalGet(MILLISECOND);
+ if (ms < 100) {
+ sb.append('0');
+ if (ms < 10) {
+ sb.append('0');
+ }
+ }
+ sb.append(ms);
+ int offset = internalGet(ZONE_OFFSET) + internalGet(DST_OFFSET);
+ offset /= 60000;
+ offset = (offset/60) * 100 + (offset%60);
+ if (offset >= 0) {
+ sb.append('+');
+ } else {
+ sb.append('-');
+ offset = -offset;
+ }
+ if (offset < 1000) {
+ sb.append('0');
+ if (offset < 100) {
+ sb.append('0');
+ }
+ }
+ sb.append(offset);
+ return sb.toString();
+ }
+
+ String toDateTimeString() {
+ return toDateString() + "T" + toTimeString();
+ }
+
+ StringBuilder msg = new StringBuilder();
+
+ void initTest() {
+ msg = new StringBuilder();
+ }
+
+ String getMessage() {
+ String s = msg.toString();
+ msg = new StringBuilder();
+ return " " + s;
+ }
+
+ void setMessage(String msg) {
+ this.msg = new StringBuilder(msg);
+ }
+
+ void appendMessage(String msg) {
+ this.msg.append(msg);
+ }
+
+ boolean getStatus() {
+ return msg.length() == 0;
+ }
+
+ int getSetStateFields() {
+ int mask = 0;
+ for (int i = 0; i < FIELD_COUNT; i++) {
+ if (isSet(i)) {
+ mask |= 1 << i;
+ }
+ }
+ return mask;
+ }
+
+ int[] getFields() {
+ int[] fds = new int[fields.length];
+ System.arraycopy(fields, 0, fds, 0, fds.length);
+ return fds;
+ }
+
+ boolean checkAllSet() {
+ initTest();
+ for (int i = 0; i < FIELD_COUNT; i++) {
+ checkFieldState(i, true);
+ }
+ return getStatus();
+ }
+
+ boolean checkInternalDate(int year, int month, int dayOfMonth) {
+ initTest();
+ checkInternalFieldValue(YEAR, year);
+ checkInternalFieldValue(MONTH, month);
+ checkInternalFieldValue(DAY_OF_MONTH, dayOfMonth);
+ return getStatus();
+ }
+
+ boolean checkInternalDate(int year, int month, int dayOfMonth, int dayOfWeek) {
+ initTest();
+ checkInternalFieldValue(YEAR, year);
+ checkInternalFieldValue(MONTH, month);
+ checkInternalFieldValue(DAY_OF_MONTH, dayOfMonth);
+ checkInternalFieldValue(DAY_OF_WEEK, dayOfWeek);
+ return getStatus();
+ }
+
+ boolean checkActualMaximum(int field, int expectedValue) {
+ int val;
+ if ((val = getActualMaximum(field)) != expectedValue) {
+ appendMessage("getActualMaximum("+FIELD_NAMES[field]+"): got " + val
+ + " expected " + expectedValue);
+ }
+ return getStatus();
+ }
+
+ boolean checkLeastMaximum(int field, int expectedValue) {
+ int val;
+ if ((val = getLeastMaximum(field)) != expectedValue) {
+ appendMessage("getLeastMaximum("+FIELD_NAMES[field]+"): got " + val
+ + " expected " + expectedValue);
+ }
+ return getStatus();
+ }
+
+ boolean checkActualMinimum(int field, int expectedValue) {
+ int val;
+ if ((val = getActualMinimum(field)) != expectedValue) {
+ appendMessage("getActualMinimum("+FIELD_NAMES[field]+"): got " + val
+ + " expected " + expectedValue);
+ }
+ return getStatus();
+ }
+
+ boolean checkGreatestMinimum(int field, int expectedValue) {
+ int val;
+ if ((val = getGreatestMinimum(field)) != expectedValue) {
+ appendMessage("getGreatestMinimum("+FIELD_NAMES[field]+"): got " + val
+ + " expected " + expectedValue);
+ }
+ return getStatus();
+ }
+
+ boolean checkDate(int year, int month, int dayOfMonth) {
+ initTest();
+ checkFieldValue(YEAR, year);
+ checkFieldValue(MONTH, month);
+ checkFieldValue(DAY_OF_MONTH, dayOfMonth);
+ return getStatus();
+ }
+
+ boolean checkDate(int year, int month, int dayOfMonth, int dayOfWeek) {
+ initTest();
+ checkFieldValue(YEAR, year);
+ checkFieldValue(MONTH, month);
+ checkFieldValue(DAY_OF_MONTH, dayOfMonth);
+ checkFieldValue(DAY_OF_WEEK, dayOfWeek);
+ return getStatus();
+ }
+
+ boolean checkDateTime(int year, int month, int dayOfMonth,
+ int hourOfDay, int minute, int second, int ms) {
+ initTest();
+ checkFieldValue(YEAR, year);
+ checkFieldValue(MONTH, month);
+ checkFieldValue(DAY_OF_MONTH, dayOfMonth);
+ checkFieldValue(HOUR_OF_DAY, hourOfDay);
+ checkFieldValue(MINUTE, minute);
+ checkFieldValue(SECOND, second);
+ checkFieldValue(MILLISECOND, ms);
+ return getStatus();
+ }
+
+ boolean checkTime(int hourOfDay, int minute, int second, int ms) {
+ initTest();
+ checkFieldValue(HOUR_OF_DAY, hourOfDay);
+ checkFieldValue(MINUTE, minute);
+ checkFieldValue(SECOND, second);
+ checkFieldValue(MILLISECOND, ms);
+ return getStatus();
+ }
+
+ boolean checkFieldState(int field, boolean expectedState) {
+ if (isSet(field) != expectedState) {
+ appendMessage(FIELD_NAMES[field] + " state is not " + expectedState + "; ");
+ return false;
+ }
+ return true;
+ }
+
+ boolean checkFieldValue(int field, int expectedValue) {
+ int val;
+ if ((val = get(field)) != expectedValue) {
+ appendMessage("get(" + FIELD_NAMES[field] + "): got " + val +
+ ", expected " + expectedValue + "; ");
+ return false;
+ }
+ return true;
+ }
+
+ boolean checkInternalFieldValue(int field, int expectedValue) {
+ int val;
+ if ((val = internalGet(field)) != expectedValue) {
+ appendMessage("internalGet(" + FIELD_NAMES[field] + "): got " + val +
+ ", expected " + expectedValue + "; ");
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/jdk/test/java/util/Calendar/Limit.java b/jdk/test/java/util/Calendar/Limit.java
new file mode 100644
index 00000000000..1ab0e172dc8
--- /dev/null
+++ b/jdk/test/java/util/Calendar/Limit.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1997, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.*;
+import java.text.*;
+
+/**
+ * Test GregorianCalendar limits, which should not exist.
+ * @test
+ * @bug 4056585
+ * @summary Make sure that GregorianCalendar works far in the past and future.
+ * @author Alan Liu
+ */
+public class Limit {
+ static final long ONE_DAY = 24*60*60*1000L;
+
+ public static void main(String args[]) throws Exception {
+ GregorianCalendar c = new GregorianCalendar();
+ DateFormat fmt = new SimpleDateFormat("EEEE, MMMM dd, yyyy G", Locale.US);
+ long bigMillis = 300000000000000L;
+
+ try {
+ // We check two things:
+ // 1. That handling millis in the range of +/- bigMillis works.
+ // bigMillis is a value that used to blow up.
+ // 2. The round-trip format/parse works in these extreme areas.
+ c.setTime(new Date(-bigMillis));
+ String s = fmt.format(c.getTime());
+ Date d = fmt.parse(s);
+ if (Math.abs(d.getTime() + bigMillis) >= ONE_DAY) {
+ throw new Exception(s + " != " + fmt.format(d));
+ }
+
+ c.setTime(new Date(+bigMillis));
+ s = fmt.format(c.getTime());
+ d = fmt.parse(s);
+ if (Math.abs(d.getTime() - bigMillis) >= ONE_DAY) {
+ throw new Exception(s + " != " + fmt.format(d));
+ }
+ } catch (IllegalArgumentException | ParseException e) {
+ throw e;
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/NonLenientTest.java b/jdk/test/java/util/Calendar/NonLenientTest.java
new file mode 100644
index 00000000000..6c42c594932
--- /dev/null
+++ b/jdk/test/java/util/Calendar/NonLenientTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4147269 4266783 4726030
+ * @summary Make sure that validation is adequate in non-lenient mode.
+ * @library /java/text/testlib
+ */
+
+import java.util.*;
+
+import static java.util.Calendar.*;
+
+public class NonLenientTest extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ Locale reservedLocale = Locale.getDefault();
+ TimeZone reservedTimeZone = TimeZone.getDefault();
+ try {
+ Locale.setDefault(Locale.US);
+ TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
+ new NonLenientTest().run(args);
+ } finally {
+ // restore the reserved locale and time zone
+ Locale.setDefault(reservedLocale);
+ TimeZone.setDefault(reservedTimeZone);
+ }
+ }
+
+ public void TestValidationInNonLenient() {
+ Koyomi cal = getNonLenient();
+
+ // 2003 isn't a leap year.
+ cal.set(2003, FEBRUARY, 29);
+ validate(cal, "2003/2/29");
+
+ // October has only 31 days.
+ cal.set(2003, OCTOBER, 32);
+ validate(cal, "2003/10/32");
+
+ // 2003/10/31 is Friday.
+ cal.set(2003, OCTOBER, 31);
+ cal.set(DAY_OF_WEEK, SUNDAY);
+ validate(cal, "2003/10/31 SUNDAY");
+
+ // 2003/10/31 is the 304th day of the year.
+ cal.clear();
+ cal.set(DAY_OF_YEAR, 1);
+ cal.set(2003, OCTOBER, 31);
+ validate(cal, "2003/10/31 DAY_OF_YEAR=1");
+
+ // 2003/10 isn't the 1st week of the year.
+ cal.clear();
+ cal.set(YEAR, 2003);
+ cal.set(WEEK_OF_YEAR, 1);
+ cal.set(MONTH, OCTOBER);
+ validate(cal, "2003/10 WEEK_OF_YEAR=1");
+
+ // The 1st week of 2003 doesn't have Monday.
+ cal.clear();
+ cal.set(YEAR, 2003);
+ cal.set(WEEK_OF_YEAR, 1);
+ cal.set(DAY_OF_WEEK, MONDAY);
+ validate(cal, "2003 WEEK_OF_YEAR=1 MONDAY.");
+
+ // 2003 has 52 weeks.
+ cal.clear();
+ cal.set(YEAR, 2003);
+ cal.set(WEEK_OF_YEAR, 53);
+ cal.set(DAY_OF_WEEK, WEDNESDAY);
+ validate(cal, "2003 WEEK_OF_YEAR=53");
+
+ /*
+ * These test cases assume incompatible behavior in Tiger as
+ * the result of the validation bug fixes. However, it looks
+ * like we have to allow applications to set ZONE_OFFSET and
+ * DST_OFFSET values to modify the time zone offsets given by
+ * a TimeZone. The definition of non-leniency for time zone
+ * offsets is somewhat vague. (See 6231602)
+ *
+ * The following test cases are now disabled.
+
+ // America/Los_Angeles is GMT-08:00
+ cal.clear();
+ cal.set(2003, OCTOBER, 31);
+ cal.set(ZONE_OFFSET, 0);
+ validate(cal, "ZONE_OFFSET=0:00 in America/Los_Angeles");
+
+ // 2003/10/31 shouldn't be in DST.
+ cal.clear();
+ cal.set(2003, OCTOBER, 31);
+ cal.set(DST_OFFSET, 60*60*1000);
+ validate(cal, "2003/10/31 DST_OFFSET=1:00 in America/Los_Angeles");
+
+ */
+ }
+
+ /**
+ * 4266783: java.util.GregorianCalendar: incorrect validation in non-lenient
+ */
+ public void Test4266783() {
+ Koyomi cal = getNonLenient();
+ // 2003/1 has up to 5 weeks.
+ cal.set(YEAR, 2003);
+ cal.set(MONTH, JANUARY);
+ cal.set(WEEK_OF_MONTH, 6);
+ cal.set(DAY_OF_WEEK, SUNDAY);
+ validate(cal, "6th Sunday in Jan 2003");
+ }
+
+
+ /**
+ * 4726030: GregorianCalendar doesn't check invalid dates in non-lenient
+ */
+ public void Test4726030() {
+ Koyomi cal = getNonLenient();
+ // Default year is 1970 in GregorianCalendar which isn't a leap year.
+ cal.set(MONTH, FEBRUARY);
+ cal.set(DAY_OF_MONTH, 29);
+ validate(cal, "2/29 in the default year 1970");
+ }
+
+ /**
+ * 4147269: java.util.GregorianCalendar.computeTime() works wrong when lenient is false
+ */
+ public void Test4147269() {
+ Koyomi calendar = getNonLenient();
+ Date date = (new GregorianCalendar(1996,0,3)).getTime();
+
+ for (int field = 0; field < Calendar.FIELD_COUNT; field++) {
+ calendar.setTime(date);
+ int max = calendar.getActualMaximum(field);
+ int value = max+1;
+ calendar.set(field, value);
+ try {
+ calendar.computeTime(); // call method under test
+ errln("Test failed with field " + calendar.getFieldName(field)
+ + "\n\tdate before: " + date
+ + "\n\tdate after: " + calendar.getTime()
+ + "\n\tvalue: " + value + " (max = " + max +")");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ for (int field = 0; field < Calendar.FIELD_COUNT; field++) {
+ calendar.setTime(date);
+ int min = calendar.getActualMinimum(field);
+ int value = min-1;
+ calendar.set(field, value);
+ try {
+ calendar.computeTime(); // call method under test
+ errln("Test failed with field " + calendar.getFieldName(field)
+ + "\n\tdate before: " + date
+ + "\n\tdate after: " + calendar.getTime()
+ + "\n\tvalue: " + value + " (min = " + min +")");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+ }
+
+ void validate(Koyomi cal, String desc) {
+ int[] originalFields = cal.getFields();
+ int setFields = cal.getSetStateFields();
+
+ try {
+ cal.complete();
+ errln(desc + " should throw IllegalArgumentException in non-lenient.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // The code below will be executed with the -nothrow option
+
+ // In non-lenient, calendar field values that have beeb set by
+ // user shouldn't be modified.
+ int[] afterFields = cal.getFields();
+ for (int i = 0; i < Calendar.FIELD_COUNT; i++) {
+ if (cal.isSet(i) && originalFields[i] != afterFields[i]) {
+ errln(" complete() modified fields[" + cal.getFieldName(i) + "] got "
+ + afterFields[i] + ", expected " + originalFields[i]);
+ }
+ }
+ // In non-lenient, set state of fields shouldn't be modified.
+ int afterSetFields = cal.getSetStateFields();
+ if (setFields != afterSetFields) {
+ errln(" complate() modified set states: before 0x" + toHex(setFields)
+ + ", after 0x"+ toHex(afterSetFields));
+ }
+ }
+
+ static Koyomi getNonLenient() {
+ Koyomi cal = new Koyomi();
+ cal.clear();
+ cal.setLenient(false);
+ return cal;
+ }
+
+ static String toHex(int x) {
+ return Integer.toHexString(x);
+ }
+}
diff --git a/jdk/test/java/util/Calendar/ResolutionTest.java b/jdk/test/java/util/Calendar/ResolutionTest.java
new file mode 100644
index 00000000000..98356131b0a
--- /dev/null
+++ b/jdk/test/java/util/Calendar/ResolutionTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2007, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6452848
+ * @summary Make sure that the resolution of (WEKK_OF_MONTH +
+ * DAY_OF_WEEK) and (DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK) works as
+ * specified in the API.
+ * @key randomness
+ */
+
+import java.util.*;
+import static java.util.Calendar.*;
+
+public class ResolutionTest {
+ static Random rand = new Random();
+
+ public static void main(String[] args) {
+ for (int year = 1995; year < 2011; year++) {
+ for (int month = JANUARY; month <= DECEMBER; month++) {
+ for (int dow = SUNDAY; dow <= SATURDAY; dow++) {
+ test(year, month, dow);
+ }
+ }
+ }
+ }
+
+ static void test(int year, int month, int dow) {
+ Calendar cal = new GregorianCalendar(year, month, 1);
+ int max = cal.getActualMaximum(DAY_OF_MONTH);
+ ArrayList list = new ArrayList();
+ for (int d = 1; d <= max; d++) {
+ cal.clear();
+ cal.set(year, month, d);
+ if (cal.get(DAY_OF_WEEK) == dow) {
+ list.add(d);
+ }
+ }
+ for (int i = 0; i < 100; i++) {
+ int nth = rand.nextInt(list.size()); // 0-based
+ int day = list.get(nth);
+ nth++; // 1-based
+ testDayOfWeekInMonth(year, month, nth, dow, day);
+ }
+
+ // Put WEEK_OF_MONTH-DAY_OF_MONTH pairs
+ list = new ArrayList();
+ for (int d = 1; d <= max; d++) {
+ cal.clear();
+ cal.set(year, month, d);
+ if (cal.get(DAY_OF_WEEK) == dow) {
+ list.add(cal.get(WEEK_OF_MONTH));
+ list.add(d);
+ }
+ }
+ for (int i = 0; i < list.size(); i++) {
+ int nth = list.get(i++);
+ int day = list.get(i);
+ testWeekOfMonth(year, month, nth, dow, day);
+ }
+ }
+
+ static Koyomi cal = new Koyomi();
+
+ static void testDayOfWeekInMonth(int year, int month, int nth, int dow, int expected) {
+ // don't call clear() here
+ cal.set(YEAR, year);
+ cal.set(MONTH, month);
+ // Set DAY_OF_WEEK_IN_MONTH before DAY_OF_WEEK
+ cal.set(DAY_OF_WEEK_IN_MONTH, nth);
+ cal.set(DAY_OF_WEEK, dow);
+ if (!cal.checkDate(year, month, expected)) {
+ throw new RuntimeException(String.format("DOWIM: year=%d, month=%d, nth=%d, dow=%d:%s%n",
+ year, month+1, nth, dow, cal.getMessage()));
+ }
+ }
+
+ static void testWeekOfMonth(int year, int month, int nth, int dow, int expected) {
+ // don't call clear() here
+ cal.set(YEAR, year);
+ cal.set(MONTH, month);
+ // Set WEEK_OF_MONTH before DAY_OF_WEEK
+ cal.set(WEEK_OF_MONTH, nth);
+ cal.set(DAY_OF_WEEK, dow);
+ if (!cal.checkDate(year, month, expected)) {
+ throw new RuntimeException(String.format("WOM: year=%d, month=%d, nth=%d, dow=%d:%s%n",
+ year, month+1, nth, dow, cal.getMessage()));
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/RollDayOfWeekTest.java b/jdk/test/java/util/Calendar/RollDayOfWeekTest.java
new file mode 100644
index 00000000000..5b85016c311
--- /dev/null
+++ b/jdk/test/java/util/Calendar/RollDayOfWeekTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2004, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 5090555 5091805
+ * @summary Make sure that rolling DAY_OF_WEEK stays in the same week
+ * around year boundaries.
+ * @run main/othervm RollDayOfWeekTest 5 5
+ */
+
+import java.util.*;
+
+import static java.util.Calendar.*;
+
+// Usage: java RollDayOfWeekTest [pastYears futureYears]
+public class RollDayOfWeekTest {
+ public static void main(String[] args) {
+ int pastYears = 5, futureYears = 23;
+ if (args.length == 2) {
+ pastYears = Integer.parseInt(args[0]);
+ pastYears = Math.max(1, Math.min(pastYears, 5));
+ futureYears = Integer.parseInt(args[1]);
+ futureYears = Math.max(1, Math.min(futureYears, 28));
+ }
+
+ System.out.printf("Test [%d .. %+d] year range.%n", -pastYears, futureYears);
+ Calendar cal = new GregorianCalendar();
+ int year = cal.get(YEAR) - pastYears;
+
+ // Use the all combinations of firstDayOfWeek and
+ // minimalDaysInFirstWeek values in the year range current
+ // year - pastYears to current year + futureYears.
+ for (int fdw = SUNDAY; fdw <= SATURDAY; fdw++) {
+ for (int mdifw = 1; mdifw <= 7; mdifw++) {
+ cal.clear();
+ cal.setFirstDayOfWeek(fdw);
+ cal.setMinimalDaysInFirstWeek(mdifw);
+ cal.set(year, JANUARY, 1);
+ checkRoll(cal, futureYears);
+ }
+ }
+
+ // testing roll from BCE to CE
+ year = -1;
+ for (int fdw = SUNDAY; fdw <= SATURDAY; fdw++) {
+ for (int mdifw = 1; mdifw <= 7; mdifw++) {
+ cal.clear();
+ cal.setFirstDayOfWeek(fdw);
+ cal.setMinimalDaysInFirstWeek(mdifw);
+ cal.set(year, JANUARY, 1);
+ checkRoll(cal, 4);
+ }
+ }
+ }
+
+
+ static void checkRoll(Calendar cal, int years) {
+ Calendar cal2 = null, cal3 = null, prev = null;
+ // Check 28 years
+ for (int x = 0; x < (int)(365.2425*years); x++) {
+ cal2 = (Calendar) cal.clone();
+ cal3 = (Calendar) cal.clone();
+
+ // roll foreword
+ for (int i = 0; i < 10; i++) {
+ prev = (Calendar) cal2.clone();
+ cal2.roll(Calendar.DAY_OF_WEEK, +1);
+ roll(cal3, +1);
+ long t2 = cal2.getTimeInMillis();
+ long t3 = cal3.getTimeInMillis();
+ if (t2 != t3) {
+ System.err.println("prev: " + prev.getTime() + "\n" + prev);
+ System.err.println("cal2: " + cal2.getTime() + "\n" + cal2);
+ System.err.println("cal3: " + cal3.getTime() + "\n" + cal3);
+ throw new RuntimeException("+1: t2=" + t2 + ", t3=" + t3);
+ }
+ }
+
+ // roll backward
+ for (int i = 0; i < 10; i++) {
+ prev = (Calendar) cal2.clone();
+ cal2.roll(Calendar.DAY_OF_WEEK, -1);
+ roll(cal3, -1);
+ long t2 = cal2.getTimeInMillis();
+ long t3 = cal3.getTimeInMillis();
+ if (t2 != t3) {
+ System.err.println("prev: " + prev.getTime() + "\n" + prev);
+ System.err.println("cal2: " + cal2.getTime() + "\n" + cal2);
+ System.err.println("cal3: " + cal3.getTime() + "\n" + cal3);
+ throw new RuntimeException("-1: t2=" + t2 + ", t3=" + t3);
+ }
+ }
+ cal.add(DAY_OF_YEAR, +1);
+ }
+ }
+
+ // Another way to roll within the same week.
+ static void roll(Calendar cal, int n) {
+ int doy = cal.get(DAY_OF_YEAR);
+ int diff = cal.get(DAY_OF_WEEK) - cal.getFirstDayOfWeek();
+ if (diff < 0) {
+ diff += 7;
+ }
+
+ // dow1: first day of the week
+ int dow1 = doy - diff;
+ n %= 7;
+ doy += n;
+ if (doy < dow1) {
+ doy += 7;
+ } else if (doy >= dow1 + 7) {
+ doy -= 7;
+ }
+ cal.set(DAY_OF_YEAR, doy);
+ }
+}
diff --git a/jdk/test/java/util/Calendar/StampOverflow.java b/jdk/test/java/util/Calendar/StampOverflow.java
new file mode 100644
index 00000000000..fc10595c87f
--- /dev/null
+++ b/jdk/test/java/util/Calendar/StampOverflow.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2001, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4404619 6348819
+ * @summary Make sure that Calendar doesn't cause nextStamp overflow.
+ */
+
+import java.lang.reflect.*;
+import java.util.*;
+import static java.util.Calendar.*;
+
+// Calendar fails when turning negative to positive (zero), not
+// positive to negative with nextStamp. If a negative value was set to
+// nextStamp, it would fail even with the fix. So, there's no way to
+// reproduce the symptom in a short time -- at leaset it would take a
+// couple of hours even if we started with Integer.MAX_VALUE. So, this
+// test case just checks that set() calls don't cause any nextStamp
+// overflow.
+
+public class StampOverflow {
+ public static void main(String[] args) throws IllegalAccessException {
+ // Get a Field for "nextStamp".
+ Field nextstamp = null;
+ try {
+ nextstamp = Calendar.class.getDeclaredField("nextStamp");
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException("implementation changed?", e);
+ }
+
+ nextstamp.setAccessible(true);
+
+ Calendar cal = new GregorianCalendar();
+ int initialValue = nextstamp.getInt(cal);
+ // Set nextStamp to a very large number
+ nextstamp.setInt(cal, Integer.MAX_VALUE - 100);
+
+ for (int i = 0; i < 1000; i++) {
+ invoke(cal);
+ int stampValue = nextstamp.getInt(cal);
+ // nextStamp must not be less than initialValue.
+ if (stampValue < initialValue) {
+ throw new RuntimeException("invalid nextStamp: " + stampValue);
+ }
+ }
+ }
+
+ static void invoke(Calendar cal) {
+ cal.clear();
+ cal.set(2000, NOVEMBER, 2, 0, 0, 0);
+ int y = cal.get(YEAR);
+ int m = cal.get(MONTH);
+ int d = cal.get(DAY_OF_MONTH);
+ if (y != 2000 || m != NOVEMBER || d != 2) {
+ throw new RuntimeException("wrong date produced ("
+ + y + "/" + (m+1) + "/" + d + ")");
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/ZoneOffsets.java b/jdk/test/java/util/Calendar/ZoneOffsets.java
new file mode 100644
index 00000000000..147df337497
--- /dev/null
+++ b/jdk/test/java/util/Calendar/ZoneOffsets.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6231602
+ * @summary Make sure that ZONE_OFFSET and/or DST_OFFSET setting is
+ * taken into account for time calculations.
+ */
+
+import java.util.*;
+import static java.util.GregorianCalendar.*;
+
+public class ZoneOffsets {
+ // This TimeZone always returns the dstOffset value.
+ private static class TestTimeZone extends TimeZone {
+ private int gmtOffset;
+ private int dstOffset;
+
+ TestTimeZone(int gmtOffset, String id, int dstOffset) {
+ this.gmtOffset = gmtOffset;
+ setID(id);
+ this.dstOffset = dstOffset;
+ }
+
+ public int getOffset(int era, int year, int month, int day,
+ int dayOfWeek, int milliseconds) {
+ return gmtOffset + dstOffset;
+ }
+
+ public int getOffset(long date) {
+ return gmtOffset + dstOffset;
+ }
+
+ public void setRawOffset(int offsetMillis) {
+ gmtOffset = offsetMillis;
+ }
+
+ public int getRawOffset() {
+ return gmtOffset;
+ }
+
+ public int getDSTSavings() {
+ return dstOffset;
+ }
+
+ public boolean useDaylightTime() {
+ return dstOffset != 0;
+ }
+
+ public boolean inDaylightTime(Date date) {
+ return dstOffset != 0;
+ }
+
+ public String toString() {
+ return "TestTimeZone[" + getID() + ", " + gmtOffset + ", " + dstOffset + "]";
+ }
+ }
+
+ private static Locale[] locales = {
+ Locale.getDefault(),
+ new Locale("th", "TH"),
+ new Locale("ja", "JP", "JP"),
+ };
+
+ private static final int HOUR = 60 * 60 * 1000;
+
+ private static int[][] offsets = {
+ { 0, 0 },
+ { 0, HOUR },
+ { 0, 2 * HOUR },
+ { -8 * HOUR, 0 },
+ { -8 * HOUR, HOUR },
+ { -8 * HOUR, 2 * HOUR },
+ { 9 * HOUR, 0 },
+ { 9 * HOUR, HOUR },
+ { 9 * HOUR, 2 * HOUR },
+ };
+
+ public static void main(String[] args) {
+ for (int l = 0; l < locales.length; l++) {
+ Locale loc = locales[l];
+ for (int i = 0; i < offsets.length; i++) {
+ test(loc, offsets[i][0], offsets[i][1]);
+ }
+ }
+
+ // The test case in the bug report.
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.setLenient(false);
+ cal.setGregorianChange(new Date(Long.MIN_VALUE));
+ cal.clear();
+ cal.set(ZONE_OFFSET, 0);
+ cal.set(DST_OFFSET, 0);
+ cal.set(ERA, AD);
+ cal.set(2004, FEBRUARY, 3, 0, 0, 0);
+ cal.set(MILLISECOND, 0);
+ // The following line should not throw an IllegalArgumentException.
+ cal.getTime();
+ }
+
+ private static void test(Locale loc, int gmtOffset, int dstOffset) {
+ TimeZone tz1 = new TestTimeZone(gmtOffset,
+ "GMT" + (gmtOffset/HOUR) + "." + (dstOffset/HOUR),
+ dstOffset);
+ int someDifferentOffset = gmtOffset + 2 * HOUR;
+ TimeZone tz2 = new TestTimeZone(someDifferentOffset,
+ "GMT"+ (someDifferentOffset/HOUR) + "." + (dstOffset/HOUR),
+ dstOffset);
+
+ int someDifferentDSTOffset = dstOffset == 2 * HOUR ? HOUR : dstOffset + HOUR;
+ TimeZone tz3 = new TestTimeZone(gmtOffset,
+ "GMT"+ (gmtOffset/HOUR) + "." + (someDifferentDSTOffset/HOUR),
+ someDifferentDSTOffset);
+
+ // cal1 is the base line.
+ Calendar cal1 = Calendar.getInstance(tz1, loc);
+ cal1.clear();
+ cal1.set(2005, MARCH, 11);
+ long t1 = cal1.getTime().getTime();
+ int gmt = cal1.get(ZONE_OFFSET);
+ int dst = cal1.get(DST_OFFSET);
+
+ // Test 8 cases with cal2.
+ Calendar cal2 = Calendar.getInstance(tz2, loc);
+ cal2.clear();
+ cal2.set(2005, MARCH, 11);
+ // test1: set only ZONE_OFFSET
+ cal2.set(ZONE_OFFSET, gmtOffset);
+ if (t1 != cal2.getTime().getTime() || dst != cal2.get(DST_OFFSET)) {
+ error("Test1", loc, cal2, gmtOffset, dstOffset, t1);
+ }
+
+ cal2.setTimeZone(tz3);
+ cal2.clear();
+ cal2.set(2005, MARCH, 11);
+ // test2: set only DST_OFFSET
+ cal2.set(DST_OFFSET, dstOffset);
+ if (t1 != cal2.getTime().getTime() || gmt != cal2.get(ZONE_OFFSET)) {
+ error("Test2", loc, cal2, gmtOffset, dstOffset, t1);
+ }
+
+ cal2.setTimeZone(tz2);
+ cal2.clear();
+ cal2.set(2005, MARCH, 11);
+ // test3: set both ZONE_OFFSET and DST_OFFSET
+ cal2.set(ZONE_OFFSET, gmtOffset);
+ cal2.set(DST_OFFSET, dstOffset);
+ if (t1 != cal2.getTime().getTime()) {
+ error("Test3", loc, cal2, gmtOffset, dstOffset, t1);
+ }
+
+ cal2.setTimeZone(tz3);
+ cal2.clear();
+ cal2.set(2005, MARCH, 11);
+ // test4: set both ZONE_OFFSET and DST_OFFSET
+ cal2.set(ZONE_OFFSET, gmtOffset);
+ cal2.set(DST_OFFSET, dstOffset);
+ if (t1 != cal2.getTime().getTime()) {
+ error("Test4", loc, cal2, gmtOffset, dstOffset, t1);
+ }
+
+ // Test the same thing in non-lenient
+ cal2.setLenient(false);
+
+ cal2.setTimeZone(tz2);
+ cal2.clear();
+ cal2.set(2005, MARCH, 11);
+ // test5: set only ZONE_OFFSET in non-lenient
+ cal2.set(ZONE_OFFSET, gmtOffset);
+ if (t1 != cal2.getTime().getTime() || dst != cal2.get(DST_OFFSET)) {
+ error("Test5", loc, cal2, gmtOffset, dstOffset, t1);
+ }
+
+ cal2.setTimeZone(tz3);
+ cal2.clear();
+ cal2.set(2005, MARCH, 11);
+ // test6: set only DST_OFFSET in non-lenient
+ cal2.set(DST_OFFSET, dstOffset);
+ if (t1 != cal2.getTime().getTime() || gmt != cal2.get(ZONE_OFFSET)) {
+ error("Test6", loc, cal2, gmtOffset, dstOffset, t1);
+ }
+
+ cal2.setTimeZone(tz2);
+ cal2.clear();
+ cal2.set(2005, MARCH, 11);
+ // test7: set both ZONE_OFFSET and DST_OFFSET in non-lenient
+ cal2.set(ZONE_OFFSET, gmtOffset);
+ cal2.set(DST_OFFSET, dstOffset);
+ if (t1 != cal2.getTime().getTime()) {
+ error("Test7", loc, cal2, gmtOffset, dstOffset, t1);
+ }
+
+ cal2.setTimeZone(tz3);
+ cal2.clear();
+ cal2.set(2005, MARCH, 11);
+ // test8: set both ZONE_OFFSET and DST_OFFSET in non-lenient
+ cal2.set(ZONE_OFFSET, gmtOffset);
+ cal2.set(DST_OFFSET, dstOffset);
+ if (t1 != cal2.getTime().getTime()) {
+ error("Test8", loc, cal2, gmtOffset, dstOffset, t1);
+ }
+ }
+
+ private static void error(String msg, Locale loc, Calendar cal2, int gmtOffset, int dstOffset, long t1) {
+ System.err.println(cal2);
+ throw new RuntimeException(msg + ": Locale=" + loc
+ + ", gmtOffset=" + gmtOffset + ", dstOffset=" + dstOffset
+ + ", cal1 time=" + t1 + ", cal2 time=" + cal2.getTime().getTime());
+ }
+}
diff --git a/jdk/test/java/util/Calendar/bug4028518.java b/jdk/test/java/util/Calendar/bug4028518.java
new file mode 100644
index 00000000000..982b93adc86
--- /dev/null
+++ b/jdk/test/java/util/Calendar/bug4028518.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1998, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4028518
+ * @summary Make sure cloned GregorianCalendar is unchanged by modifying its original.
+ */
+
+import java.util.GregorianCalendar ;
+import static java.util.Calendar.*;
+
+public class bug4028518 {
+
+ public static void main(String[] args)
+ {
+ GregorianCalendar cal1 = new GregorianCalendar() ;
+ GregorianCalendar cal2 = (GregorianCalendar) cal1.clone() ;
+
+ printdate(cal1, "cal1: ") ;
+ printdate(cal2, "cal2 - cloned(): ") ;
+ cal1.add(DAY_OF_MONTH, 1) ;
+ printdate(cal1, "cal1 after adding 1 day: ") ;
+ printdate(cal2, "cal2 should be unmodified: ") ;
+ if (cal1.get(DAY_OF_MONTH) == cal2.get(DAY_OF_MONTH)) {
+ throw new RuntimeException("cloned GregorianCalendar modified");
+ }
+ }
+
+ private static void printdate(GregorianCalendar cal, String string)
+ {
+ System.out.println(string + (cal.get(MONTH) + 1)
+ + "/" + cal.get(DAY_OF_MONTH)
+ + "/" + cal.get(YEAR)) ;
+ }
+}
diff --git a/jdk/test/java/util/Calendar/bug4100311.java b/jdk/test/java/util/Calendar/bug4100311.java
new file mode 100644
index 00000000000..ef0f36ecbd2
--- /dev/null
+++ b/jdk/test/java/util/Calendar/bug4100311.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1998, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4100311
+ * @summary Make sure set(DAY_OF_YEAR, 1) works.
+ */
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Date;
+
+public class bug4100311
+{
+ @SuppressWarnings("deprecation")
+ public static void main(String args[])
+ {
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.set(Calendar.YEAR, 1997);
+ cal.set(Calendar.DAY_OF_YEAR, 1);
+ Date d = cal.getTime(); // Should be Jan 1
+ if (d.getMonth() != 0 || d.getDate() != 1) {
+ throw new RuntimeException("Date isn't Jan 1");
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/bug4243802.java b/jdk/test/java/util/Calendar/bug4243802.java
new file mode 100644
index 00000000000..1f3b910c1b3
--- /dev/null
+++ b/jdk/test/java/util/Calendar/bug4243802.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2001, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4243802
+ * @summary confirm that Calendar.setTimeInMillis() and
+ * getTimeInMillis() can be called from a user program. (They used to
+ * be protected methods.)
+ * @library /java/text/testlib
+ */
+
+import java.util.*;
+
+public class bug4243802 extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new bug4243802().run(args);
+ }
+
+ /**
+ * 4243802: RFE: need way to set the date of a calendar without a Date object
+ */
+ public void Test4243802() {
+ TimeZone saveZone = TimeZone.getDefault();
+ Locale saveLocale = Locale.getDefault();
+ try {
+ Locale.setDefault(Locale.US);
+ TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
+
+ Calendar cal1 = Calendar.getInstance();
+ Calendar cal2 = Calendar.getInstance();
+
+ cal1.clear();
+ cal2.clear();
+ cal1.set(2001, Calendar.JANUARY, 25, 1, 23, 45);
+ cal2.setTimeInMillis(cal1.getTimeInMillis());
+ if ((cal2.get(Calendar.YEAR) != 2001) ||
+ (cal2.get(Calendar.MONTH) != Calendar.JANUARY) ||
+ (cal2.get(Calendar.DAY_OF_MONTH) != 25) ||
+ (cal2.get(Calendar.HOUR_OF_DAY) != 1) ||
+ (cal2.get(Calendar.MINUTE) != 23) ||
+ (cal2.get(Calendar.SECOND) != 45) ||
+ (cal2.get(Calendar.MILLISECOND) != 0)) {
+ errln("Failed: expected 1/25/2001 1:23:45.000" +
+ ", got " + (cal2.get(Calendar.MONTH)+1) + "/" +
+ cal2.get(Calendar.DAY_OF_MONTH) +"/" +
+ cal2.get(Calendar.YEAR) + " " +
+ cal2.get(Calendar.HOUR_OF_DAY) + ":" +
+ cal2.get(Calendar.MINUTE) + ":" +
+ cal2.get(Calendar.SECOND) + "." +
+ toMillis(cal2.get(Calendar.MILLISECOND)));
+ }
+ logln("Passed.");
+ }
+ finally {
+ Locale.setDefault(saveLocale);
+ TimeZone.setDefault(saveZone);
+ }
+ }
+
+ private String toMillis(int m) {
+ StringBuffer sb = new StringBuffer();
+ if (m < 100) {
+ sb.append('0');
+ }
+ if (m < 10) {
+ sb.append('0');
+ }
+ sb.append(m);
+ return sb.toString();
+ }
+}
diff --git a/jdk/test/java/util/Calendar/bug4316678.java b/jdk/test/java/util/Calendar/bug4316678.java
new file mode 100644
index 00000000000..8ae6bbc294f
--- /dev/null
+++ b/jdk/test/java/util/Calendar/bug4316678.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2000, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+
+/**
+ * @test
+ * @bug 4316678
+ * @summary test that Calendar's Serializasion works correctly.
+ * @library /java/text/testlib
+ */
+public class bug4316678 extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new bug4316678().run(args);
+ }
+
+ public void Test4316678() throws Exception {
+ GregorianCalendar gc1;
+ GregorianCalendar gc2;
+ TimeZone saveZone = TimeZone.getDefault();
+
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("PST"));
+
+ gc1 = new GregorianCalendar(2000, Calendar.OCTOBER, 10);
+ try (ObjectOutputStream out
+ = new ObjectOutputStream(new FileOutputStream("bug4316678.ser"))) {
+ out.writeObject(gc1);
+ }
+
+ try (ObjectInputStream in
+ = new ObjectInputStream(new FileInputStream("bug4316678.ser"))) {
+ gc2 = (GregorianCalendar)in.readObject();
+ }
+
+ gc1.set(Calendar.DATE, 16);
+ gc2.set(Calendar.DATE, 16);
+ if (!gc1.getTime().equals(gc2.getTime())) {
+ errln("Invalid Time :" + gc2.getTime() +
+ ", expected :" + gc1.getTime());
+ }
+ } finally {
+ TimeZone.setDefault(saveZone);
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/bug4372743.java b/jdk/test/java/util/Calendar/bug4372743.java
new file mode 100644
index 00000000000..1800ebc002a
--- /dev/null
+++ b/jdk/test/java/util/Calendar/bug4372743.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2000, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4372743
+ * @summary test that checks transitions of ERA and YEAR which are caused by add(MONTH).
+ * @library /java/text/testlib
+ */
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+
+import static java.util.GregorianCalendar.*;
+
+public class bug4372743 extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new bug4372743().run(args);
+ }
+
+ private int[][] data = {
+ {AD, 2, MARCH},
+ {AD, 2, FEBRUARY},
+ {AD, 2, JANUARY},
+ {AD, 1, DECEMBER},
+ {AD, 1, NOVEMBER},
+ {AD, 1, OCTOBER},
+ {AD, 1, SEPTEMBER},
+ {AD, 1, AUGUST},
+ {AD, 1, JULY},
+ {AD, 1, JUNE},
+ {AD, 1, MAY},
+ {AD, 1, APRIL},
+ {AD, 1, MARCH},
+ {AD, 1, FEBRUARY},
+ {AD, 1, JANUARY},
+ {BC, 1, DECEMBER},
+ {BC, 1, NOVEMBER},
+ {BC, 1, OCTOBER},
+ {BC, 1, SEPTEMBER},
+ {BC, 1, AUGUST},
+ {BC, 1, JULY},
+ {BC, 1, JUNE},
+ {BC, 1, MAY},
+ {BC, 1, APRIL},
+ {BC, 1, MARCH},
+ {BC, 1, FEBRUARY},
+ {BC, 1, JANUARY},
+ {BC, 2, DECEMBER},
+ {BC, 2, NOVEMBER},
+ {BC, 2, OCTOBER},
+ };
+ private int tablesize = data.length;
+
+ private void check(GregorianCalendar gc, int index) {
+ if (gc.get(ERA) != data[index][ERA]) {
+ errln("Invalid era :" + gc.get(ERA) +
+ ", expected :" + data[index][ERA]);
+ }
+ if (gc.get(YEAR) != data[index][YEAR]) {
+ errln("Invalid year :" + gc.get(YEAR) +
+ ", expected :" + data[index][YEAR]);
+ }
+ if (gc.get(MONTH) != data[index][MONTH]) {
+ errln("Invalid month :" + gc.get(MONTH) +
+ ", expected :" + data[index][MONTH]);
+ }
+ }
+
+ public void Test4372743() {
+ GregorianCalendar gc;
+ TimeZone saveZone = TimeZone.getDefault();
+
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("PST"));
+
+ /* Set March 3, A.D. 2 */
+ gc = new GregorianCalendar(2, MARCH, 3);
+ for (int i = 0; i < tablesize; i++) {
+ check(gc, i);
+ gc.add(gc.MONTH, -1);
+ }
+
+ /* Again, Set March 3, A.D. 2 */
+ gc = new GregorianCalendar(2, MARCH, 3);
+ for (int i = 0; i < tablesize; i+=7) {
+ check(gc, i);
+ gc.add(gc.MONTH, -7);
+ }
+
+ /* Set March 10, 2 B.C. */
+ gc = new GregorianCalendar(2, OCTOBER, 10);
+ gc.add(gc.YEAR, -3);
+ for (int i = tablesize -1; i >= 0; i--) {
+ check(gc, i);
+ gc.add(gc.MONTH, 1);
+ }
+
+ /* Again, Set March 10, 2 B.C. */
+ gc = new GregorianCalendar(2, OCTOBER, 10);
+ gc.add(gc.YEAR, -3);
+ for (int i = tablesize -1; i >= 0; i-=8) {
+ check(gc, i);
+ gc.add(gc.MONTH, 8);
+ }
+ }
+ finally {
+ TimeZone.setDefault(saveZone);
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/bug4401223.java b/jdk/test/java/util/Calendar/bug4401223.java
new file mode 100644
index 00000000000..fbd9e29a8f6
--- /dev/null
+++ b/jdk/test/java/util/Calendar/bug4401223.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2001, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4401223
+ * @summary Make sure that GregorianCalendar doesn't cause IllegalArgumentException at some special situations which are related to the Leap Year.
+ * @library /java/text/testlib
+ */
+
+import java.util.*;
+
+public class bug4401223 extends IntlTest {
+
+ public void Test4401223a() {
+ int status = 0;
+ String s = null;
+
+ try {
+ Date date = new Date(2000-1900, Calendar.FEBRUARY, 29);
+ GregorianCalendar gc = new GregorianCalendar();
+ gc.setTime(date);
+ gc.setLenient(false);
+ gc.set(Calendar.YEAR, 2001);
+ s = "02/29/00 & set(YEAR,2001) = " + gc.getTime().toString();
+ } catch (Exception ex) {
+ status++;
+ s = "Exception occurred for 2/29/00 & set(YEAR,2001): " + ex;
+ }
+ if (status > 0) {
+ errln(s);
+ } else {
+ logln(s);
+ }
+ }
+
+ public void Test4401223b() {
+ int status = 0;
+ String s = null;
+
+ try {
+ Date date = new Date(2000-1900, Calendar.DECEMBER, 31);
+ GregorianCalendar gc = new GregorianCalendar();
+ gc.setTime(date);
+ gc.setLenient(false);
+ gc.set(Calendar.YEAR, 2001);
+
+ if (gc.get(Calendar.YEAR) != 2001 ||
+ gc.get(Calendar.MONTH) != Calendar.DECEMBER ||
+ gc.get(Calendar.DATE) != 31 ||
+ gc.get(Calendar.DAY_OF_YEAR) != 365) {
+ status++;
+ s = "Wrong Date : 12/31/00 & set(YEAR,2001) ---> " + gc.getTime().toString();
+ } else {
+ s = "12/31/00 & set(YEAR,2001) = " + gc.getTime().toString();
+ }
+ } catch (Exception ex) {
+ status++;
+ s = "Exception occurred for 12/31/00 & set(YEAR,2001) : " + ex;
+ }
+ if (status > 0) {
+ errln(s);
+ } else {
+ logln(s);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ new bug4401223().run(args);
+ }
+}
diff --git a/jdk/test/java/util/Calendar/bug4409072.java b/jdk/test/java/util/Calendar/bug4409072.java
new file mode 100644
index 00000000000..d8e56a45547
--- /dev/null
+++ b/jdk/test/java/util/Calendar/bug4409072.java
@@ -0,0 +1,683 @@
+/*
+ * Copyright (c) 2001, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4409072
+ * @summary tests for set(), add(), and roll() with various week parameters.
+ * @library /java/text/testlib
+ */
+
+import java.util.*;
+import static java.util.Calendar.*;
+
+public class bug4409072 extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new bug4409072().run(args);
+ }
+
+ /* Confirm some public methods' behavior in Calendar.
+ * (e.g. add(), roll(), set())
+ */
+ public void Test4409072() {
+ if (Locale.getDefault().equals(new Locale("th", "TH"))) {
+ return;
+ }
+
+ Locale savedLocale = Locale.getDefault();
+ TimeZone savedTZ = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ testSet();
+ testAdd();
+ testRoll();
+ } finally {
+ TimeZone.setDefault(savedTZ);
+ Locale.setDefault(savedLocale);
+ }
+ }
+
+ /*
+ * Golden data for set() test
+ */
+ static final int[][][] resultWOMForSetTest = {
+ { /* For year1998 */
+ /* Min = 1 2 3 4 5 6 7 */
+ /* Sun */ {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11,11}, {11,11},
+ /* Mon */ {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11,11},
+ /* Tue */ {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},
+ /* Wed */ {10,27}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},
+ /* Thu */ {10,27}, {10,27}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},
+ /* Fri */ {10,27}, {10,27}, {10,27}, {11, 4}, {11, 4}, {11, 4}, {11, 4},
+ /* Sat */ {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11,11}, {11,11}, {11,11},
+ },
+ { /* For year1999 */
+ /* Min = 1 2 3 4 5 6 7 */
+ /* Sun */ {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11,10}, {11,10}, {11,10},
+ /* Mon */ {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11,10}, {11,10},
+ /* Tue */ {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11,10},
+ /* Wed */ {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3},
+ /* Thu */ {10,26}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3},
+ /* Fri */ {10,26}, {10,26}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3},
+ /* Sat */ {11, 3}, {11, 3}, {11, 3}, {11,10}, {11,10}, {11,10}, {11,10},
+ },
+ { /* For year2000 */
+ /* Min = 1 2 3 4 5 6 7 */
+ /* Sun */ {11, 1}, {11, 1}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8},
+ /* Mon */ {11, 1}, {11, 1}, {11, 1}, {11, 8}, {11, 8}, {11, 8}, {11, 8},
+ /* Tue */ {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 8}, {11, 8}, {11, 8},
+ /* Wed */ {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 8}, {11, 8},
+ /* Thu */ {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 8},
+ /* Fri */ {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 1},
+ /* Sat */ {11, 1}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8},
+ },
+ { /* For year2001 */
+ /* Min = 1 2 3 4 5 6 7 */
+ /* Sun */ {10,30}, {11, 7}, {11, 7}, {11, 7}, {11, 7}, {11, 7}, {11, 7},
+ /* Mon */ {10,30}, {10,30}, {11, 7}, {11, 7}, {11, 7}, {11, 7}, {11, 7},
+ /* Tue */ {10,30}, {10,30}, {10,30}, {11, 7}, {11, 7}, {11, 7}, {11, 7},
+ /* Wed */ {10,30}, {10,30}, {10,30}, {10,30}, {11, 7}, {11, 7}, {11, 7},
+ /* Thu */ {10,30}, {10,30}, {10,30}, {10,30}, {10,30}, {11, 7}, {11, 7},
+ /* Fri */ {10,30}, {10,30}, {10,30}, {10,30}, {10,30}, {10,30}, {11, 7},
+ /* Sat */ {11, 7}, {11, 7}, {11, 7}, {11, 7}, {11, 7}, {11, 7}, {11, 7},
+ },
+ { /* For year2002 */
+ /* Min = 1 2 3 4 5 6 7 */
+ /* Sun */ {11, 6}, {11, 6}, {11, 6}, {11, 6}, {11, 6}, {11, 6}, {11, 6},
+ /* Mon */ {10,29}, {11, 6}, {11, 6}, {11, 6}, {11, 6}, {11, 6}, {11, 6},
+ /* Tue */ {10,29}, {10,29}, {11, 6}, {11, 6}, {11, 6}, {11, 6}, {11, 6},
+ /* Wed */ {10,29}, {10,29}, {10,29}, {11, 6}, {11, 6}, {11, 6}, {11, 6},
+ /* Thu */ {10,29}, {10,29}, {10,29}, {10,29}, {11, 6}, {11, 6}, {11, 6},
+ /* Fri */ {10,29}, {10,29}, {10,29}, {10,29}, {10,29}, {11, 6}, {11, 6},
+ /* Sat */ {11, 6}, {11, 6}, {11, 6}, {11, 6}, {11, 6}, {11, 6}, {11,13},
+ },
+ { /* For year2003 */
+ /* Min = 1 2 3 4 5 6 7 */
+ /* Sun */ {11, 5}, {11, 5}, {11, 5}, {11, 5}, {11, 5}, {11, 5}, {11,12},
+ /* Mon */ {11, 5}, {11, 5}, {11, 5}, {11, 5}, {11, 5}, {11, 5}, {11, 5},
+ /* Tue */ {10,28}, {11, 5}, {11, 5}, {11, 5}, {11, 5}, {11, 5}, {11, 5},
+ /* Wed */ {10,28}, {10,28}, {11, 5}, {11, 5}, {11, 5}, {11, 5}, {11, 5},
+ /* Thu */ {10,28}, {10,28}, {10,28}, {11, 5}, {11, 5}, {11, 5}, {11, 5},
+ /* Fri */ {10,28}, {10,28}, {10,28}, {10,28}, {11, 5}, {11, 5}, {11, 5},
+ /* Sat */ {11, 5}, {11, 5}, {11, 5}, {11, 5}, {11, 5}, {11,12}, {11,12},
+ },
+ { /* For year2004 */
+ /* Min = 1 2 3 4 5 6 7 */
+ /* Sun */ {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11,10}, {11,10}, {11,10},
+ /* Mon */ {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11,10}, {11,10},
+ /* Tue */ {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11,10},
+ /* Wed */ {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3},
+ /* Thu */ {10,26}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3},
+ /* Fri */ {10,26}, {10,26}, {11, 3}, {11, 3}, {11, 3}, {11, 3}, {11, 3},
+ /* Sat */ {11, 3}, {11, 3}, {11, 3}, {11,10}, {11,10}, {11,10}, {11,10},
+ },
+ { /* For year2005 */
+ /* Min = 1 2 3 4 5 6 7 */
+ /* Sun */ {11, 2}, {11, 2}, {11, 2}, {11, 9}, {11, 9}, {11, 9}, {11, 9},
+ /* Mon */ {11, 2}, {11, 2}, {11, 2}, {11, 2}, {11, 9}, {11, 9}, {11, 9},
+ /* Tue */ {11, 2}, {11, 2}, {11, 2}, {11, 2}, {11, 2}, {11, 9}, {11, 9},
+ /* Wed */ {11, 2}, {11, 2}, {11, 2}, {11, 2}, {11, 2}, {11, 2}, {11, 9},
+ /* Thu */ {11, 2}, {11, 2}, {11, 2}, {11, 2}, {11, 2}, {11, 2}, {11, 2},
+ /* Fri */ {10,25}, {11, 2}, {11, 2}, {11, 2}, {11, 2}, {11, 2}, {11, 2},
+ /* Sat */ {11, 2}, {11, 2}, {11, 9}, {11, 9}, {11, 9}, {11, 9}, {11, 9},
+ },
+ { /* For year2006 */
+ /* Min = 1 2 3 4 5 6 7 */
+ /* Sun */ {11, 1}, {11, 1}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8},
+ /* Mon */ {11, 1}, {11, 1}, {11, 1}, {11, 8}, {11, 8}, {11, 8}, {11, 8},
+ /* Tue */ {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 8}, {11, 8}, {11, 8},
+ /* Wed */ {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 8}, {11, 8},
+ /* Thu */ {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 8},
+ /* Fri */ {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 1}, {11, 1},
+ /* Sat */ {11, 1}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8},
+ },
+ };
+
+ static final int[][][] resultWOYForSetTest1 = {
+ { /* For year1998 */
+ /* FirstDayOfWeek = Sunday */
+ {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 9},
+ {1998, 0, 9}, {1998, 0, 9}, {1998, 0, 9},
+ /* FirstDayOfWeek = Monday */
+ {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 2},
+ {1998, 0, 9}, {1998, 0, 9}, {1998, 0, 9},
+ /* FirstDayOfWeek = Tuesday */
+ {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 2},
+ {1998, 0, 2}, {1998, 0, 9}, {1998, 0, 9},
+ /* FirstDayOfWeek = Wednesday */
+ {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 2},
+ {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 9},
+ /* FirstDayOfWeek = Thursday */
+ {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 2},
+ {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 2},
+ /* FirstDayOfWeek = Friday */
+ {1997,11,26}, {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 2},
+ {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 2},
+ /* FirstDayOfWeek = Saturday */
+ {1998, 0, 2}, {1998, 0, 2}, {1998, 0, 9}, {1998, 0, 9},
+ {1998, 0, 9}, {1998, 0, 9}, {1998, 0, 9},
+ },
+ { /* For year1999 */
+ /* FirstDayOfWeek = Sunday */
+ {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 8}, {1999, 0, 8},
+ {1999, 0, 8}, {1999, 0, 8}, {1999, 0, 8},
+ /* FirstDayOfWeek = Monday */
+ {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 8},
+ {1999, 0, 8}, {1999, 0, 8}, {1999, 0, 8},
+ /* FirstDayOfWeek = Tuesday */
+ {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 1},
+ {1999, 0, 8}, {1999, 0, 8}, {1999, 0, 8},
+ /* FirstDayOfWeek = Wednesday */
+ {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 1},
+ {1999, 0, 1}, {1999, 0, 8}, {1999, 0, 8},
+ /* FirstDayOfWeek = Thursday */
+ {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 1},
+ {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 8},
+ /* FirstDayOfWeek = Friday */
+ {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 1},
+ {1999, 0, 1}, {1999, 0, 1}, {1999, 0, 1},
+ /* FirstDayOfWeek = Saturday */
+ {1999, 0, 1}, {1999, 0, 8}, {1999, 0, 8}, {1999, 0, 8},
+ {1999, 0, 8}, {1999, 0, 8}, {1999, 0, 8},
+ },
+ { /* For year2000 */
+ /* FirstDayOfWeek = Sunday */
+ {1999,11,31}, {2000, 0, 7}, {2000, 0, 7}, {2000, 0, 7},
+ {2000, 0, 7}, {2000, 0, 7}, {2000, 0, 7},
+ /* FirstDayOfWeek = Monday */
+ {1999,11,31}, {1999,11,31}, {2000, 0, 7}, {2000, 0, 7},
+ {2000, 0, 7}, {2000, 0, 7}, {2000, 0, 7},
+ /* FirstDayOfWeek = Tuesday */
+ {1999,11,31}, {1999,11,31}, {1999,11,31}, {2000, 0, 7},
+ {2000, 0, 7}, {2000, 0, 7}, {2000, 0, 7},
+ /* FirstDayOfWeek = Wednesday */
+ {1999,11,31}, {1999,11,31}, {1999,11,31}, {1999,11,31},
+ {2000, 0, 7}, {2000, 0, 7}, {2000, 0, 7},
+ /* FirstDayOfWeek = Thursday */
+ {1999,11,31}, {1999,11,31}, {1999,11,31}, {1999,11,31},
+ {1999,11,31}, {2000, 0, 7}, {2000, 0, 7},
+ /* FirstDayOfWeek = Friday */
+ {1999,11,31}, {1999,11,31}, {1999,11,31}, {1999,11,31},
+ {1999,11,31}, {1999,11,31}, {2000, 0, 7},
+ /* FirstDayOfWeek = Saturday */
+ {2000, 0, 7}, {2000, 0, 7}, {2000, 0, 7}, {2000, 0, 7},
+ {2000, 0, 7}, {2000, 0, 7}, {2000, 0, 7},
+ },
+ { /* For year2001 */
+ /* FirstDayOfWeek = Sunday */
+ {2001, 0, 5}, {2001, 0, 5}, {2001, 0, 5}, {2001, 0, 5},
+ {2001, 0, 5}, {2001, 0, 5}, {2001, 0,12},
+ /* FirstDayOfWeek = Monday */
+ {2001, 0, 5}, {2001, 0, 5}, {2001, 0, 5}, {2001, 0, 5},
+ {2001, 0, 5}, {2001, 0, 5}, {2001, 0, 5},
+ /* FirstDayOfWeek = Tuesday */
+ {2000,11,29}, {2001, 0, 5}, {2001, 0, 5}, {2001, 0, 5},
+ {2001, 0, 5}, {2001, 0, 5}, {2001, 0, 5},
+ /* FirstDayOfWeek = Wednesday */
+ {2000,11,29}, {2000,11,29}, {2001, 0, 5}, {2001, 0, 5},
+ {2001, 0, 5}, {2001, 0, 5}, {2001, 0, 5},
+ /* FirstDayOfWeek = Thursday */
+ {2000,11,29}, {2000,11,29}, {2000,11,29}, {2001, 0, 5},
+ {2001, 0, 5}, {2001, 0, 5}, {2001, 0, 5},
+ /* FirstDayOfWeek = Friday */
+ {2000,11,29}, {2000,11,29}, {2000,11,29}, {2000,11,29},
+ {2001, 0, 5}, {2001, 0, 5}, {2001, 0, 5},
+ /* FirstDayOfWeek = Saturday */
+ {2001, 0, 5}, {2001, 0, 5}, {2001, 0, 5}, {2001, 0, 5},
+ {2001, 0, 5}, {2001, 0,12}, {2001, 0,12},
+ },
+ { /* For year2002 */
+ /* FirstDayOfWeek = Sunday */
+ {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4},
+ {2002, 0, 4}, {2002, 0,11}, {2002, 0,11},
+ /* FirstDayOfWeek = Monday */
+ {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4},
+ {2002, 0, 4}, {2002, 0, 4}, {2002, 0,11},
+ /* FirstDayOfWeek = Tuesday */
+ {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4},
+ {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4},
+ /* FirstDayOfWeek = Wednesday */
+ {2001,11,28}, {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4},
+ {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4},
+ /* FirstDayOfWeek = Thursday */
+ {2001,11,28}, {2001,11,28}, {2002, 0, 4}, {2002, 0, 4},
+ {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4},
+ /* FirstDayOfWeek = Friday */
+ {2001,11,28}, {2001,11,28}, {2001,11,28}, {2002, 0, 4},
+ {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4},
+ /* FirstDayOfWeek = Saturday */
+ {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4}, {2002, 0, 4},
+ {2002, 0,11}, {2002, 0,11}, {2002, 0,11},
+ },
+ { /* For year2003 */
+ /* FirstDayOfWeek = Sunday */
+ {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3},
+ {2003, 0,10}, {2003, 0,10}, {2003, 0,10},
+ /* FirstDayOfWeek = Monday */
+ {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3},
+ {2003, 0, 3}, {2003, 0,10}, {2003, 0,10},
+ /* FirstDayOfWeek = Tuesday */
+ {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3},
+ {2003, 0, 3}, {2003, 0, 3}, {2003, 0,10},
+ /* FirstDayOfWeek = Wednesday */
+ {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3},
+ {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3},
+ /* FirstDayOfWeek = Thursday */
+ {2002,11,27}, {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3},
+ {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3},
+ /* FirstDayOfWeek = Friday */
+ {2002,11,27}, {2002,11,27}, {2003, 0, 3}, {2003, 0, 3},
+ {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3},
+ /* FirstDayOfWeek = Saturday */
+ {2003, 0, 3}, {2003, 0, 3}, {2003, 0, 3}, {2003, 0,10},
+ {2003, 0,10}, {2003, 0,10}, {2003, 0,10},
+ },
+ { /* For year2004 */
+ /* FirstDayOfWeek = Sunday */
+ {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 9},
+ {2004, 0, 9}, {2004, 0, 9}, {2004, 0, 9},
+ /* FirstDayOfWeek = Monday */
+ {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 2},
+ {2004, 0, 9}, {2004, 0, 9}, {2004, 0, 9},
+ /* FirstDayOfWeek = Tuesday */
+ {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 2},
+ {2004, 0, 2}, {2004, 0, 9}, {2004, 0, 9},
+ /* FirstDayOfWeek = Wednesday */
+ {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 2},
+ {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 9},
+ /* FirstDayOfWeek = Thursday */
+ {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 2},
+ {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 2},
+ /* FirstDayOfWeek = Friday */
+ {2003,11,26}, {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 2},
+ {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 2},
+ /* FirstDayOfWeek = Saturday */
+ {2004, 0, 2}, {2004, 0, 2}, {2004, 0, 9}, {2004, 0, 9},
+ {2004, 0, 9}, {2004, 0, 9}, {2004, 0, 9},
+ },
+ { /* For year2005 */
+ /* FirstDayOfWeek = Sunday */
+ {2004,11,31}, {2005, 0, 7}, {2005, 0, 7}, {2005, 0, 7},
+ {2005, 0, 7}, {2005, 0, 7}, {2005, 0, 7},
+ /* FirstDayOfWeek = Monday */
+ {2004,11,31}, {2004,11,31}, {2005, 0, 7}, {2005, 0, 7},
+ {2005, 0, 7}, {2005, 0, 7}, {2005, 0, 7},
+ /* FirstDayOfWeek = Tuesday */
+ {2004,11,31}, {2004,11,31}, {2004,11,31}, {2005, 0, 7},
+ {2005, 0, 7}, {2005, 0, 7}, {2005, 0, 7},
+ /* FirstDayOfWeek = Wednesday */
+ {2004,11,31}, {2004,11,31}, {2004,11,31}, {2004,11,31},
+ {2005, 0, 7}, {2005, 0, 7}, {2005, 0, 7},
+ /* FirstDayOfWeek = Thursday */
+ {2004,11,31}, {2004,11,31}, {2004,11,31}, {2004,11,31},
+ {2004,11,31}, {2005, 0, 7}, {2005, 0, 7},
+ /* FirstDayOfWeek = Friday */
+ {2004,11,31}, {2004,11,31}, {2004,11,31}, {2004,11,31},
+ {2004,11,31}, {2004,11,31}, {2005, 0, 7},
+ /* FirstDayOfWeek = Saturday */
+ {2005, 0, 7}, {2005, 0, 7}, {2005, 0, 7}, {2005, 0, 7},
+ {2005, 0, 7}, {2005, 0, 7}, {2005, 0, 7},
+ },
+ { /* For year2006 */
+ /* FirstDayOfWeek = Sunday */
+ {2006, 0, 6}, {2006, 0, 6}, {2006, 0, 6}, {2006, 0, 6},
+ {2006, 0, 6}, {2006, 0, 6}, {2006, 0, 6},
+ /* FirstDayOfWeek = Monday */
+ {2005,11,30}, {2006, 0, 6}, {2006, 0, 6}, {2006, 0, 6},
+ {2006, 0, 6}, {2006, 0, 6}, {2006, 0, 6},
+ /* FirstDayOfWeek = Tuesday */
+ {2005,11,30}, {2005,11,30}, {2006, 0, 6}, {2006, 0, 6},
+ {2006, 0, 6}, {2006, 0, 6}, {2006, 0, 6},
+ /* FirstDayOfWeek = Wednesday */
+ {2005,11,30}, {2005,11,30}, {2005,11,30}, {2006, 0, 6},
+ {2006, 0, 6}, {2006, 0, 6}, {2006, 0, 6},
+ /* FirstDayOfWeek = Thursday */
+ {2005,11,30}, {2005,11,30}, {2005,11,30}, {2005,11,30},
+ {2006, 0, 6}, {2006, 0, 6}, {2006, 0, 6},
+ /* FirstDayOfWeek = Friday */
+ {2005,11,30}, {2005,11,30}, {2005,11,30}, {2005,11,30},
+ {2005,11,30}, {2006, 0, 6}, {2006, 0, 6},
+ /* FirstDayOfWeek = Saturday */
+ {2006, 0, 6}, {2006, 0, 6}, {2006, 0, 6}, {2006, 0, 6},
+ {2006, 0, 6}, {2006, 0, 6}, {2006, 0,13},
+ }
+ };
+
+ static final int[][] resultWOYForSetTest2 = {
+ /* Min = 1 2 3 4 5 6 7 */
+ /* Sun */ {4,25}, {5, 1}, {5, 1}, {5, 1}, {5, 1}, {5, 1}, {5, 1},
+ /* Mon */ {4,25}, {4,25}, {5, 1}, {5, 1}, {5, 1}, {5, 1}, {5, 1},
+ /* Tue */ {4,25}, {4,25}, {4,25}, {5, 1}, {5, 1}, {5, 1}, {5, 1},
+ /* Wed */ {4,25}, {4,25}, {4,25}, {4,25}, {5, 1}, {5, 1}, {5, 1},
+ /* Thu */ {5, 1}, {5, 1}, {5, 1}, {5, 1}, {5, 1}, {5, 8}, {5, 8},
+ /* Fri */ {5, 1}, {5, 1}, {5, 1}, {5, 1}, {5, 1}, {5, 1}, {5, 8},
+ /* Sat */ {5, 1}, {5, 1}, {5, 1}, {5, 1}, {5, 1}, {5, 1}, {5, 1},
+ };
+
+ /**
+ * Test for set()
+ */
+ void testSet() {
+ boolean noerror = true;
+ Calendar cal = Calendar.getInstance();
+ int sYear=1998;
+ int eYear=2006;
+
+ // Loop for FirstDayOfWeek: SUNDAY..SATURDAY
+ for (int dow = SUNDAY; dow <= SATURDAY; dow++) {
+
+ // Loop for MinimalDaysInFirstWeek: 1..7
+ for (int minDow = 1; minDow <= 7; minDow++) {
+ int index = (dow-1)*7 + (minDow-1);
+
+ cal.clear();
+ cal.setLenient(true);
+ cal.setMinimalDaysInFirstWeek(minDow);
+ cal.setFirstDayOfWeek(dow);
+ cal.set(YEAR, 2005);
+ cal.set(DAY_OF_WEEK, WEDNESDAY);
+ cal.set(WEEK_OF_YEAR, 22);
+
+ int y = 2005;
+ int m = resultWOYForSetTest2[index][0];
+ int d = resultWOYForSetTest2[index][1];
+ int year = cal.get(YEAR);
+ int month = cal.get(MONTH);
+ int date = cal.get(DATE);
+
+ if (cal.get(WEEK_OF_YEAR) != 22) {
+ noerror = false;
+ errln("Failed : set(WEEK_OF_YEAR=22)" +
+ " *** get(WEEK_OF_YEAR=" +
+ cal.get(WEEK_OF_YEAR) + ")" +
+ ", got " + (month+1)+"/"+date+"/"+year +
+ ", expected " + (m+1)+"/"+d+"/"+2005 +
+ ", MinFirstDOW=" + minDow +
+ ", FirstDOW=" + dow);
+ } else if ((year != y) || (month != m) || (date != d)) {
+ noerror = false;
+ errln("Failed : set(WEEK_OF_YEAR=22)" +
+ " got " + (month+1)+"/"+date+"/"+year +
+ ", expected " + (m+1)+"/"+d+"/"+y +
+ ", MinFirstDOW=" + minDow +
+ ", FirstDOW=" + dow);
+ }
+
+ for (int targetYear = sYear; targetYear<= eYear; targetYear++) {
+ cal.clear();
+ cal.setLenient(true);
+ cal.setMinimalDaysInFirstWeek(minDow);
+ cal.setFirstDayOfWeek(dow);
+ cal.set(YEAR, targetYear);
+ cal.set(DAY_OF_WEEK, FRIDAY);
+ cal.set(MONTH, DECEMBER);
+ cal.set(WEEK_OF_MONTH, 1);
+
+ y = targetYear;
+ m = resultWOMForSetTest[targetYear-sYear][index][0];
+ d = resultWOMForSetTest[targetYear-sYear][index][1];
+ year = cal.get(YEAR);
+ month = cal.get(MONTH);
+ date = cal.get(DATE);
+
+ if ((year != y) || (month != m) || (date != d)) {
+ noerror = false;
+ errln("Failed : set(WEEK_OF_MONTH=1)" +
+ " got " + (month+1)+"/"+date+"/"+year +
+ ", expected " + (m+1)+"/"+d+"/"+y +
+ ", MinFirstDOW=" + minDow +
+ ", FirstDOW=" + dow);
+ }
+
+ cal.clear();
+ cal.setLenient(true);
+ cal.setMinimalDaysInFirstWeek(minDow);
+ cal.setFirstDayOfWeek(dow);
+ cal.set(YEAR, targetYear);
+ cal.set(DAY_OF_WEEK, FRIDAY);
+ cal.set(WEEK_OF_YEAR, 1);
+
+ y = resultWOYForSetTest1[targetYear-sYear][index][0];
+ m = resultWOYForSetTest1[targetYear-sYear][index][1];
+ d = resultWOYForSetTest1[targetYear-sYear][index][2];
+ year = cal.get(YEAR);
+ month = cal.get(MONTH);
+ date = cal.get(DATE);
+
+ if (cal.get(WEEK_OF_YEAR) != 1) {
+ noerror = false;
+ errln("Failed : set(WEEK_OF_YEAR=1)" +
+ " *** get(WEEK_OF_YEAR=" +
+ cal.get(WEEK_OF_YEAR) + ")" +
+ ", got " + (month+1)+"/"+date+"/"+year +
+ ", expected " + (m+1)+"/"+d+"/"+y +
+ ", MinFirstDOW=" + minDow +
+ ", FirstDOW=" + dow);
+ } else if ((year != y) || (month != m) || (date != d)) {
+ noerror = false;
+ errln("Failed : set(WEEK_OF_YEAR=1)" +
+ " got " + (month+1)+"/"+date+"/"+year +
+ ", expected " + (m+1)+"/"+d+"/"+y +
+ ", MinFirstDOW=" + minDow +
+ ", FirstDOW=" + dow);
+ }
+ }
+ }
+ }
+
+ if (noerror) {
+ logln("Passed : set() test");
+ }
+ }
+
+ /**
+ * Test for add()
+ */
+ void testAdd() {
+ boolean noerror = true;
+ Calendar cal = Calendar.getInstance();
+
+ // Loop for FirstDayOfWeek: SUNDAY..SATURDAY
+ for (int dow = SUNDAY; dow <= SATURDAY; dow++) {
+
+ // Loop for MinimalDaysInFirstWeek: 1..7
+ for (int minDow = 1; minDow <= 7; minDow++) {
+ int oldWOY, newWOY;
+
+ cal.clear();
+ cal.setLenient(true);
+ cal.setMinimalDaysInFirstWeek(minDow);
+ cal.setFirstDayOfWeek(dow);
+ cal.set(2005, DECEMBER, 7);
+ oldWOY = cal.get(WEEK_OF_YEAR);
+
+ for (int cnt = 0; cnt < 7; cnt++) {
+ cal.add(WEEK_OF_YEAR, 1);
+ }
+
+ int year = cal.get(YEAR);
+ int month = cal.get(MONTH);
+ int date = cal.get(DATE);
+
+ if ((year != 2006) || (month != 0) || (date != 25)) {
+ noerror = false;
+ errln("Failed : add(WEEK_OF_YEAR+1)" +
+ " got " + (month+1)+"/"+date+"/"+year +
+ ", expected 1/25/2006" +
+ ", MinFirstDOW=" + minDow +
+ ", FirstDOW=" + dow);
+ }
+
+ for (int cnt = 0; cnt < 10; cnt++) {
+ cal.add(WEEK_OF_YEAR, -1);
+ }
+ newWOY = cal.get(WEEK_OF_YEAR);
+
+ year = cal.get(YEAR);
+ month = cal.get(MONTH);
+ date = cal.get(DATE);
+
+ if ((oldWOY - newWOY) != 3) {
+ errln("Failed : add(WEEK_OF_YEAR-1)" +
+ " got " + (month+1)+"/"+date+"/"+year +
+ ", expected 11/16/2005" +
+ ", MinFirstDOW=" + minDow +
+ ", FirstDOW=" + dow +
+ ", WEEK_OF_YEAR=" + newWOY +
+ " should be " + (oldWOY-3));
+ } else if ((year != 2005) || (month != 10) || (date != 16)) {
+ errln("Failed : add(-1)" +
+ " got " + (month+1)+"/"+date+"/"+year +
+ ", expected 11/16/2005" +
+ ", MinFirstDOW=" + minDow +
+ ", FirstDOW=" + dow);
+ }
+ }
+ }
+
+ if (noerror) {
+ logln("Passed : add() test");
+ }
+ }
+
+ /*
+ * Golden data for roll() test
+ */
+ static final int[] resultWOMForRollTest = {
+ /* Min = 1 2 3 4 5 6 7 */
+ /* Sun */ 1, 1, 1, 26, 26, 26, 26,
+ /* Mon */ 1, 1, 1, 1, 26, 26, 26,
+ /* Tue */ 31, 31, 31, 31, 31, 24, 24,
+ /* Wed */ 31, 31, 31, 31, 31, 31, 24,
+ /* Thu */ 31, 31, 31, 31, 31, 31, 31,
+ /* Fri */ 1, 31, 31, 31, 31, 31, 31,
+ /* Sat */ 1, 1, 31, 31, 31, 31, 31,
+ };
+
+ static final int[][] resultWOYForRollTest = {
+ /* Min = 1 2 3 4 5 6 7 */
+ /* Sun */ {0,26}, {0,26}, {0,26}, {0,26}, {0,26}, {0,26}, {0,26},
+ /* Mon */ {1, 2}, {0,26}, {0,26}, {0,26}, {0,26}, {0,26}, {0,26},
+ /* Tue */ {1, 2}, {1, 2}, {0,26}, {0,26}, {0,26}, {0,26}, {0,26},
+ /* Wed */ {1, 2}, {1, 2}, {1, 2}, {0,26}, {0,26}, {0,26}, {0,26},
+ /* Thu */ {0,26}, {0,26}, {0,26}, {0,26}, {0,26}, {1, 2}, {1, 2},
+ /* Fri */ {0,26}, {0,26}, {0,26}, {0,26}, {0,26}, {0,26}, {1, 2},
+ /* Sat */ {0,26}, {0,26}, {0,26}, {0,26}, {0,26}, {0,26}, {0,26},
+ };
+
+ /**
+ * Test for roll()
+ */
+ void testRoll() {
+ boolean noerror = true;
+ Calendar cal = Calendar.getInstance();
+
+ // Loop for FirstDayOfWeek: SUNDAY..SATURDAY
+ for (int dow = SUNDAY; dow <= SATURDAY; dow++) {
+
+ // Loop for MinimalDaysInFirstWeek: 1..7
+ for (int minDow = 1; minDow <= 7; minDow++) {
+ int oldWOY, newWOY;
+ int index = (dow-1)*7 + (minDow-1);
+
+ cal.clear();
+ cal.setLenient(true);
+ cal.setMinimalDaysInFirstWeek(minDow);
+ cal.setFirstDayOfWeek(dow);
+ cal.set(2005, DECEMBER, 12);
+ oldWOY = cal.get(WEEK_OF_YEAR);
+ for (int cnt = 0; cnt < 2; cnt++) {
+ cal.roll(WEEK_OF_MONTH, -1);
+ }
+ int y = 2005;
+ int m = DECEMBER;
+ int d = resultWOMForRollTest[index];
+ int year = cal.get(YEAR);
+ int month = cal.get(MONTH);
+ int date = cal.get(DATE);
+
+ if ((year != y) || (month != m) || (date != d)) {
+ noerror = false;
+ errln("Failed : roll(WEEK_OF_MONTH-1)" +
+ " got " + (month+1) + "/" + date + "/" + year +
+ ", expected " + (m+1) + "/" + d + "/" + y +
+ ", MinFirstDOW=" + minDow +
+ ", FirstDOW=" + dow);
+ }
+
+ cal.clear();
+ cal.setLenient(true);
+ cal.setMinimalDaysInFirstWeek(minDow);
+ cal.setFirstDayOfWeek(dow);
+ cal.set(2005, DECEMBER, 7);
+ oldWOY = cal.get(WEEK_OF_YEAR);
+
+ for (int cnt = 0; cnt < 7; cnt++) {
+ cal.roll(WEEK_OF_YEAR, 1);
+ }
+
+ y = 2005;
+ m = resultWOYForRollTest[index][0];
+ d = resultWOYForRollTest[index][1];
+ year = cal.get(YEAR);
+ month = cal.get(MONTH);
+ date = cal.get(DATE);
+
+ if ((year != y) || (month != m) || (date != d)) {
+ noerror = false;
+ errln("Failed : roll(WEEK_OF_YEAR+1)" +
+ " got " + (month+1) + "/" + date + "/" + year +
+ ", expected " + (m+1) + "/" + d + "/" + y +
+ ", MinFirstDOW=" + minDow +
+ ", FirstDOW=" + dow);
+ }
+
+ for (int cnt = 0; cnt < 10; cnt++) {
+ cal.roll(WEEK_OF_YEAR, -1);
+ }
+ newWOY = cal.get(WEEK_OF_YEAR);
+
+ y = 2005;
+ m = NOVEMBER;
+ d = 16;
+ year = cal.get(YEAR);
+ month = cal.get(MONTH);
+ date = cal.get(DATE);
+
+ if ((year != y) || (month != m) || (date != d)) {
+ noerror = false;
+ errln("Failed : roll(WEEK_OF_YEAR-1)" +
+ " got " + (month+1)+"/"+date+"/"+year +
+ ", expected " + (m+1)+"/"+d+"/"+y +
+ ", MinFirstDOW=" + minDow +
+ ", FirstDOW=" + dow);
+ }
+ }
+ }
+
+ if (noerror) {
+ logln("Passed : roll() test");
+ }
+ }
+}
diff --git a/jdk/test/java/util/Calendar/bug4514831.java b/jdk/test/java/util/Calendar/bug4514831.java
new file mode 100644
index 00000000000..9d635e26167
--- /dev/null
+++ b/jdk/test/java/util/Calendar/bug4514831.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2002, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4514831
+ * @summary Confirm that GregorianCalendar.roll() works properly during transition from Daylight Saving Time to Standard Time.
+ */
+
+import java.util.*;
+
+public class bug4514831 {
+
+ public static void main(String[] args) {
+ Locale savedLocale = Locale.getDefault();
+ TimeZone savedTimeZone = TimeZone.getDefault();
+ boolean err = false;
+
+ String golden_data1 ="27-28 28-29 29-30 30-31 31-1 1-2 2-3 ";
+ String golden_data2 ="27-28 28-29 29-30 30-31 31-25 25-26 26-27 ";
+ String golden_data3 ="1-8 8-15 15-22 22-29 29-1 1-8 8-15 ";
+
+ try {
+ Locale.setDefault(Locale.US);
+ TimeZone.setDefault(TimeZone.getTimeZone("US/Pacific"));
+
+ String test_roll = "";
+ GregorianCalendar c_roll = new GregorianCalendar(2001, Calendar.OCTOBER, 27);
+ for (int i=0; i < 7; i++) {
+ test_roll += c_roll.get(c_roll.DAY_OF_MONTH) + "-";
+ c_roll.roll(c_roll.DAY_OF_YEAR, true);
+ test_roll += c_roll.get(c_roll.DAY_OF_MONTH) + " ";
+ }
+ if (!test_roll.equals(golden_data1)) {
+ err = true;
+ System.err.println("Wrong roll(DAY_OF_YEAR) transition: got "+
+ test_roll + "expected " + golden_data1);
+ }
+
+ test_roll = "";
+ c_roll = new GregorianCalendar(2001, Calendar.OCTOBER, 27);
+ c_roll.setFirstDayOfWeek(Calendar.THURSDAY);
+ for (int i=0; i < 7; i++) {
+ test_roll += c_roll.get(c_roll.DAY_OF_MONTH) + "-";
+ c_roll.roll(c_roll.DAY_OF_WEEK, true);
+ test_roll += c_roll.get(c_roll.DAY_OF_MONTH) + " ";
+ }
+ if (!test_roll.equals(golden_data2)) {
+ err = true;
+ System.err.println("Wrong roll(DAY_OF_WEEK) transition: got "+
+ test_roll + "expected " + golden_data2);
+ }
+
+ test_roll = "";
+ c_roll = new GregorianCalendar(2001, Calendar.OCTOBER, 1);
+ for (int i=0; i < 7; i++) {
+ test_roll += c_roll.get(c_roll.DAY_OF_MONTH) + "-";
+ c_roll.roll(c_roll.DAY_OF_WEEK_IN_MONTH, true);
+ test_roll += c_roll.get(c_roll.DAY_OF_MONTH) + " ";
+ }
+ if (!test_roll.equals(golden_data3)) {
+ err = true;
+ System.err.println("Wrong roll(DAY_OF_WEEK_IN_MONTH) transition: got "+
+ test_roll + "expected " + golden_data3);
+ }
+ } finally {
+ Locale.setDefault(savedLocale);
+ TimeZone.setDefault(savedTimeZone);
+ }
+
+ if (err) {
+ throw new RuntimeException("Wrong roll() transition");
+ }
+ }
+}
diff --git a/jdk/test/java/util/Date/Bug4955000.java b/jdk/test/java/util/Date/Bug4955000.java
new file mode 100644
index 00000000000..c94b23868ca
--- /dev/null
+++ b/jdk/test/java/util/Date/Bug4955000.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4955000
+ * @summary Make sure that a Date and a GregorianCalendar produce the
+ * same date/time. Both are new implementations in 1.5.
+ */
+
+import java.util.*;
+import static java.util.GregorianCalendar.*;
+
+@SuppressWarnings("deprecation")
+public class Bug4955000 {
+ // Tests for Date.UTC(), derived from JCK
+ // Date.miscTests.Date1025 and Date2015
+ public static void main(String[] args) {
+ TimeZone defaultTZ = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("NST"));
+ GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
+ // Date1025
+ int[] years1 = {
+ Integer.MIN_VALUE,
+ Integer.MIN_VALUE + 1,
+ gc.getMinimum(YEAR) - 1,
+ gc.getMaximum(YEAR) + 1,
+ Integer.MAX_VALUE - 1,
+ Integer.MAX_VALUE
+ };
+ for (int i = 0; i < years1.length; i++) {
+ gc.clear();
+ gc.set(years1[i], gc.JANUARY, 1);
+ long t = gc.getTimeInMillis();
+ long utc = Date.UTC(years1[i] - 1900, 1-1, 1,
+ 0, 0, 0); // Jan 1 00:00:00
+ if (t != utc) {
+ throw new RuntimeException("t (" + t + ") != utc (" + utc +")");
+ }
+ }
+
+ // Date2015
+ int years[] = {
+ gc.getGreatestMinimum(YEAR),
+ gc.getGreatestMinimum(YEAR) + 1,
+ -1,
+ 0,
+ 1,
+ gc.getLeastMaximum(YEAR) - 1,
+ gc.getLeastMaximum(YEAR)
+ };
+
+ int months[] = {
+ gc.getMinimum(MONTH),
+ gc.getMinimum(MONTH) + 1,
+ gc.getMaximum(MONTH) - 1,
+ gc.getMaximum(MONTH)
+ };
+
+ int dates[] = {
+ gc.getMinimum(DAY_OF_MONTH),
+ gc.getMinimum(DAY_OF_MONTH) + 1,
+ gc.getMaximum(DAY_OF_MONTH) - 1,
+ gc.getMaximum(DAY_OF_MONTH)
+ };
+
+ int hs[] = {
+ gc.getMinimum(HOUR),
+ gc.getMinimum(HOUR) + 1,
+ gc.getMaximum(HOUR) - 1,
+ gc.getMaximum(HOUR)
+ };
+
+ int ms[] = {
+ gc.getMinimum(MINUTE),
+ gc.getMinimum(MINUTE) + 1,
+ gc.getMaximum(MINUTE) - 1,
+ gc.getMaximum(MINUTE)
+ };
+
+ int ss[] = {
+ gc.getMinimum(SECOND),
+ gc.getMinimum(SECOND) + 1,
+ gc.getMaximum(SECOND) - 1,
+ gc.getMaximum(SECOND)
+ };
+
+ for(int i = 0; i < years.length; i++) {
+ for(int j = 0; j < months.length; j++) {
+ for(int k = 0; k < dates.length; k++) {
+ for(int m = 0; m < hs.length; m++) {
+ for(int n = 0; n < ms.length; n++) {
+ for(int p = 0; p < ss.length; p++) {
+ int year = years[i] - 1900;
+ int month = months[j];
+ int date = dates[k];
+ int hours = hs[m];
+ int minutes = ms[n];
+ int seconds = ss[p];
+
+ long result = Date.UTC(year, month, date,
+ hours, minutes, seconds);
+
+ gc.clear();
+ gc.set(year + 1900, month, date, hours, minutes, seconds);
+
+ long expected = gc.getTime().getTime();
+
+ if (expected != result) {
+ throw new RuntimeException("expected (" + expected
+ + ") != result (" + result +")");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } finally {
+ TimeZone.setDefault(defaultTZ);
+ }
+ }
+}
diff --git a/jdk/test/java/util/Date/DateGregorianCalendarTest.java b/jdk/test/java/util/Date/DateGregorianCalendarTest.java
new file mode 100644
index 00000000000..49dbc8bc41a
--- /dev/null
+++ b/jdk/test/java/util/Date/DateGregorianCalendarTest.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2003, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4614842
+ * @summary Make sure that a Date and a GregorianCalendar produce the same date/time. Both are new implementations in 1.5.
+ * @run main DateGregorianCalendarTest 15
+ */
+
+import java.util.*;
+import static java.util.GregorianCalendar.*;
+
+// Usage: java DateGregorianCalendarTest [duration]
+
+@SuppressWarnings("deprecation")
+public class DateGregorianCalendarTest {
+ static volatile boolean runrun = true;
+ static int nThreads;
+
+ public static void main(String[] args) {
+ int duration = 600;
+ if (args.length == 1) {
+ duration = Math.max(10, Integer.parseInt(args[0]));
+ }
+
+ TimeZone savedTZ = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ Thread[] t = new Thread[10]; // for future bugs...
+ int index = 0;
+ t[index++] = new Thread(new Runnable() {
+ public void run() {
+ GregorianCalendar gc = new GregorianCalendar();
+
+ long delta = (long)(279 * 365.2422 * 24 * 60 * 60 * 1000);
+ long count = 0;
+ try {
+ for (long t = Long.MIN_VALUE; runrun && t < Long.MAX_VALUE-delta; t += delta) {
+ gc.setTimeInMillis(t);
+ Date date = new Date(t);
+ int y;
+ if (!((y = gc.get(YEAR)) == (date.getYear()+1900) &&
+ gc.get(MONTH) == date.getMonth() &&
+ gc.get(DAY_OF_MONTH) == date.getDate() &&
+ gc.get(HOUR_OF_DAY) == date.getHours() &&
+ gc.get(MINUTE) == date.getMinutes() &&
+ gc.get(SECOND) == date.getSeconds())) {
+ throw new RuntimeException("GregorinCalendar and Date returned different dates."
+ +" (millis=" + t + ")\n"
+ +"GC=" + gc + "\nDate=" + date);
+ }
+ ++count;
+ if (y >= 1) {
+ delta = (long)(365.2422 * 24 * 60 * 60 * 1000);
+ }
+ if (y >= 1970) {
+ delta = (24 * 60 * 60 * 1000);
+ }
+ if (y >= 2039) {
+ delta = (long)(279 * 365.2422 * 24 * 60 * 60 * 1000);
+ }
+ }
+ if (runrun) {
+ System.out.println("Part I (count="+count+"): Passed");
+ } else {
+ System.out.println("Part I (count="+count+"): Incomplete");
+ }
+ } catch (RuntimeException e) {
+ System.out.println("Part I (count="+count+"): FAILED");
+ runrun = false;
+ throw e;
+ } finally {
+ decrementCounter();
+ }
+ }
+ });
+
+ t[index++] = new Thread(new Runnable() {
+ public void run() {
+ GregorianCalendar gc = new GregorianCalendar();
+
+ long count = 0;
+ int delta;
+ try {
+ for (long year = Integer.MIN_VALUE+1900;
+ runrun && year <= Integer.MAX_VALUE; year += delta) {
+ checkTimes(gc, year, JANUARY, 1, 0, 0, 0);
+ ++count;
+ delta = getDelta((int)year);
+ }
+
+ for (long month = Integer.MIN_VALUE;
+ runrun && month <= Integer.MAX_VALUE; month += delta) {
+ checkTimes(gc, 1900, month, 1, 0, 0, 0);
+ ++count;
+ delta = getDelta(gc.get(YEAR));
+ }
+
+ for (long dayOfMonth = Integer.MIN_VALUE;
+ runrun && dayOfMonth <= Integer.MAX_VALUE; dayOfMonth += delta) {
+ checkTimes(gc, 1900, JANUARY, dayOfMonth, 0, 0, 0);
+ ++count;
+ delta = getDelta(gc.get(YEAR));
+ }
+ if (runrun) {
+ System.out.println("Part II (count="+count+"): Passed");
+ } else {
+ System.out.println("Part II (count="+count+"): Incomplete");
+ }
+ } catch (RuntimeException e) {
+ System.out.println("Part II (count="+count+"): FAILED");
+ runrun = false;
+ throw e;
+ } finally {
+ decrementCounter();
+ }
+ }
+ });
+
+ // t3 takes more than 10 minutes (on Ultra-60 450MHz) without
+ // the 4936355 fix due to getting the small delta.
+ t[index++] = new Thread(new Runnable() {
+ public void run() {
+ GregorianCalendar gc = new GregorianCalendar();
+
+ long count = 0;
+ int delta;
+ try {
+ for (long hourOfDay = Integer.MIN_VALUE;
+ runrun && hourOfDay <= Integer.MAX_VALUE; hourOfDay += delta) {
+ checkTimes(gc, 1970, JANUARY, 1, hourOfDay, 0, 0);
+ ++count;
+ delta = getDelta(gc.get(YEAR));
+ }
+ for (long minutes = Integer.MIN_VALUE;
+ runrun && minutes <= Integer.MAX_VALUE; minutes += delta) {
+ checkTimes(gc, 1970, JANUARY, 1, 0, minutes, 0);
+ ++count;
+ delta = getDelta(gc.get(YEAR)) * 60;
+ }
+ for (long seconds = Integer.MIN_VALUE;
+ runrun && seconds <= Integer.MAX_VALUE; seconds += delta) {
+ checkTimes(gc, 1970, JANUARY, 1, 0, 0, seconds);
+ ++count;
+ delta = getDelta(gc.get(YEAR)) * 60 * 60;
+ }
+ if (runrun) {
+ System.out.println("Part III (count="+count+"): Passed");
+ } else {
+ System.out.println("Part III (count="+count+"): Incomplete");
+ }
+ } catch (RuntimeException e) {
+ System.out.println("Part III (count="+count+"): FAILED");
+ runrun = false;
+ throw e;
+ } finally {
+ decrementCounter();
+ }
+ }
+ });
+
+ for (int i = 0; i < index; i++) {
+ incrementCounter();
+ t[i].start();
+ }
+
+ try {
+ for (int i = 0; getCounter() > 0 && i < duration; i++) {
+ Thread.sleep(1000);
+ }
+ runrun = false;
+ for (int i = 0; i < index; i++) {
+ t[i].join();
+ }
+ } catch (InterruptedException e) {
+ }
+ } finally {
+ TimeZone.setDefault(savedTZ);
+ }
+ }
+
+ static void checkTimes(GregorianCalendar gc, long year, long month, long dayOfMonth,
+ long hourOfDay, long minutes, long seconds) {
+ gc.clear();
+ gc.set((int)year, (int)month, (int)dayOfMonth, (int)hourOfDay, (int)minutes, (int)seconds);
+ long time = gc.getTimeInMillis();
+ Date date = new Date((int)year - 1900, (int)month, (int)dayOfMonth,
+ (int)hourOfDay, (int)minutes, (int)seconds);
+ long time2 = date.getTime();
+ if (time != time2) {
+ throw new RuntimeException("GregorinCalendar and Date returned different values.\n"
+ +"year="+year+", month="+month+", dayOfMonth="+dayOfMonth
+ +"\nhourOfDay="+hourOfDay+", minutes="+minutes+", seconds="+seconds
+ +"\ntime=" + time + ", time2=" + time2
+ +"\nGC=" + gc + "\nDate=" + date);
+ }
+ }
+
+ static final int getDelta(int year) {
+ return (year >= 1970 && year <= 2039) ? 1 : 1<<13;
+ }
+
+ synchronized static void incrementCounter() {
+ nThreads++;
+ }
+
+ synchronized static void decrementCounter() {
+ nThreads--;
+ }
+
+ synchronized static int getCounter() {
+ return nThreads;
+ }
+}
diff --git a/jdk/test/java/util/Date/DateRegression.java b/jdk/test/java/util/Date/DateRegression.java
new file mode 100644
index 00000000000..70d8a5bf706
--- /dev/null
+++ b/jdk/test/java/util/Date/DateRegression.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 1998, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4023247 4027685 4032037 4072029 4073003 4118010 4120606 4133833 4136916 6274757 6314387
+ * @library /java/text/testlib
+ */
+
+import java.util.*;
+
+@SuppressWarnings("deprecation")
+public class DateRegression extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new DateRegression().run(args);
+ }
+
+ /**
+ * @bug 4023247
+ */
+ public void Test4023247() {
+ Date d1 = new Date(0);
+ Date d2 = new Date(0);
+
+ d1.setYear(96);
+ d1.setMonth(11);
+ d1.setDate(22);
+ d1.setHours(0);
+ d1.setMinutes(0);
+ d1.setSeconds(0);
+
+ d2.setYear(96);
+ d2.setMonth(11);
+ d2.setDate(22);
+ d2.setHours(0);
+ d2.setMinutes(0);
+ d2.setSeconds(0);
+
+ if (d1.hashCode() != d2.hashCode())
+ errln("Fail: Date hashCode misbehaves");
+ }
+
+ /**
+ * @bug 4027685
+ */
+ public void Test4027685() {
+ // Should be 01/16/97 00:00:00
+ Date nite = new Date("16-JAN-97 12:00 AM");
+ // Should be 01/16/97 12:00:00
+ Date noon = new Date("16-JAN-97 12:00 PM");
+
+ logln("Midnight = " + nite + ", Noon = " + noon);
+ if (!nite.equals(new Date(97, Calendar.JANUARY, 16, 0, 0)) ||
+ !noon.equals(new Date(97, Calendar.JANUARY, 16, 12, 0)))
+ errln("Fail: Nite/Noon confused");
+ }
+
+ /**
+ * @bug 4032037
+ */
+ public void Test4032037() {
+ Date ref = new Date(97, 1, 10);
+ Date d = new Date(Date.parse("2/10/97"));
+ logln("Date.parse(2/10/97) => " + d);
+ if (!d.equals(ref)) errln("Fail: Want " + ref + " Got " + d);
+ d = new Date(Date.parse("10 feb 1997"));
+ logln("Date.parse(10 feb 1997) => " + d);
+ if (!d.equals(ref)) errln("Fail: Want " + ref + " Got " + d);
+ d = new Date("2/10/97");
+ logln("Date(2/10/97) => " + d);
+ if (!d.equals(ref)) errln("Fail: Want " + ref + " Got " + d);
+ d = new Date("10 feb 1997");
+ logln("Date(10 feb 1997) => " + d);
+ if (!d.equals(ref)) errln("Fail: Want " + ref + " Got " + d);
+ }
+
+ /**
+ * @bug 4072029
+ */
+ public void Test4072029() {
+ TimeZone saveZone = TimeZone.getDefault();
+
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("PST"));
+ Date now = new Date();
+ String s = now.toString();
+ Date now2 = new Date(now.toString());
+ String s2 = now2.toString(); // An hour's difference
+
+ if (!s.equals(s2) ||
+ Math.abs(now.getTime() - now2.getTime()) > 60000 /*one min*/) {
+ errln("Fail: Roundtrip toString/parse");
+ }
+ }
+ finally {
+ TimeZone.setDefault(saveZone);
+ }
+ }
+
+ /**
+ * @bug 4073003
+ */
+ public void Test4073003() {
+ Date d = new Date(Date.parse("01/02/1984"));
+ if (!d.equals(new Date(84, 0, 2)))
+ errln("Fail: Want 1/2/1984 Got " + d);
+ d = new Date(Date.parse("02/03/2012"));
+ if (!d.equals(new Date(112, 1, 3)))
+ errln("Fail: Want 2/3/2012 Got " + d);
+ d = new Date(Date.parse("03/04/15"));
+ if (!d.equals(new Date(115, 2, 4)))
+ errln("Fail: Want 3/4/2015 Got " + d);
+ }
+
+ /**
+ * @bug 4118010
+ * Regress bug:
+ * Feb. 2000 has 29 days, but Date(2000, 1, 29) returns March 01, 2000
+ * NOTE: This turned out to be a user error (passing in 2000 instead
+ * of 2000-1900 to the Date constructor).
+ */
+ public void Test4118010() {
+ Date d=new java.util.Date(2000-1900, Calendar.FEBRUARY, 29);
+ int m=d.getMonth();
+ int date=d.getDate();
+ if (m != Calendar.FEBRUARY ||
+ date != 29)
+ errln("Fail: Want Feb 29, got " + d);
+ }
+
+ /**
+ * @bug 4120606
+ * Date objects share state after cloning.
+ */
+ public void Test4120606() {
+ Date d = new Date(98, Calendar.JUNE, 24);
+ d.setMonth(Calendar.MAY);
+ Date e = (Date)d.clone();
+ d.setMonth(Calendar.FEBRUARY);
+ if (e.getMonth() != Calendar.MAY) {
+ errln("Cloned Date objects share state");
+ }
+ }
+
+ /**
+ * @bug 4133833
+ * Date constructor crashes with parameters out of range, when it should
+ * normalize.
+ */
+ public void Test4133833() {
+ Date date = new java.util.Date(12,15,19);
+ Date exp = new Date(1913-1900, Calendar.APRIL, 19);
+ if (!date.equals(exp))
+ errln("Fail: Want " + exp +
+ "; got " + date);
+ }
+
+ /**
+ * @bug 4136916
+ * Date.toString() throws exception in 1.2b4-E
+ * CANNOT REPRODUCE this bug
+ */
+ public void Test4136916() {
+ Date time = new Date();
+ logln(time.toString());
+ }
+
+ /**
+ * @bug 6274757
+ * Date getTime and toString interaction for some time values
+ */
+ public void Test6274757() {
+ TimeZone savedTz = TimeZone.getDefault();
+ try {
+ // Use a time zone west of GMT.
+ TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
+ TimeZone jdkGMT = TimeZone.getTimeZone("GMT");
+ Calendar jdkCal = Calendar.getInstance(jdkGMT);
+ jdkCal.clear();
+ jdkCal.set(1582, Calendar.OCTOBER, 15);
+ logln("JDK time: " + jdkCal.getTime().getTime() );
+ logln("JDK time (str): " + jdkCal.getTime() );
+ logln("Day of month: " + jdkCal.get(Calendar.DAY_OF_MONTH));
+ Date co = jdkCal.getTime();
+ logln("Change over (Oct 15 1582) = " + co + " (" +
+ co.getTime() + ")");
+ long a = jdkCal.getTime().getTime();
+ Date c = jdkCal.getTime();
+ c.toString();
+ long b = c.getTime();
+
+ if (a != b) {
+ errln("ERROR: " + a + " != " + b);
+ } else {
+ logln(a + " = " + b);
+ }
+ } finally {
+ TimeZone.setDefault(savedTz);
+ }
+ }
+
+ /**
+ * @bug 6314387
+ * JCK6.0: api/java_util/Date/index.html#misc fails, mustang
+ */
+ public void Test6314387() {
+ Date d = new Date(Long.MAX_VALUE);
+ int y = d.getYear();
+ if (y != 292277094) {
+ errln("yesr: got " + y + ", expected 292277094");
+ }
+ d = new Date(Long.MIN_VALUE);
+ y = d.getYear();
+ if (y != 292267155) {
+ errln("yesr: got " + y + ", expected 292267155");
+ }
+ }
+}
+
+//eof
diff --git a/jdk/test/java/util/Date/DateTest.java b/jdk/test/java/util/Date/DateTest.java
new file mode 100644
index 00000000000..98392760ba3
--- /dev/null
+++ b/jdk/test/java/util/Date/DateTest.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 1997, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4143459
+ * @summary test Date
+ * @library /java/text/testlib
+ */
+
+import java.text.*;
+import java.util.*;
+
+@SuppressWarnings("deprecation")
+public class DateTest extends IntlTest
+{
+ public static void main(String[] args) throws Exception {
+ new DateTest().run(args);
+ }
+
+ /**
+ * @bug 4143459
+ * Warning: Use TestDefaultZone() for complete testing of this bug.
+ */
+ public void TestDefaultZoneLite() {
+ // Note: This test is redundant with TestDefaultZone(). It was added by
+ // request to provide a short&sweet test for this bug. It does not test
+ // all cases though, so IF THIS TEST PASSES, THE BUG MAY STILL BE
+ // PRESENT. Use TestDefaultZone() to be sure.
+ TimeZone save = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ Date d = new Date();
+ d.setYear(98);
+ d.setMonth(Calendar.JANUARY);
+ d.setDate(1);
+ d.setHours(6);
+ TimeZone.setDefault(TimeZone.getTimeZone("PST"));
+ if (d.getHours() != 22) {
+ errln("Fail: Date.setHours()/getHours() ignoring default zone");
+ }
+ }
+ finally { TimeZone.setDefault(save); }
+ }
+
+ /**
+ * @bug 4143459
+ */
+ public void TestDefaultZone() {
+ // Various problems can creep up, with the current implementation of Date,
+ // when the default zone is changed.
+
+ TimeZone saveZone = TimeZone.getDefault();
+ try {
+
+ Date d = new Date(); // Trigger static init
+ Date ref = new Date(883634400000L); // This is Thu Jan 1 1998 6:00 am GMT
+ String refstr = "Jan 1 1998 6:00";
+ TimeZone GMT = TimeZone.getTimeZone("GMT");
+ TimeZone PST = TimeZone.getTimeZone("PST");
+
+ String[] names = { "year", "month", "date", "day of week", "hour", "offset" };
+ int[] GMT_EXP = { 98, Calendar.JANUARY, 1, Calendar.THURSDAY - Calendar.SUNDAY, 6, 0 };
+ int[] PST_EXP = { 97, Calendar.DECEMBER, 31, Calendar.WEDNESDAY - Calendar.SUNDAY, 22, 480 };
+
+ // There are two cases to consider: a Date object with no Calendar
+ // sub-object (most Date objects), and a Date object with a Calendar
+ // sub-object. We make two passes to cover the two cases.
+ for (int pass=0; pass<2; ++pass) {
+ logln(pass == 0 ? "Normal Date object" : "Date with Calendar sub-object");
+
+ TimeZone.setDefault(GMT);
+ d = new Date(refstr);
+ if (pass == 1) {
+ // Force creation of Calendar sub-object
+ d.setYear(d.getYear());
+ }
+ if (d.getTime() != ref.getTime()) {
+ errln("FAIL: new Date(\"" + refstr + "\") x GMT -> " + d +
+ " " + d.getTime() + " ms");
+ }
+
+ int[] fields = { d.getYear(), d.getMonth(), d.getDate(),
+ d.getDay(), d.getHours(), d.getTimezoneOffset() };
+ for (int i=0; i PER_LOOP_LIMIT)
+ logln("WARNING: Date constructor/getYear slower than " +
+ PER_LOOP_LIMIT + " ms");
+ }
+ static double PER_LOOP_LIMIT = 3.0;
+
+ /**
+ * Verify that the Date(String) constructor works.
+ */
+ public void TestParseOfGMT()
+ {
+ Date OUT = null;
+
+ /* Input values */
+ String stringVal = "Jan 01 00:00:00 GMT 1900";
+ long expectedVal = -2208988800000L;
+
+ OUT = new Date( stringVal );
+
+ if( OUT.getTime( ) == expectedVal ) {
+ // logln("PASS");
+ }
+ else {
+ errln( "Expected: " +
+ new Date( expectedVal ) +
+ ": " +
+ expectedVal +
+ " Received: " +
+ OUT.toString() +
+ ": " +
+ OUT.getTime() );
+ }
+ }
+
+ // Check out Date's behavior with large negative year values; bug 664
+ // As of the fix to bug 4056585, Date should work correctly with
+ // large negative years.
+ public void TestDateNegativeYears()
+ {
+ Date d1= new Date(80,-1,2);
+ logln(d1.toString());
+ d1= new Date(-80,-1,2);
+ logln(d1.toString());
+ boolean e = false;
+ try {
+ d1= new Date(-800000,-1,2);
+ logln(d1.toString());
+ }
+ catch (IllegalArgumentException ex) {
+ e = true;
+ }
+ if (e) errln("FAIL: Saw exception for year -800000");
+ else logln("Pass: No exception for year -800000");
+ }
+
+ // Verify the behavior of Date
+ public void TestDate480()
+ {
+ TimeZone save = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("PST"));
+ Date d1=new java.util.Date(97,8,13,10,8,13);
+ logln("d = "+d1);
+ Date d2=new java.util.Date(97,8,13,30,8,13); // 20 hours later
+ logln("d+20h = "+d2);
+
+ double delta = (d2.getTime() - d1.getTime()) / 3600000;
+
+ logln("delta = " + delta + "h");
+
+ if (delta != 20.0) errln("Expected delta of 20; got " + delta);
+
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(1997,8,13,10,8,13);
+ Date t1 = cal.getTime();
+ logln("d = "+t1);
+ cal.clear();
+ cal.set(1997,8,13,30,8,13); // 20 hours later
+ Date t2 = cal.getTime();
+ logln("d+20h = "+t2);
+
+ double delta2 = (t2.getTime() - t1.getTime()) / 3600000;
+
+ logln("delta = " + delta2 + "h");
+
+ if (delta != 20.0) errln("Expected delta of 20; got " + delta2);
+ }
+ finally {
+ TimeZone.setDefault(save);
+ }
+ }
+}
diff --git a/jdk/test/java/util/Date/TZ.java b/jdk/test/java/util/Date/TZ.java
new file mode 100644
index 00000000000..56722a1cdb7
--- /dev/null
+++ b/jdk/test/java/util/Date/TZ.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1998, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4108737
+ * @summary java.util.Date doesn't fail if current TimeZone is changed
+ */
+
+import java.util.TimeZone;
+import java.util.Date;
+
+public class TZ {
+
+ public static void main(String args[]) {
+ TimeZone tz = TimeZone.getDefault();
+ try {
+ testMain();
+ } finally {
+ TimeZone.setDefault(tz);
+ }
+ }
+
+ static void testMain() {
+ String expectedResult = "Sat Feb 01 00:00:00 PST 1997";
+
+ // load the java.util.Date class in the GMT timezone
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ new Date(); // load the class (to run static initializers)
+
+ // use the class in different timezone
+ TimeZone.setDefault(TimeZone.getTimeZone("PST"));
+ @SuppressWarnings("deprecation")
+ Date date = new Date(97, 1, 1);
+ if (!date.toString().equals(expectedResult)) {
+ throw new RuntimeException("Regression bug id #4108737 - Date fails if default time zone changed");
+ }
+ }
+}
diff --git a/jdk/test/java/util/Date/TimestampTest.java b/jdk/test/java/util/Date/TimestampTest.java
new file mode 100644
index 00000000000..950f0a5fb91
--- /dev/null
+++ b/jdk/test/java/util/Date/TimestampTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2004, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 5008227
+ * @summary Make sure that changes to the Date class don't break java.sql.Timestamp.
+ * @modules java.sql
+ * @library /java/text/testlib
+ */
+
+import java.util.*;
+import java.sql.Timestamp;
+
+public class TimestampTest extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new TimestampTest().run(args);
+ }
+
+ /**
+ * 5008227: java.sql.Timestamp.after() is not returning correct result
+ *
+ * Test before(), after(), equals(), compareTo() and getTime().
+ */
+ public void Test5008227() {
+ long t = System.currentTimeMillis();
+ Timestamp ts1 = new Timestamp(t), ts2 = new Timestamp(t);
+ ts1.setNanos(999999999);
+ ts2.setNanos( 1000000);
+ compareTimestamps(ts1, ts2, 1);
+
+ ts1.setTime(t + 1000);
+ ts2.setTime(t);
+ ts1.setNanos( 999999);
+ ts2.setNanos(999999999);
+ compareTimestamps(ts1, ts2, 1);
+
+ ts1.setTime(t);
+ ts2.setTime(t);
+ ts1.setNanos(123456789);
+ ts2.setNanos(123456789);
+ compareTimestamps(ts1, ts2, 0);
+
+ ts1.setTime(t);
+ ts2.setTime(t);
+ ts1.setNanos(1);
+ ts2.setNanos(2);
+ compareTimestamps(ts1, ts2, -1);
+
+ ts1.setTime(t);
+ ts2.setTime(t+1000);
+ ts1.setNanos(999999);
+ ts2.setNanos( 0);
+ compareTimestamps(ts1, ts2, -1);
+ }
+
+ /**
+ * Compares two Timestamps with the expected result.
+ *
+ * @param ts1 the first Timestamp
+ * @param ts2 the second Timestamp
+ * @param expect the expected relation between ts1 and ts2; 0 if
+ * ts1 equals to ts2, or 1 if ts1 is after ts2, or -1 if ts1 is
+ * before ts2.
+ */
+ private void compareTimestamps(Timestamp ts1, Timestamp ts2, int expected) {
+ boolean expectedResult = expected > 0;
+ boolean result = ts1.after(ts2);
+ if (result != expectedResult) {
+ errln("ts1.after(ts2) returned " + result
+ + ". (ts1=" + ts1 + ", ts2=" + ts2 + ")");
+ }
+
+ expectedResult = expected < 0;
+ result = ts1.before(ts2);
+ if (result != expectedResult) {
+ errln("ts1.before(ts2) returned " + result
+ + ". (ts1=" + ts1 + ", ts2=" + ts2 + ")");
+ }
+
+ expectedResult = expected == 0;
+ result = ts1.equals(ts2);
+ if (result != expectedResult) {
+ errln("ts1.equals(ts2) returned " + result
+ + ". (ts1=" + ts1 + ", ts2=" + ts2 + ")");
+ }
+
+ int x = ts1.compareTo(ts2);
+ int y = (x > 0) ? 1 : (x < 0) ? -1 : 0;
+ if (y != expected) {
+ errln("ts1.compareTo(ts2) returned " + x + ", expected "
+ + relation(expected, "") + "0"
+ + ". (ts1=" + ts1 + ", ts2=" + ts2 + ")");
+ }
+ long t1 = ts1.getTime();
+ long t2 = ts2.getTime();
+ int z = (t1 > t2) ? 1 : (t1 < t2) ? -1 : 0;
+ if (z == 0) {
+ int n1 = ts1.getNanos();
+ int n2 = ts2.getNanos();
+ z = (n1 > n2) ? 1 : (n1 < n2) ? -1 : 0;
+ }
+ if (z != expected) {
+ errln("ts1.getTime() " + relation(z, "==") + " ts2.getTime(), expected "
+ + relation(expected, "==")
+ + ". (ts1=" + ts1 + ", ts2=" + ts2 + ")");
+ }
+ }
+
+ private static String relation(int x, String whenEqual) {
+ return (x > 0) ? ">" : (x < 0) ? "<" : whenEqual;
+ }
+}
diff --git a/jdk/test/java/util/ResourceBundle/RestrictedBundleTest.html b/jdk/test/java/util/ResourceBundle/RestrictedBundleTest.html
deleted file mode 100644
index 4214467a1e9..00000000000
--- a/jdk/test/java/util/ResourceBundle/RestrictedBundleTest.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
-This is a test.
-
diff --git a/jdk/test/java/util/ResourceBundle/RestrictedBundleTest.java b/jdk/test/java/util/ResourceBundle/RestrictedBundleTest.java
deleted file mode 100644
index 7a1969164f0..00000000000
--- a/jdk/test/java/util/ResourceBundle/RestrictedBundleTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2007, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-/**
- * @test
- * @bug 4126805
- * @ignore until 6842022 is resolved
- * @run applet RestrictedBundleTest.html
- * @summary I was able to reproduce this bug with 1.2b2, but not with the current 1.2
- * build. It appears that it was fixed by changes to the class-loading mechanism,
- * which now throws a ClassNotFoundException where before it was propagating through
- * a bogus ClassFormatError. Therefore, this is just an additional regression test
- * for whatever bug that was.
- */
-
-import java.util.ResourceBundle;
-import java.applet.Applet;
-import java.util.MissingResourceException;
-
-public class RestrictedBundleTest extends Applet {
- public void init() {
- super.init();
- try {
- ResourceBundle bundle = ResourceBundle.getBundle("unavailable.base.name");
-
- throw new RuntimeException("Error: MissingResourceException is not thrown");
- }
- catch (MissingResourceException e) {
- // other types of error will propagate back out into the test harness
- System.out.println("OK");
- }
- }
-}
diff --git a/jdk/test/java/util/TimeZone/Bug4322313.java b/jdk/test/java/util/TimeZone/Bug4322313.java
new file mode 100644
index 00000000000..fdd1f7c92ce
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/Bug4322313.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2001, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4322313
+ * @summary Make sure that new implementation of custom time zone
+ * support for TimeZone.getTimeZone() works correctly and the
+ * getDisplayName() methods are locale independent.
+ * @library /java/text/testlib
+ */
+
+import java.io.*;
+import java.text.*;
+import java.util.*;
+
+public class Bug4322313 extends IntlTest {
+ private static final int MPM = 60 * 1000; /* Milliseconds per minute */
+ private static final Object[][] VALIDS = {
+ /* given ID rawOffset normalized ID */
+ {"GMT+00:00", 0, "GMT+00:00"},
+ {"GMT+3:04", 184 * MPM, "GMT+03:04"},
+ {"GMT+03:04", 184 * MPM, "GMT+03:04"},
+ {"GMT+13:42", 822 * MPM, "GMT+13:42"},
+ /* ISO-LATIN-1 digits */
+ {"GMT+\u0030\u0031:\u0032\u0033", 83 * MPM, "GMT+01:23"},
+
+ {"GMT+0", 0, "GMT+00:00"},
+ {"GMT+3", 180 * MPM, "GMT+03:00"},
+ {"GMT+13", 780 * MPM, "GMT+13:00"},
+ {"GMT+034", 34 * MPM, "GMT+00:34"},
+ {"GMT+1034", 634 * MPM, "GMT+10:34"},
+
+ {"GMT-00:00", 0, "GMT-00:00"},
+ {"GMT-3:04", -184 * MPM, "GMT-03:04"},
+ {"GMT-03:04", -184 * MPM, "GMT-03:04"},
+ {"GMT-13:42", -822 * MPM, "GMT-13:42"},
+ /* ISO-LATIN-1 digits */
+ {"GMT-\u0030\u0031:\u0032\u0033", -83 * MPM, "GMT-01:23"},
+
+ {"GMT-0", 0, "GMT-00:00"},
+ {"GMT-3", -180 * MPM, "GMT-03:00"},
+ {"GMT-13", -780 * MPM, "GMT-13:00"},
+ {"GMT-034", -34 * MPM, "GMT-00:34"},
+ {"GMT-1034", -634 * MPM, "GMT-10:34"},
+ };
+
+ private static final String[] INVALIDS = {
+ "GMT+5:8", "GMT+11:1", "GMT+23:60", "GMT+24:13",
+ "GMT+0a:0A", "GMT +13:42", "GMT+ 13:42", "GMT+13 :42",
+ "GMT+13: 42", "GMT+421:950", "GMT+-13:42", "GMT+!13:42",
+ "GMT+a", "GMT+24", "GMT+060", "GMT+3003",
+ "GMT+42195", "GMT+-1", "GMT+-15", " GMT",
+
+ "GMT-5:8", "GMT-11:1", "GMT-23:60", "GMT-24:13",
+ "GMT-0a:0A", "GMT -13:42", "GMT- 13:42", "GMT-13 :42",
+ "GMT-13: 42", "GMT-421:950", "GMT-+13:42", "GMT-#13:42",
+ "GMT-a", "GMT-24", "GMT-060", "GMT-2403",
+ "GMT-42195", "GMT-+1", "GMT-+15", "G M T",
+ "GMT+09:00 ",
+ };
+
+ void Test4322313() {
+ Locale savedLocale = Locale.getDefault();
+ TimeZone savedTimeZone = TimeZone.getDefault();
+ boolean err = false;
+
+ Locale[] locs = Locale.getAvailableLocales();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+
+ for (int i = 0; i < locs.length; i++) {
+ Locale.setDefault(locs[i]);
+
+ /* Okay case */
+ for (int k = 0; k < VALIDS.length; k++) {
+ TimeZone tz = TimeZone.getTimeZone((String)VALIDS[k][0]);
+ int offset;
+
+ if (!tz.getID().equals(VALIDS[k][2])) {
+ err = true;
+ System.err.println("\tFailed [Locale=" +
+ Locale.getDefault() + ", \"" + VALIDS[k][0] +
+ "\"] Invalid TimeZone ID, expected:" +
+ VALIDS[k][2] + ", got:" + tz.getID() + ", " + tz);
+ } else {
+ logln("\tPassed [Locale=" +
+ Locale.getDefault() + ", \"" + VALIDS[k][0] +
+ "\"] Valid TimeZone ID, got:" + VALIDS[k][2]);
+ }
+
+ offset = tz.getRawOffset();
+ if (offset != (int)VALIDS[k][1]) {
+ err = true;
+ System.err.println("\tFailed [Locale=" +
+ Locale.getDefault() + ", \"" + VALIDS[k][0] +
+ "\"] Invalid RawOffset, expected:" + VALIDS[k][1] +
+ ", got:" + offset + ", " + tz);
+ } else {
+ logln("\tPassed [Locale=" +
+ Locale.getDefault() + ", \"" + VALIDS[k][0] +
+ "\"] Vaild RawOffset, got:" + offset);
+ }
+
+ offset = tz.getDSTSavings();
+ if (offset != 0) {
+ err = true;
+ System.err.println("\tFailed [Locale=" +
+ Locale.getDefault() + ", \"" + VALIDS[k][0] +
+ "\"] DSTSavings should be zero, got:" + offset +
+ ", " + tz);
+ } else {
+ logln("\tPassed [Locale=" +
+ Locale.getDefault() + ", \"" + VALIDS[k][0] +
+ "\"] DSTSavings is zero.");
+ }
+ }
+
+ /* Error case */
+ for (int k=0; k < INVALIDS.length; k++) {
+ TimeZone tz = TimeZone.getTimeZone(INVALIDS[k]);
+ int offset;
+
+ if (!tz.getID().equals("GMT")) {
+ err = true;
+ System.err.println("\tFailed [Locale=" +
+ Locale.getDefault() + ", \"" + INVALIDS[k] +
+ "\"] Invalid TimeZone ID, expected:GMT, got:" +
+ tz.getID() + ", " + tz);
+ } else {
+ logln("\tPassed [Locale=" +
+ Locale.getDefault() + ", \"" + INVALIDS[k] +
+ "\"] Valid TimeZone ID, got:" + tz.getID());
+ }
+
+ offset = tz.getRawOffset();
+ if (offset != 0) {
+ err = true;
+ System.err.println("\tFailed [Locale=" +
+ Locale.getDefault() + ", \"" + INVALIDS[k] +
+ "\"] RawOffset should be zero, got:" + offset +
+ ", " + tz);
+ } else {
+ logln("\tPassed [Locale=" +
+ Locale.getDefault() + ", \"" + INVALIDS[k] +
+ "\"] RawOffset is zero.");
+ }
+
+ offset = tz.getDSTSavings();
+ if (offset != 0) {
+ err = true;
+ System.err.println("\tFailed [Locale=" +
+ Locale.getDefault() + ", \"" + INVALIDS[k] +
+ "\"] DSTSavings should be zero, got:" + offset +
+ ", " + tz);
+ } else {
+ logln("\tPassed [Locale=" +
+ Locale.getDefault() + ", \"" + INVALIDS[k] +
+ "\"] DSTSavings is zero.");
+ }
+ }
+
+ // getDisplayName() tests
+ {
+ String normalizedID = "GMT-08:00";
+ TimeZone tz = TimeZone.getTimeZone("GMT-8");
+ String s;
+ s = tz.getDisplayName(true, tz.LONG);
+ if (!normalizedID.equals(s)) {
+ err = true;
+ System.err.println("getDisplayName returned unexpected name: " + s +
+ " in " + Locale.getDefault());
+ }
+ s = tz.getDisplayName(true, tz.SHORT);
+ if (!normalizedID.equals(s)) {
+ err = true;
+ System.err.println("getDisplayName returned unexpected name: " + s +
+ " in " + Locale.getDefault());
+ }
+ s = tz.getDisplayName(false, tz.LONG);
+ if (!normalizedID.equals(s)) {
+ err = true;
+ System.err.println("getDisplayName returned unexpected name: " + s +
+ " in " + Locale.getDefault());
+ }
+ s = tz.getDisplayName(false, tz.SHORT);
+ if (!normalizedID.equals(s)) {
+ err = true;
+ System.err.println("getDisplayName returned unexpected name: " + s +
+ " in " + Locale.getDefault());
+ }
+ }
+ }
+ } finally {
+ Locale.setDefault(savedLocale);
+ TimeZone.setDefault(savedTimeZone);
+ }
+ if (err) {
+ errln("TimeZone.getTimeZone() test failed");
+ } else {
+ logln("TimeZone.getTimeZone() test passed");
+ }
+ }
+
+ public static void main (String[] args) throws Exception {
+ new Bug4322313().run(args);
+ }
+}
diff --git a/jdk/test/java/util/TimeZone/Bug5097350.java b/jdk/test/java/util/TimeZone/Bug5097350.java
new file mode 100644
index 00000000000..ff0894bf3d7
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/Bug5097350.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2004, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 5097350
+ * @summary Make sure that TimeZone.getTimeZone returns a clone of a cached TimeZone instance.
+ */
+
+import java.util.*;
+import java.text.*;
+
+public class Bug5097350 {
+ public static void main(String[] args) {
+ String[] tzids = TimeZone.getAvailableIDs();
+ List ids = new ArrayList<>(tzids.length + 10);
+ ids.addAll(Arrays.asList(tzids));
+ // add some custom ids
+ ids.add("GMT+1");
+ ids.add("GMT-7:00");
+ ids.add("GMT+10:20");
+ ids.add("GMT-00:00");
+ ids.add("GMT+00:00");
+
+ for (String id : ids) {
+ test(id);
+ }
+ }
+
+ private static void test(String id) {
+ TimeZone tz1 = TimeZone.getTimeZone(id);
+ int offset1 = tz1.getRawOffset();
+ tz1.setRawOffset(offset1 + 13 * 60 * 60 * 1000);
+
+ TimeZone tz2 = TimeZone.getTimeZone(id);
+ if (tz1 == tz2) {
+ throw new RuntimeException("TimeZones are identical: " + id);
+ }
+ if (offset1 != tz2.getRawOffset()) {
+ throw new RuntimeException("Offset changed through aliasing: " + id);
+ }
+ }
+}
diff --git a/jdk/test/java/util/TimeZone/CheckDisplayNames.java b/jdk/test/java/util/TimeZone/CheckDisplayNames.java
new file mode 100644
index 00000000000..efdb5cdf38d
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/CheckDisplayNames.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2002, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6405639 8008577
+ * @summary Validate timezone display names in
+ * src/java.base/share/classes/sun/util/resources/TimeZoneNames.java.
+ * @modules java.base/sun.util.resources
+ * @compile -XDignore.symbol.file CheckDisplayNames.java
+ * @run main/othervm -Djava.locale.providers=COMPAT,SPI CheckDisplayNames
+ */
+
+import java.util.*;
+import sun.util.resources.TimeZoneNames;
+
+/**
+ * CheckDisplayNames checks all available time zones in the Java run
+ * time environment and sees if those have their display names besides doing
+ * some other test cases. It outputs time zones that don't have display names
+ * if -source option is specified.
+ *
+ *
+ * Usage: java CheckDisplayNames [-source]
+ * -source ... produces source code for editing TimeZoneNames.java.
+ *
+ *
+ */
+public class CheckDisplayNames {
+
+ private static boolean err = false;
+ private static boolean src = false;
+
+ private static Locale[] locales = Locale.getAvailableLocales();
+ private static String[] zones = TimeZone.getAvailableIDs();
+
+ private static String[] zones_118 = {
+ "ACT", "Australia/Darwin",
+ "AET", "Australia/Sydney",
+ "AGT", "America/Buenos_Aires",
+ "ART", "Africa/Cairo",
+ "AST", "America/Anchorage",
+ "BET", "America/Sao_Paulo",
+ "BST", "Asia/Dacca",
+ "CAT", "Africa/Harare",
+ "CNT", "America/St_Johns",
+ "CST", "America/Chicago",
+ "CTT", "Asia/Shanghai",
+ "EAT", "Africa/Addis_Ababa",
+ "ECT", "Europe/Paris",
+// "EET", "Africa/Istanbul",
+ "EST", "America/New_York",
+ "HST", "Pacific/Honolulu",
+ "IET", "America/Indiana/Indianapolis",
+// Comment out for this test case fails as the result of L10N for hi_IN.
+// "IST", "Asia/Calcutta",
+ "JST", "Asia/Tokyo",
+// "MET", "Asia/Tehran",
+ "MIT", "Pacific/Apia",
+ "MST", "America/Denver",
+ "NET", "Asia/Yerevan",
+ "NST", "Pacific/Auckland",
+ "PLT", "Asia/Karachi",
+ "PNT", "America/Phoenix",
+ "PRT", "America/Puerto_Rico",
+ "PST", "America/Los_Angeles",
+ "SST", "Pacific/Guadalcanal",
+ "VST", "Asia/Saigon",
+ };
+
+
+ public static void main(String[] argv) {
+ Locale reservedLocale = Locale.getDefault();
+ try {
+ if (argv.length == 1 && "-source".equals(argv[0])) {
+ src = true;
+ }
+
+ testDisplayNames();
+ testRAWoffsetAndDisplayNames();
+ test118DisplayNames();
+
+ if (err) {
+ throw new RuntimeException(
+ "TimeZone display name validation failed.");
+ } else {
+ System.out.println(
+ "\nAll test passed.\nTotal number of valid TimeZone id is "
+ + zones.length);
+ }
+ } finally {
+ // restore the reserved locale
+ Locale.setDefault(reservedLocale);
+ }
+
+ }
+
+ /*
+ * Checks if each timezone ID has display names. If it doesn't and
+ * "-source" option was specified, source code is generated.
+ */
+ private static void testDisplayNames() {
+ System.out.println("Checking if each entry in TimeZoneNames is a valid TimeZone ID");
+
+ Locale.setDefault(Locale.US);
+ Enumeration data = new TimeZoneNames().getKeys();
+
+ while (data.hasMoreElements()) {
+ String name = (String)data.nextElement();
+ String id = TimeZone.getTimeZone(name).getID();
+ if (!name.equals(id)) {
+ System.err.println("\t" + name + " doesn't seem to be a valid TimeZone ID.");
+ err = true;
+ }
+ }
+
+ System.out.println("Checking if each TimeZone ID has display names.");
+
+ for (int i = 0; i < zones.length; i++) {
+ String id = zones[i];
+
+ if (id != null) {
+ if (id.startsWith("Etc/GMT")) {
+ continue;
+ }
+ if (id.indexOf("Riyadh8") != -1) {
+ continue;
+ }
+ if (id.equals("GMT0")) {
+ continue;
+ }
+ }
+
+ TimeZone tz = TimeZone.getTimeZone(id);
+ String name = tz.getDisplayName();
+
+ if (name == null || name.startsWith("GMT+") || name.startsWith("GMT-")) {
+ if (src) {
+ System.out.println("\t {\"" + tz.getID() + "\", " +
+ "new String[] {\"Standard Time Name\", \"ST\",\n" +
+ "\t\t\t\t\t\t\"Daylight Time Name\", \"DT\"}},");
+ } else {
+ System.err.println("\t" + tz.getID() + " doesn't seem to have display names");
+ err = true;
+ }
+ }
+ }
+ }
+
+ /*
+ * Compares
+ * - raw DST offset
+ * - short display names in non-DST
+ * - short display names in DST
+ * - long display names in DST
+ * of two timezones whose long display names in non-DST are same.
+ * If one of these are different, there may be a bug.
+ */
+ private static void testRAWoffsetAndDisplayNames() {
+ System.out.println("Checking if each entry in TimeZoneNames is a valid TimeZone ID");
+
+ HashMap map = new HashMap();
+
+ for (int i = 0; i < locales.length; i++) {
+ map.clear();
+
+ for (int j = 0; j < zones.length; j++) {
+ TimeZone tz1 = TimeZone.getTimeZone(zones[j]);
+ String name = tz1.getDisplayName(false, TimeZone.LONG, locales[i]);
+
+ if (map.containsKey(name)) {
+ TimeZone tz2 = map.get(name);
+
+ int offset1 = tz1.getRawOffset();
+ int offset2 = tz2.getRawOffset();
+ if (offset1 != offset2) {
+ System.err.println("Two timezones which have the same long display name \"" +
+ name + "\" in non-DST have different DST offsets in " +
+ locales[i] + " locale.\n\tTimezone 1=" +
+ tz1.getID() + "(" + offset1 + ")\n\tTimezone 2=" +
+ tz2.getID() + "(" + offset2 + ")");
+ }
+
+ String name1 = tz1.getDisplayName(false, TimeZone.SHORT, locales[i]);
+ String name2 = tz2.getDisplayName(false, TimeZone.SHORT, locales[i]);
+ if (!(name1.equals("GMT") && name2.equals("GMT")) &&
+ !(name1.equals("CET") && name2.equals("MET")) &&
+ !(name1.equals("MET") && name2.equals("CET"))) {
+ if (!name1.equals(name2)) {
+ System.err.println("Two timezones which have the same short display name \"" +
+ name +
+ "\" in non-DST have different short display names in non-DST in " +
+ locales[i] + " locale.\n\tTimezone 1=" +
+ tz1.getID() + "(" + name1 + ")\n\tTimezone 2=" +
+ tz2.getID() + "(" + name2 + ")");
+ }
+
+ name1 = tz1.getDisplayName(true, TimeZone.SHORT, locales[i]);
+ name2 = tz2.getDisplayName(true, TimeZone.SHORT, locales[i]);
+ if (!name1.equals(name2)) {
+ System.err.println("Two timezones which have the same short display name \"" +
+ name +
+ "\" in non-DST have different short display names in DST in " +
+ locales[i] + " locale.\n\tTimezone 1=" +
+ tz1.getID() + "(" + name1 + ")\n\tTimezone 2=" +
+ tz2.getID() + "(" + name2 + ")");
+ }
+
+ name1 = tz1.getDisplayName(true, TimeZone.LONG, locales[i]);
+ name2 = tz2.getDisplayName(true, TimeZone.LONG, locales[i]);
+ if (!name1.equals(name2)) {
+ System.err.println("Two timezones which have the same long display name \"" +
+ name +
+ "\" in non-DST have different long display names in DST in " +
+ locales[i] + " locale.\n\tTimezone 1=" +
+ tz1.getID() + "(" + name1 + ")\n\tTimezone 2=" +
+ tz2.getID() + "(" + name2 + ")");
+ }
+ }
+ } else {
+ map.put(name, tz1);
+ }
+ }
+ }
+ }
+
+ /*
+ * Compares three-letter timezones' display names with corresponding
+ * "popular" timezones.
+ */
+ private static void test118DisplayNames() {
+ System.out.println("Checking compatibility of Java 1.1.X's three-letter timezones");
+
+ for (int i = 0; i < zones_118.length; i+=2) {
+ String id_118 = zones_118[i];
+ String id_later = zones_118[i+1];
+ String zone_118, zone_later, localename;
+ TimeZone tz_118 = TimeZone.getTimeZone(id_118);
+ TimeZone tz_later = TimeZone.getTimeZone(id_later);
+
+ for (int j = 0; j < locales.length; j++) {
+ localename = locales[j].toString();
+ zone_118 = tz_118.getDisplayName(false, TimeZone.SHORT, locales[j]);
+ zone_later = tz_later.getDisplayName(false, TimeZone.SHORT, locales[j]);
+ check(id_118, id_later, zone_118, zone_later, "short", "non-DST", localename);
+
+ zone_118 = tz_118.getDisplayName(true, TimeZone.SHORT, locales[j]);
+ zone_later = tz_later.getDisplayName(true, TimeZone.SHORT, locales[j]);
+ check(id_118, id_later, zone_118, zone_later, "short", "DST", localename);
+
+ zone_118 = tz_118.getDisplayName(false, TimeZone.LONG, locales[j]);
+ zone_later = tz_later.getDisplayName(false, TimeZone.LONG, locales[j]);
+ check(id_118, id_later, zone_118, zone_later, "long", "non-DST", localename);
+
+ zone_118 = tz_118.getDisplayName(true, TimeZone.LONG, locales[j]);
+ zone_later = tz_later.getDisplayName(true, TimeZone.LONG, locales[j]);
+ check(id_118, id_later, zone_118, zone_later, "long", "DST", localename);
+ }
+ }
+ }
+
+ private static void check(String zoneID_118, String zoneID_later,
+ String zonename_118, String zonename_later,
+ String format, String dst, String loc) {
+ if (!zonename_118.equals(zonename_later)) {
+ System.err.println("JDK 118 TimeZone \"" + zoneID_118 +
+ "\" has a different " + format +
+ " display name from its equivalent timezone \"" +
+ zoneID_later + "\" in " + dst + " in " + loc + " locale.");
+ System.err.println(" Got: " + zonename_118 + ", Expected: " +
+ zonename_later);
+ err = true;
+ }
+ }
+
+}
diff --git a/jdk/test/java/util/TimeZone/DefaultTimeZoneTest.html b/jdk/test/java/util/TimeZone/DefaultTimeZoneTest.html
new file mode 100644
index 00000000000..1fa0659ed63
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/DefaultTimeZoneTest.html
@@ -0,0 +1,74 @@
+
+
+
+
+
+ Disable Auto-adjust Daylight Saving Time Test
+
+
+
+This applet tests the platform time zone detection on all platforms (Part I)
+and on/off of DST adjustment on Windows (Part II).
+
+Part I:
+
+Observe the displayed Time zone ID and the local time. If you can change
+the platform time zone setting, try several time zones. If both the ID and
+the local time, including the time zone name and its time zone offset, are
+always correct, Part I passes. Note that some time zone IDs have their
+aliases that may be displayed. For example, "US/Pacific" is an alias of
+"America/Los_Angeles".
+
+If you are running this applet in non-English locale, the time zone names
+can be displayed in the local language and English by pushing the
+English/Local button.
+
+If platform time zones are NOT detected correctly, press the Fail button
+to finish this applet.
+
+If this platform is Windows, proceed to Part II. Otherwise, press the Pass
+button to finish this applet.
+
+Part II:
+
+Note that Part II may require the Administrator privilege to change
+Windows setting.
+
+ 1. Open the Date and Time control panel.
+ 2. Select any time zone where daylight saving time is *currently* in effect,
+ such as "(GMT-08:00) Pacific Time (US & Canada); Tijuana",
+ "(GMT+10:00) Canberra, Melbourne, Sydney", and Apply.
+ 3. Observe the local time on the control panel (Date&Time pane) and
+ the applet local time should be the same (daylight time).
+ 4. Clear "Automatically adjust clock for daylight saving changes" and Apply.
+ 5. Observe the two local times should be the same (standard time).
+ 6. Select "Automatically adjust clock for daylight saving changes" and Apply.
+
+If the local time in the control panel and applet are always the same,
+then this test passes. Press the Pass or Fail button based on the Part II
+result and finish this applet.
+
+
+
+
diff --git a/jdk/test/java/util/TimeZone/DefaultTimeZoneTest.java b/jdk/test/java/util/TimeZone/DefaultTimeZoneTest.java
new file mode 100644
index 00000000000..a6d3ac50866
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/DefaultTimeZoneTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4296930 5033603 7092679
+ * @summary Make sure that Java runtime detects the platform time zone
+ * correctly. Also make sure that the system time zone detection code
+ * detects the "Automatically adjust clock for daylight saving
+ * changes" setting correctly on Windows.
+ * @run applet/manual=yesno DefaultTimeZoneTest.html
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.text.*;
+import java.util.*;
+
+public class DefaultTimeZoneTest extends JApplet implements Runnable {
+ static final String FORMAT = "yyyy-MM-dd HH:mm:ss zzzz (XXX)";
+ JLabel tzid;
+ JLabel label;
+ SimpleDateFormat sdf = new SimpleDateFormat(FORMAT);
+ JButton button = new JButton("English");
+ Thread clock;
+ boolean english = false;
+
+ @Override
+ public void init() {
+ tzid = new JLabel("Time zone ID: " + sdf.getTimeZone().getID(), SwingConstants.CENTER);
+ tzid.setAlignmentX(Component.CENTER_ALIGNMENT);
+ label = new JLabel(sdf.format(new Date()), SwingConstants.CENTER);
+ label.setAlignmentX(Component.CENTER_ALIGNMENT);
+ button.addActionListener(new ActionListener() {
+ @Override
+ @SuppressWarnings("deprecation")
+ public void actionPerformed(ActionEvent e) {
+ english = (english == false);
+ Locale loc = english ? Locale.US : Locale.getDefault();
+ sdf = new SimpleDateFormat(FORMAT, loc);
+ button.setLabel(!english ? "English" : "Local");
+ }
+ });
+ button.setAlignmentX(Component.CENTER_ALIGNMENT);
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
+ panel.add(Box.createRigidArea(new Dimension(0, 10)));
+ panel.add(tzid);
+ panel.add(Box.createRigidArea(new Dimension(0, 5)));
+ panel.add(label);
+ panel.add(Box.createRigidArea(new Dimension(0, 10)));
+ panel.add(button);
+ getContentPane().add(panel);
+ }
+
+ @Override
+ public void start() {
+ clock = new Thread(this);
+ clock.start();
+ }
+
+ @Override
+ public void stop() {
+ clock = null;
+ }
+
+ @Override
+ public void run() {
+ Thread me = Thread.currentThread();
+
+ while (clock == me) {
+ // Reset the default time zone so that
+ // TimeZone.getDefault will detect the platform time zone
+ TimeZone.setDefault(null);
+ System.setProperty("user.timezone", "");
+ TimeZone tz = TimeZone.getDefault();
+ sdf.setTimeZone(tz);
+ tzid.setText("Time zone ID: " + tz.getID());
+ label.setText(sdf.format(new Date()));
+ repaint();
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+}
diff --git a/jdk/test/java/util/TimeZone/HongKong.java b/jdk/test/java/util/TimeZone/HongKong.java
new file mode 100644
index 00000000000..ef9c3f923f5
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/HongKong.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2001, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4487276 8008577
+ * @summary Verify that Hong Kong locale uses traditional Chinese names.
+ * @run main/othervm -Djava.locale.providers=COMPAT,SPI HongKong
+ */
+
+import java.util.Locale;
+import java.util.TimeZone;
+
+public class HongKong {
+ public static void main(String[] args) {
+ Locale reservedLocale = Locale.getDefault();
+ try {
+ Locale.setDefault(new Locale("zh", "HK"));
+ checkCountry(Locale.GERMANY, "\u5fb7\u570b");
+ checkCountry(Locale.FRANCE, "\u6cd5\u570b");
+ checkCountry(Locale.ITALY, "\u7fa9\u5927\u5229");
+ checkTimeZone("Asia/Shanghai",
+ "\u4e2d\u570b\u6a19\u6e96\u6642\u9593");
+ } finally {
+ // restore the reserved locale
+ Locale.setDefault(reservedLocale);
+ }
+ }
+
+ private static void checkCountry(Locale country, String expected) {
+ String actual = country.getDisplayCountry();
+ if (!expected.equals(actual)) {
+ throw new RuntimeException();
+ }
+ }
+
+ private static void checkTimeZone(String timeZoneID, String expected) {
+ TimeZone timeZone = TimeZone.getTimeZone(timeZoneID);
+ String actual = timeZone.getDisplayName();
+ if (!expected.equals(actual)) {
+ throw new RuntimeException();
+ }
+ }
+}
diff --git a/jdk/test/java/util/TimeZone/IDTest.java b/jdk/test/java/util/TimeZone/IDTest.java
new file mode 100644
index 00000000000..d5396b619b8
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/IDTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2002, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4509255 5055567 6176318 7090844
+ * @summary Tests consistencies of time zone IDs.
+ */
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.TreeMap;
+
+public class IDTest {
+ public static void main(String[] args) {
+ Set ids = new HashSet<>();
+ Map> tree = new TreeMap<>();
+
+ String[] tzs = TimeZone.getAvailableIDs();
+ String[] tzs2 = TimeZone.getAvailableIDs();
+ if (tzs.length != tzs2.length) {
+ throw new RuntimeException("tzs.length(" + tzs.length
+ + ") != tzs2.length(" + tzs2.length + ")");
+ }
+ for (int i = 0; i < tzs.length; i++) {
+ if (tzs[i] != tzs2[i]) {
+ throw new RuntimeException(i + ": " + tzs[i] + " != " + tzs2[i]);
+ }
+ }
+
+ System.out.println("Total: " + tzs.length + " time zone IDs");
+ for (String id : tzs) {
+ ids.add(id);
+ TimeZone tz = TimeZone.getTimeZone(id);
+ Integer offset = tz.getRawOffset();
+ Set s = tree.get(offset);
+ if (s == null) {
+ s = new HashSet<>();
+ tree.put(offset, s);
+ }
+ s.add(id);
+ }
+
+ for (Integer key : tree.keySet()) {
+ Set s1 = tree.get(key);
+
+ // Make sure no duplicates in the other sets
+ for (Integer k : tree.keySet()) {
+ if (k.equals(key)) {
+ continue;
+ }
+ Set s2 = new HashSet<>(tree.get(k));
+ s2.retainAll(s1);
+ if (!s2.isEmpty()) {
+ throw new RuntimeException("s1 included in the subset for " + (k.intValue()/60000) +
+ " (" + s2 + " shouldn't be in s1)");
+ }
+ }
+
+ // Check the getAvailableIDs(int) call to return the same
+ // set of IDs
+ int offset = key.intValue();
+ tzs = TimeZone.getAvailableIDs(offset);
+ tzs2 = TimeZone.getAvailableIDs(offset);
+ if (!Arrays.equals(tzs, tzs2)) {
+ throw new RuntimeException("inconsistent tzs from getAvailableIDs("+offset+")");
+ }
+ Set s2 = new HashSet<>();
+ s2.addAll(Arrays.asList(tzs));
+ if (!s1.equals(s2)) {
+ throw new RuntimeException("s1 != s2 for " + offset/60000 +
+ " (diff=" + getDiff(s1, s2) + ")");
+ }
+ if (!ids.containsAll(s2)) {
+ throw new RuntimeException("s2 isn't a subset of ids (" + getDiff(s2, ids) +
+ " not in ids)");
+ }
+ }
+
+ for (Integer key : tree.keySet()) {
+ Set s1 = tree.get(key);
+ ids.removeAll(s1);
+ }
+ if (!ids.isEmpty()) {
+ throw new RuntimeException("ids didn't become empty. (" + ids + ")");
+ }
+ }
+
+ private static String getDiff(Set set1, Set set2) {
+ Set s1 = new HashSet<>(set1);
+ s1.removeAll(set2);
+
+ Set s2 = new HashSet<>(set2);
+ s2.removeAll(set1);
+ s2.addAll(s1);
+ return s2.toString();
+ }
+}
diff --git a/jdk/test/java/util/TimeZone/TimeZoneBoundaryTest.java b/jdk/test/java/util/TimeZone/TimeZoneBoundaryTest.java
new file mode 100644
index 00000000000..a1d44ea080d
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/TimeZoneBoundaryTest.java
@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 1997, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /java/text/testlib
+ * @summary test Time Zone Boundary
+ */
+
+import java.text.*;
+import java.util.*;
+
+/**
+ * A test which discovers the boundaries of DST programmatically and verifies
+ * that they are correct.
+ */
+public class TimeZoneBoundaryTest extends IntlTest
+{
+ static final int ONE_SECOND = 1000;
+ static final int ONE_MINUTE = 60*ONE_SECOND;
+ static final int ONE_HOUR = 60*ONE_MINUTE;
+ static final long ONE_DAY = 24*ONE_HOUR;
+ static final long ONE_YEAR = (long)(365.25 * ONE_DAY);
+ static final long SIX_MONTHS = ONE_YEAR / 2;
+
+ static final int MONTH_LENGTH[] = {31,29,31,30,31,30,31,31,30,31,30,31};
+
+ // These values are empirically determined to be correct
+ static final long PST_1997_BEG = 860320800000L;
+ static final long PST_1997_END = 877856400000L;
+
+ // Minimum interval for binary searches in ms; should be no larger
+ // than 1000.
+ static final long INTERVAL = 10; // Milliseconds
+
+ static final String AUSTRALIA = "Australia/Adelaide";
+ static final long AUSTRALIA_1997_BEG = 877797000000L;
+ static final long AUSTRALIA_1997_END = 859653000000L;
+
+ public static void main(String[] args) throws Exception {
+ new TimeZoneBoundaryTest().run(args);
+ }
+
+ /**
+ * Date.toString().substring() Boundary Test
+ * Look for a DST changeover to occur within 6 months of the given Date.
+ * The initial Date.toString() should yield a string containing the
+ * startMode as a SUBSTRING. The boundary will be tested to be
+ * at the expectedBoundary value.
+ */
+ void findDaylightBoundaryUsingDate(Date d, String startMode, long expectedBoundary)
+ {
+ // Given a date with a year start, find the Daylight onset
+ // and end. The given date should be 1/1/xx in some year.
+
+ if (d.toString().indexOf(startMode) == -1)
+ {
+ logln("Error: " + startMode + " not present in " + d);
+ }
+
+ // Use a binary search, assuming that we have a Standard
+ // time at the midpoint.
+ long min = d.getTime();
+ long max = min + SIX_MONTHS;
+
+ while ((max - min) > INTERVAL)
+ {
+ long mid = (min + max) >> 1;
+ String s = new Date(mid).toString();
+ // logln(s);
+ if (s.indexOf(startMode) != -1)
+ {
+ min = mid;
+ }
+ else
+ {
+ max = mid;
+ }
+ }
+
+ logln("Date Before: " + showDate(min));
+ logln("Date After: " + showDate(max));
+ long mindelta = expectedBoundary - min;
+ long maxdelta = max - expectedBoundary;
+ if (mindelta >= 0 && mindelta <= INTERVAL &&
+ mindelta >= 0 && mindelta <= INTERVAL)
+ logln("PASS: Expected boundary at " + expectedBoundary);
+ else
+ errln("FAIL: Expected boundary at " + expectedBoundary);
+ }
+
+ void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST, long expectedBoundary)
+ {
+ findDaylightBoundaryUsingTimeZone(d, startsInDST, expectedBoundary,
+ TimeZone.getDefault());
+ }
+
+ void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST,
+ long expectedBoundary, TimeZone tz)
+ {
+ // Given a date with a year start, find the Daylight onset
+ // and end. The given date should be 1/1/xx in some year.
+
+ // Use a binary search, assuming that we have a Standard
+ // time at the midpoint.
+ long min = d.getTime();
+ long max = min + SIX_MONTHS;
+
+ if (tz.inDaylightTime(d) != startsInDST)
+ {
+ errln("FAIL: " + tz.getID() + " inDaylightTime(" +
+ d + ") != " + startsInDST);
+ startsInDST = !startsInDST; // Flip over; find the apparent value
+ }
+
+ if (tz.inDaylightTime(new Date(max)) == startsInDST)
+ {
+ errln("FAIL: " + tz.getID() + " inDaylightTime(" +
+ (new Date(max)) + ") != " + (!startsInDST));
+ return;
+ }
+
+ while ((max - min) > INTERVAL)
+ {
+ long mid = (min + max) >> 1;
+ boolean isIn = tz.inDaylightTime(new Date(mid));
+ if (isIn == startsInDST)
+ {
+ min = mid;
+ }
+ else
+ {
+ max = mid;
+ }
+ }
+
+ logln(tz.getID() + " Before: " + showDate(min, tz));
+ logln(tz.getID() + " After: " + showDate(max, tz));
+
+ long mindelta = expectedBoundary - min;
+ long maxdelta = max - expectedBoundary;
+ if (mindelta >= 0 && mindelta <= INTERVAL &&
+ mindelta >= 0 && mindelta <= INTERVAL)
+ logln("PASS: Expected boundary at " + expectedBoundary);
+ else
+ errln("FAIL: Expected boundary at " + expectedBoundary);
+ }
+
+ private static String showDate(long l)
+ {
+ return showDate(new Date(l));
+ }
+
+ @SuppressWarnings("deprecation")
+ private static String showDate(Date d)
+ {
+ return "" + d.getYear() + "/" + showNN(d.getMonth()+1) + "/" + showNN(d.getDate()) +
+ " " + showNN(d.getHours()) + ":" + showNN(d.getMinutes()) +
+ " \"" + d + "\" = " +
+ d.getTime();
+ }
+
+ private static String showDate(long l, TimeZone z)
+ {
+ return showDate(new Date(l), z);
+ }
+
+ @SuppressWarnings("deprecation")
+ private static String showDate(Date d, TimeZone zone)
+ {
+ DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ fmt.setTimeZone(zone);
+ return "" + d.getYear() + "/" + showNN(d.getMonth()+1) + "/" + showNN(d.getDate()) +
+ " " + showNN(d.getHours()) + ":" + showNN(d.getMinutes()) +
+ " \"" + d + "\" = " +
+ fmt.format(d);
+ }
+
+ private static String showNN(int n)
+ {
+ return ((n < 10) ? "0" : "") + n;
+ }
+
+ /**
+ * Given a date, a TimeZone, and expected values for inDaylightTime,
+ * useDaylightTime, zone and DST offset, verify that this is the case.
+ */
+ void verifyDST(Date d, TimeZone time_zone,
+ boolean expUseDaylightTime, boolean expInDaylightTime,
+ int expZoneOffset, int expDSTOffset)
+ {
+ logln("-- Verifying time " + d +
+ " in zone " + time_zone.getID());
+
+ if (time_zone.inDaylightTime(d) == expInDaylightTime)
+ logln("PASS: inDaylightTime = " + time_zone.inDaylightTime(d));
+ else
+ errln("FAIL: inDaylightTime = " + time_zone.inDaylightTime(d));
+
+ if (time_zone.useDaylightTime() == expUseDaylightTime)
+ logln("PASS: useDaylightTime = " + time_zone.useDaylightTime());
+ else
+ errln("FAIL: useDaylightTime = " + time_zone.useDaylightTime());
+
+ if (time_zone.getRawOffset() == expZoneOffset)
+ logln("PASS: getRawOffset() = " + expZoneOffset/(double)ONE_HOUR);
+ else
+ errln("FAIL: getRawOffset() = " + time_zone.getRawOffset()/(double)ONE_HOUR +
+ "; expected " + expZoneOffset/(double)ONE_HOUR);
+
+ GregorianCalendar gc = new GregorianCalendar(time_zone);
+ gc.setTime(d);
+ int offset = time_zone.getOffset(gc.get(gc.ERA), gc.get(gc.YEAR), gc.get(gc.MONTH),
+ gc.get(gc.DAY_OF_MONTH), gc.get(gc.DAY_OF_WEEK),
+ ((gc.get(gc.HOUR_OF_DAY) * 60 +
+ gc.get(gc.MINUTE)) * 60 +
+ gc.get(gc.SECOND)) * 1000 +
+ gc.get(gc.MILLISECOND));
+ if (offset == expDSTOffset)
+ logln("PASS: getOffset() = " + offset/(double)ONE_HOUR);
+ else
+ errln("FAIL: getOffset() = " + offset/(double)ONE_HOUR +
+ "; expected " + expDSTOffset/(double)ONE_HOUR);
+ }
+
+ @SuppressWarnings("deprecation")
+ public void TestBoundaries()
+ {
+ TimeZone pst = TimeZone.getTimeZone("PST");
+ TimeZone save = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(pst);
+
+ // DST changeover for PST is 4/6/1997 at 2 hours past midnight
+ Date d = new Date(97,Calendar.APRIL,6);
+
+ // i is minutes past midnight standard time
+ for (int i=60; i<=180; i+=15)
+ {
+ boolean inDST = (i >= 120);
+ Date e = new Date(d.getTime() + i*60*1000);
+ verifyDST(e, pst, true, inDST, -8*ONE_HOUR,
+ inDST ? -7*ONE_HOUR : -8*ONE_HOUR);
+ }
+
+ logln("========================================");
+ findDaylightBoundaryUsingDate(new Date(97,0,1), "PST", PST_1997_BEG);
+ logln("========================================");
+ findDaylightBoundaryUsingDate(new Date(97,6,1), "PDT", PST_1997_END);
+
+ // Southern hemisphere test
+ logln("========================================");
+ TimeZone z = TimeZone.getTimeZone(AUSTRALIA);
+ findDaylightBoundaryUsingTimeZone(new Date(97,0,1), true, AUSTRALIA_1997_END, z);
+
+ logln("========================================");
+ findDaylightBoundaryUsingTimeZone(new Date(97,0,1), false, PST_1997_BEG);
+ logln("========================================");
+ findDaylightBoundaryUsingTimeZone(new Date(97,6,1), true, PST_1997_END);
+ } finally {
+ TimeZone.setDefault(save);
+ }
+ }
+
+ void testUsingBinarySearch(SimpleTimeZone tz, Date d, long expectedBoundary)
+ {
+ // Given a date with a year start, find the Daylight onset
+ // and end. The given date should be 1/1/xx in some year.
+
+ // Use a binary search, assuming that we have a Standard
+ // time at the midpoint.
+ long min = d.getTime();
+ long max = min + (long)(365.25 / 2 * ONE_DAY);
+
+ // First check the boundaries
+ boolean startsInDST = tz.inDaylightTime(d);
+
+ if (tz.inDaylightTime(new Date(max)) == startsInDST)
+ {
+ logln("Error: inDaylightTime(" + (new Date(max)) + ") != " + (!startsInDST));
+ }
+
+ while ((max - min) > INTERVAL)
+ {
+ long mid = (min + max) >> 1;
+ if (tz.inDaylightTime(new Date(mid)) == startsInDST)
+ {
+ min = mid;
+ }
+ else
+ {
+ max = mid;
+ }
+ }
+
+ logln("Binary Search Before: " + showDate(min));
+ logln("Binary Search After: " + showDate(max));
+
+ long mindelta = expectedBoundary - min;
+ long maxdelta = max - expectedBoundary;
+ if (mindelta >= 0 && mindelta <= INTERVAL &&
+ mindelta >= 0 && mindelta <= INTERVAL)
+ logln("PASS: Expected boundary at " + expectedBoundary);
+ else
+ errln("FAIL: Expected boundary at " + expectedBoundary);
+ }
+
+ /*
+ static void testUsingMillis(Date d, boolean startsInDST)
+ {
+ long millis = d.getTime();
+ long max = millis + (long)(370 * ONE_DAY); // A year plus extra
+
+ boolean lastDST = startsInDST;
+ while (millis < max)
+ {
+ cal.setTime(new Date(millis));
+ boolean inDaylight = cal.inDaylightTime();
+
+ if (inDaylight != lastDST)
+ {
+ logln("Switch " + (inDaylight ? "into" : "out of")
+ + " DST at " + (new Date(millis)));
+ lastDST = inDaylight;
+ }
+
+ millis += 15*ONE_MINUTE;
+ }
+ }
+ */
+
+ /**
+ * Test new rule formats.
+ */
+ @SuppressWarnings("deprecation")
+ public void TestNewRules()
+ {
+ //logln(Locale.getDefault().getDisplayName());
+ //logln(TimeZone.getDefault().getID());
+ //logln(new Date(0));
+
+ if (true)
+ {
+ // Doesn't matter what the default TimeZone is here, since we
+ // are creating our own TimeZone objects.
+
+ SimpleTimeZone tz;
+
+ logln("-----------------------------------------------------------------");
+ logln("Aug 2ndTues .. Mar 15");
+ tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_1",
+ Calendar.AUGUST, 2, Calendar.TUESDAY, 2*ONE_HOUR,
+ Calendar.MARCH, 15, 0, 2*ONE_HOUR);
+ //logln(tz.toString());
+ logln("========================================");
+ testUsingBinarySearch(tz, new Date(97,0,1), 858416400000L);
+ logln("========================================");
+ testUsingBinarySearch(tz, new Date(97,6,1), 871380000000L);
+
+ logln("-----------------------------------------------------------------");
+ logln("Apr Wed>=14 .. Sep Sun<=20");
+ tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_2",
+ Calendar.APRIL, 14, -Calendar.WEDNESDAY, 2*ONE_HOUR,
+ Calendar.SEPTEMBER, -20, -Calendar.SUNDAY, 2*ONE_HOUR);
+ //logln(tz.toString());
+ logln("========================================");
+ testUsingBinarySearch(tz, new Date(97,0,1), 861184800000L);
+ logln("========================================");
+ testUsingBinarySearch(tz, new Date(97,6,1), 874227600000L);
+ }
+
+ /*
+ if (true)
+ {
+ logln("========================================");
+ logln("Stepping using millis");
+ testUsingMillis(new Date(97,0,1), false);
+ }
+
+ if (true)
+ {
+ logln("========================================");
+ logln("Stepping using fields");
+ testUsingFields(1997, false);
+ }
+
+ if (false)
+ {
+ cal.clear();
+ cal.set(1997, 3, 5, 10, 0);
+ // cal.inDaylightTime();
+ logln("Date = " + cal.getTime());
+ logln("Millis = " + cal.getTime().getTime()/3600000);
+ }
+ */
+ }
+
+ //----------------------------------------------------------------------
+ //----------------------------------------------------------------------
+ //----------------------------------------------------------------------
+ // Long Bug
+ //----------------------------------------------------------------------
+ //----------------------------------------------------------------------
+ //----------------------------------------------------------------------
+
+ //public void Test3()
+ //{
+ // findDaylightBoundaryUsingTimeZone(new Date(97,6,1), true);
+ //}
+
+ /**
+ * Find boundaries by stepping.
+ */
+ @SuppressWarnings("deprecation")
+ void findBoundariesStepwise(int year, long interval, TimeZone z, int expectedChanges)
+ {
+ Date d = new Date(year - 1900, Calendar.JANUARY, 1);
+ long time = d.getTime(); // ms
+ long limit = time + ONE_YEAR + ONE_DAY;
+ boolean lastState = z.inDaylightTime(d);
+ int changes = 0;
+ logln("-- Zone " + z.getID() + " starts in " + year + " with DST = " + lastState);
+ logln("useDaylightTime = " + z.useDaylightTime());
+ while (time < limit)
+ {
+ d.setTime(time);
+ boolean state = z.inDaylightTime(d);
+ if (state != lastState)
+ {
+ logln((state ? "Entry " : "Exit ") +
+ "at " + d);
+ lastState = state;
+ ++changes;
+ }
+ time += interval;
+ }
+ if (changes == 0)
+ {
+ if (!lastState && !z.useDaylightTime()) logln("No DST");
+ else errln("FAIL: Timezone<" + z.getID() + "> DST all year, or no DST with true useDaylightTime");
+ }
+ else if (changes != 2)
+ {
+ errln("FAIL: Timezone<" + z.getID() + "> " + changes + " changes seen; should see 0 or 2");
+ }
+ else if (!z.useDaylightTime())
+ {
+ errln("FAIL: Timezone<" + z.getID() + "> useDaylightTime false but 2 changes seen");
+ }
+ if (changes != expectedChanges)
+ {
+ errln("FAIL: Timezone<" + z.getID() + "> " + changes + " changes seen; expected " + expectedChanges);
+ }
+ }
+
+ public void TestStepwise()
+ {
+ findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("ACT"), 0);
+ // "EST" is disabled because its behavior depends on the mapping property. (6466476).
+ //findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("EST"), 2);
+ findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("HST"), 0);
+ findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("PST"), 2);
+ findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("PST8PDT"), 2);
+ findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("SystemV/PST"), 0);
+ findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("SystemV/PST8PDT"), 2);
+ findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Japan"), 0);
+ findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Europe/Paris"), 2);
+ findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("America/Los_Angeles"), 2);
+ findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone(AUSTRALIA), 2);
+ }
+}
diff --git a/jdk/test/java/util/TimeZone/TimeZoneRegression.java b/jdk/test/java/util/TimeZone/TimeZoneRegression.java
new file mode 100644
index 00000000000..8b9e2f4a22a
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/TimeZoneRegression.java
@@ -0,0 +1,995 @@
+/*
+ * Copyright (c) 1998, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4052967 4073209 4073215 4084933 4096952 4109314 4126678 4151406 4151429
+ * 4154525 4154537 4154542 4154650 4159922 4162593 4173604 4176686 4184229 4208960
+ * 4966229 6433179 6851214 8007520 8008577
+ * @library /java/text/testlib
+ * @run main/othervm -Djava.locale.providers=COMPAT,SPI TimeZoneRegression
+ */
+
+import java.util.*;
+import java.io.*;
+import java.text.*;
+
+public class TimeZoneRegression extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new TimeZoneRegression().run(args);
+ }
+
+ public void Test4052967() {
+ logln("*** CHECK TIMEZONE AGAINST HOST OS SETTING ***");
+ String id = TimeZone.getDefault().getID();
+ logln("user.timezone: " + System.getProperty("user.timezone", ""));
+ logln("TimeZone.getDefault().getID(): " + id);
+ logln(new Date().toString());
+ logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");
+ }
+
+ public void Test4073209() {
+ TimeZone z1 = TimeZone.getTimeZone("PST");
+ TimeZone z2 = TimeZone.getTimeZone("PST");
+ if (z1 == z2) {
+ errln("Fail: TimeZone should return clones");
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public void Test4073215() {
+ SimpleTimeZone z = new SimpleTimeZone(0, "GMT");
+ if (z.useDaylightTime()) {
+ errln("Fail: Fix test to start with non-DST zone");
+ }
+ z.setStartRule(Calendar.FEBRUARY, 1, Calendar.SUNDAY, 0);
+ z.setEndRule(Calendar.MARCH, -1, Calendar.SUNDAY, 0);
+ if (!z.useDaylightTime()) {
+ errln("Fail: DST not active");
+ }
+ if (z.inDaylightTime(new Date(97, Calendar.JANUARY, 31)) ||
+ !z.inDaylightTime(new Date(97, Calendar.MARCH, 1)) ||
+ z.inDaylightTime(new Date(97, Calendar.MARCH, 31))) {
+ errln("Fail: DST not working as expected");
+ }
+ }
+
+ /**
+ * The expected behavior of TimeZone around the boundaries is:
+ * (Assume transition time of 2:00 AM)
+ * day of onset 1:59 AM STD = display name 1:59 AM ST
+ * 2:00 AM STD = display name 3:00 AM DT
+ * day of end 0:59 AM STD = display name 1:59 AM DT
+ * 1:00 AM STD = display name 1:00 AM ST
+ */
+ public void Test4084933() {
+ // test both SimpleTimeZone and ZoneInfo objects.
+ // @since 1.4
+ sub4084933(getPST());
+ sub4084933(TimeZone.getTimeZone("PST"));
+ }
+
+ private void sub4084933(TimeZone tz) {
+ long offset1 = tz.getOffset(1,
+ 1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (2*60*60*1000));
+ long offset2 = tz.getOffset(1,
+ 1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (2*60*60*1000)-1);
+
+ long offset3 = tz.getOffset(1,
+ 1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (1*60*60*1000));
+ long offset4 = tz.getOffset(1,
+ 1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (1*60*60*1000)-1);
+
+ /*
+ * The following was added just for consistency. It shows that going *to* Daylight
+ * Savings Time (PDT) does work at 2am.
+ */
+
+ long offset5 = tz.getOffset(1,
+ 1997, Calendar.APRIL, 6, Calendar.SUNDAY, (2*60*60*1000));
+ long offset6 = tz.getOffset(1,
+ 1997, Calendar.APRIL, 6, Calendar.SUNDAY, (2*60*60*1000)-1);
+
+ long offset7 = tz.getOffset(1,
+ 1997, Calendar.APRIL, 6, Calendar.SUNDAY, (1*60*60*1000));
+ long offset8 = tz.getOffset(1,
+ 1997, Calendar.APRIL, 6, Calendar.SUNDAY, (1*60*60*1000)-1);
+
+ long SToffset = -8 * 60*60*1000L;
+ long DToffset = -7 * 60*60*1000L;
+ if (offset1 != SToffset || offset2 != SToffset ||
+ offset3 != SToffset || offset4 != DToffset ||
+ offset5 != DToffset || offset6 != SToffset ||
+ offset7 != SToffset || offset8 != SToffset)
+ errln("Fail: TimeZone misbehaving"); {
+ }
+ }
+
+ public void Test4096952() {
+ String[] ZONES = { "GMT", "MET", "IST" };
+ boolean pass = true;
+ try {
+ for (int i=0; i= ONE_DAY) {
+ millis -= ONE_DAY;
+ ++date;
+ dow = Calendar.SUNDAY + ((dow - Calendar.SUNDAY + 1) % 7);
+ }
+
+ tzOffset = testTZ.getOffset(testCal.get(Calendar.ERA),
+ testCal.get(Calendar.YEAR),
+ testCal.get(Calendar.MONTH),
+ date,
+ dow,
+ millis);
+ tzRawOffset = testTZ.getRawOffset();
+ tzOffsetFloat = new Float((float)tzOffset/(float)3600000);
+ tzRawOffsetFloat = new Float((float)tzRawOffset/(float)3600000);
+
+ Date testDate = testCal.getTime();
+
+ boolean inDaylightTime = testTZ.inDaylightTime(testDate);
+ SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm");
+ sdf.setCalendar(testCal);
+ String inDaylightTimeString;
+
+ boolean passed;
+
+ if (inDaylightTime)
+ {
+ inDaylightTimeString = " DST ";
+ passed = (tzOffset == (tzRawOffset + 3600000));
+ }
+ else
+ {
+ inDaylightTimeString = " ";
+ passed = (tzOffset == tzRawOffset);
+ }
+
+ String output = testTZ.getID() + " " + sdf.format(testDate) +
+ " Offset(" + tzOffsetFloat + ")" +
+ " RawOffset(" + tzRawOffsetFloat + ")" +
+ " " + millis/(float)3600000 + " " +
+ inDaylightTimeString;
+
+ if (passed)
+ output += " ";
+ else
+ output += "ERROR";
+
+ if (passed) logln(output); else errln(output);
+ return passed;
+ }
+
+ /**
+ * CANNOT REPRODUDE
+ *
+ * Yet another _alleged_ bug in TimeZone.getOffset(), a method that never
+ * should have been made public. It's simply too hard to use correctly.
+ *
+ * The original test code failed to do the following:
+ * (1) Call Calendar.setTime() before getting the fields!
+ * (2) Use the right millis (as usual) for getOffset(); they were passing
+ * in the MILLIS field, instead of the STANDARD MILLIS IN DAY.
+ * When you fix these two problems, the test passes, as expected.
+ */
+ public void Test4126678() {
+ // Note: this test depends on the PST time zone.
+ TimeZone initialZone = TimeZone.getDefault();
+
+ // test both SimpleTimeZone and ZoneInfo objects.
+ // @since 1.4
+ sub4126678(getPST());
+ sub4126678(TimeZone.getTimeZone("PST"));
+
+ // restore the initial time zone so that this test case
+ // doesn't affect the others.
+ TimeZone.setDefault(initialZone);
+ }
+
+ @SuppressWarnings("deprecation")
+ private void sub4126678(TimeZone tz) {
+ Calendar cal = Calendar.getInstance();
+ TimeZone.setDefault(tz);
+ cal.setTimeZone(tz);
+
+ Date dt = new Date(1998-1900, Calendar.APRIL, 5, 10, 0);
+ // the dt value is local time in PST.
+ if (!tz.inDaylightTime(dt))
+ errln("We're not in Daylight Savings Time and we should be.\n");
+
+ cal.setTime(dt);
+ int era = cal.get(Calendar.ERA);
+ int year = cal.get(Calendar.YEAR);
+ int month = cal.get(Calendar.MONTH);
+ int day = cal.get(Calendar.DATE);
+ int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
+ int millis = cal.get(Calendar.MILLISECOND) +
+ (cal.get(Calendar.SECOND) +
+ (cal.get(Calendar.MINUTE) +
+ (cal.get(Calendar.HOUR) * 60) * 60) * 1000) -
+ cal.get(Calendar.DST_OFFSET);
+
+ long offset = tz.getOffset(era, year, month, day, dayOfWeek, millis);
+ long raw_offset = tz.getRawOffset();
+ if (offset == raw_offset) {
+ errln("Offsets should not match when in DST");
+ }
+ }
+
+ /**
+ * TimeZone.getAvailableIDs(int) throws exception for certain values,
+ * due to a faulty constant in TimeZone.java.
+ */
+ public void Test4151406() {
+ int max = 0;
+ for (int h=-28; h<=30; ++h) {
+ // h is in half-hours from GMT; rawoffset is in millis
+ int rawoffset = h * 1800000;
+ int hh = (h<0) ? -h : h;
+ String hname = ((h<0) ? "GMT-" : "GMT+") +
+ ((hh/2 < 10) ? "0" : "") +
+ (hh/2) + ':' +
+ ((hh%2==0) ? "00" : "30");
+ try {
+ String[] ids = TimeZone.getAvailableIDs(rawoffset);
+ if (ids.length > max) max = ids.length;
+ logln(hname + ' ' + ids.length +
+ ((ids.length > 0) ? (" e.g. " + ids[0]) : ""));
+ } catch (Exception e) {
+ errln(hname + ' ' + "Fail: " + e);
+ }
+ }
+ logln("Maximum zones per offset = " + max);
+ }
+
+ public void Test4151429() {
+ try {
+ TimeZone tz = TimeZone.getTimeZone("GMT");
+ String name = tz.getDisplayName(true, Integer.MAX_VALUE,
+ Locale.getDefault());
+ errln("IllegalArgumentException not thrown by TimeZone.getDisplayName()");
+ } catch(IllegalArgumentException e) {}
+ }
+
+ /**
+ * SimpleTimeZone accepts illegal DST savings values. These values
+ * must be non-zero. There is no upper limit at this time.
+ */
+ public void Test4154525() {
+ final int GOOD = 1, BAD = 0;
+ int[] DATA = {
+ 1, GOOD,
+ 0, BAD,
+ -1, BAD,
+ 60*60*1000, GOOD,
+ Integer.MIN_VALUE, BAD,
+ // Integer.MAX_VALUE, ?, // no upper limit on DST savings at this time
+ };
+ for (int i=0; i) should work but throws " + ex)
+ : ", ) should fail but doesn't"));
+ }
+
+ ex = null;
+ try {
+ SimpleTimeZone temp = new SimpleTimeZone(0, "Z",
+ GOOD_MONTH, GOOD_DAY, GOOD_DAY_OF_WEEK, GOOD_TIME,
+ month, day, dayOfWeek, time);
+ } catch (IllegalArgumentException e) {
+ ex = e;
+ }
+ if ((ex == null) != shouldBeGood) {
+ errln("SimpleTimeZone(, month=" + month + ", day=" + day +
+ ", dayOfWeek=" + dayOfWeek + ", time=" + time +
+ (shouldBeGood ? (") should work but throws " + ex)
+ : ") should fail but doesn't"));
+ }
+ }
+ }
+
+ /**
+ * SimpleTimeZone.getOffset accepts illegal arguments.
+ */
+ public void Test4154650() {
+ final int GOOD=1, BAD=0;
+ final int GOOD_ERA=GregorianCalendar.AD, GOOD_YEAR=1998, GOOD_MONTH=Calendar.AUGUST;
+ final int GOOD_DAY=2, GOOD_DOW=Calendar.SUNDAY, GOOD_TIME=16*3600000;
+ int[] DATA = {
+ GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
+
+ GOOD, GregorianCalendar.BC, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
+ GOOD, GregorianCalendar.AD, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
+ BAD, GregorianCalendar.BC-1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
+ BAD, GregorianCalendar.AD+1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
+
+ GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, GOOD_DAY, GOOD_DOW, GOOD_TIME,
+ GOOD, GOOD_ERA, GOOD_YEAR, Calendar.DECEMBER, GOOD_DAY, GOOD_DOW, GOOD_TIME,
+ BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY-1, GOOD_DAY, GOOD_DOW, GOOD_TIME,
+ BAD, GOOD_ERA, GOOD_YEAR, Calendar.DECEMBER+1, GOOD_DAY, GOOD_DOW, GOOD_TIME,
+
+ GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 1, GOOD_DOW, GOOD_TIME,
+ GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 31, GOOD_DOW, GOOD_TIME,
+ BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 0, GOOD_DOW, GOOD_TIME,
+ BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 32, GOOD_DOW, GOOD_TIME,
+
+ GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SUNDAY, GOOD_TIME,
+ GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SATURDAY, GOOD_TIME,
+ BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SUNDAY-1, GOOD_TIME,
+ BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SATURDAY+1, GOOD_TIME,
+
+ GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 0,
+ GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000-1,
+ BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, -1,
+ BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000,
+ };
+
+ TimeZone tz = TimeZone.getDefault();
+ for (int i=0; i " + DATA[i+1] + ", exp " + DATA[i+2]);
+ }
+ }
+ }
+
+ /**
+ * SimpleTimeZone allows invalid DOM values.
+ */
+ public void Test4184229() {
+ SimpleTimeZone zone = null;
+ try {
+ zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0);
+ errln("Failed. No exception has been thrown for DOM -1 startDay");
+ } catch(IllegalArgumentException e) {
+ logln("(a) " + e.getMessage());
+ }
+ try {
+ zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0);
+ errln("Failed. No exception has been thrown for DOM -1 endDay");
+ } catch(IllegalArgumentException e) {
+ logln("(b) " + e.getMessage());
+ }
+ try {
+ zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0, 1000);
+ errln("Failed. No exception has been thrown for DOM -1 startDay +savings");
+ } catch(IllegalArgumentException e) {
+ logln("(c) " + e.getMessage());
+ }
+ try {
+ zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0, 1000);
+ errln("Failed. No exception has been thrown for DOM -1 endDay +savings");
+ } catch(IllegalArgumentException e) {
+ logln("(d) " + e.getMessage());
+ }
+ // Make a valid constructor call for subsequent tests.
+ zone = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 0, 1, 0, 0);
+ try {
+ zone.setStartRule(0, -1, 0, 0);
+ errln("Failed. No exception has been thrown for DOM -1 setStartRule +savings");
+ } catch(IllegalArgumentException e) {
+ logln("(e) " + e.getMessage());
+ }
+ try {
+ zone.setStartRule(0, -1, 0);
+ errln("Failed. No exception has been thrown for DOM -1 setStartRule");
+ } catch(IllegalArgumentException e) {
+ logln("(f) " + e.getMessage());
+ }
+ try {
+ zone.setEndRule(0, -1, 0, 0);
+ errln("Failed. No exception has been thrown for DOM -1 setEndRule +savings");
+ } catch(IllegalArgumentException e) {
+ logln("(g) " + e.getMessage());
+ }
+ try {
+ zone.setEndRule(0, -1, 0);
+ errln("Failed. No exception has been thrown for DOM -1 setEndRule");
+ } catch(IllegalArgumentException e) {
+ logln("(h) " + e.getMessage());
+ }
+ }
+
+ /**
+ * SimpleTimeZone.getOffset() throws IllegalArgumentException when to get
+ * of 2/29/1996 (leap day).
+ */
+ public void Test4208960 () {
+ // test both SimpleTimeZone and ZoneInfo objects.
+ // @since 1.4
+ sub4208960(getPST());
+ sub4208960(TimeZone.getTimeZone("PST"));
+ }
+
+ private void sub4208960(TimeZone tz) {
+ try {
+ int offset = tz.getOffset(GregorianCalendar.AD, 1996, Calendar.FEBRUARY, 29,
+ Calendar.THURSDAY, 0);
+ } catch (IllegalArgumentException e) {
+ errln("FAILED: to get TimeZone.getOffset(2/29/96)");
+ }
+ try {
+ int offset = tz.getOffset(GregorianCalendar.AD, 1997, Calendar.FEBRUARY, 29,
+ Calendar.THURSDAY, 0);
+ errln("FAILED: TimeZone.getOffset(2/29/97) expected to throw Exception.");
+ } catch (IllegalArgumentException e) {
+ logln("got IllegalArgumentException");
+ }
+ }
+
+ /**
+ * 4966229: java.util.Date methods may works incorrect.
+ * sun.util.calendar.ZoneInfo doesn't clone properly.
+ */
+ @SuppressWarnings("deprecation")
+ public void Test4966229() {
+ TimeZone savedTZ = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ Date d = new Date(2100-1900, 5, 1); // specify year >2037
+ TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
+
+ Calendar cal = new GregorianCalendar(tz);
+ cal.setTime(d);
+
+ // Change the raw offset in tz
+ int offset = tz.getRawOffset();
+ tz.setRawOffset(0);
+
+ TimeZone tz2 = (TimeZone) tz.clone();
+ Calendar cal2 = new GregorianCalendar(tz2);
+ cal2.setTime(d);
+ int expectedHourOfDay = cal2.get(cal.HOUR_OF_DAY);
+
+ // Restore the GMT offset in tz which shouldn't affect tz2
+ tz.setRawOffset(offset);
+ cal2.setTime(d);
+ int hourOfDay = cal2.get(cal.HOUR_OF_DAY);
+ if (hourOfDay != expectedHourOfDay) {
+ errln("wrong hour of day: got: " + hourOfDay
+ + ", expected: " + expectedHourOfDay);
+ }
+ } finally {
+ TimeZone.setDefault(savedTZ);
+ }
+ }
+
+ /**
+ * 6433179: (tz) Incorrect DST end for America/Winnipeg and Canada/Central in 2038+
+ */
+ public void Test6433179() {
+ // Use the old America/Winnipeg rule for testing. Note that
+ // startMode is WALL_TIME for testing. It's actually
+ // STANDARD_TIME, though.
+ //Rule Winn 1966 2005 - Oct lastSun 2:00s 0 S
+ //Rule Winn 1987 2005 - Apr Sun>=1 2:00s 1:00 D
+ TimeZone tz = new SimpleTimeZone(-6*ONE_HOUR, "America/Winnipeg",
+ Calendar.APRIL, 1, -Calendar.SUNDAY, 2*ONE_HOUR, SimpleTimeZone.WALL_TIME,
+ Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*ONE_HOUR, SimpleTimeZone.STANDARD_TIME,
+ 1*ONE_HOUR);
+ Calendar cal = Calendar.getInstance(tz, Locale.US);
+ cal.clear();
+ cal.set(2039, Calendar.OCTOBER, 1);
+ cal.getTime();
+ cal.set(cal.DAY_OF_WEEK, cal.SUNDAY);
+ cal.set(cal.DAY_OF_WEEK_IN_MONTH, -1);
+ cal.add(Calendar.HOUR_OF_DAY, 2);
+ if (cal.get(cal.DST_OFFSET) == 0) {
+ errln("Should still be in DST.");
+ }
+ }
+
+ private static final int ONE_HOUR = 60 * 60 * 1000;
+ /**
+ * Returns an instance of SimpleTimeZone for
+ * "PST". (TimeZone.getTimeZone() no longer returns a
+ * SimpleTimeZone object.)
+ * @since 1.4
+ */
+ private SimpleTimeZone getPST() {
+ return new SimpleTimeZone(-8*ONE_HOUR, "PST",
+ Calendar.APRIL, 1, -Calendar.SUNDAY, 2*ONE_HOUR,
+ Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*ONE_HOUR,
+ 1*ONE_HOUR);
+ }
+}
+//eof
diff --git a/jdk/test/java/util/TimeZone/TimeZoneTest.java b/jdk/test/java/util/TimeZone/TimeZoneTest.java
new file mode 100644
index 00000000000..2413d15e8f5
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/TimeZoneTest.java
@@ -0,0 +1,737 @@
+/*
+ * Copyright (c) 1997, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4028006 4044013 4096694 4107276 4107570 4112869 4130885 7039469 7126465 7158483
+ * 8008577 8077685 8098547 8133321 8138716 8148446
+ * @modules java.base/sun.util.resources
+ * @library /java/text/testlib
+ * @summary test TimeZone
+ */
+
+import java.io.*;
+import java.text.*;
+import java.util.*;
+import sun.util.resources.LocaleData;
+
+public class TimeZoneTest extends IntlTest
+{
+ static final int millisPerHour = 3600000;
+
+ public static void main(String[] args) throws Exception {
+ new TimeZoneTest().run(args);
+ }
+
+ /**
+ * Bug 4130885
+ * Certain short zone IDs, used since 1.1.x, are incorrect.
+ *
+ * The worst of these is:
+ *
+ * "CAT" (Central African Time) should be GMT+2:00, but instead returns a
+ * zone at GMT-1:00. The zone at GMT-1:00 should be called EGT, CVT, EGST,
+ * or AZOST, depending on which zone is meant, but in no case is it CAT.
+ *
+ * Other wrong zone IDs:
+ *
+ * ECT (European Central Time) GMT+1:00: ECT is Ecuador Time,
+ * GMT-5:00. European Central time is abbreviated CEST.
+ *
+ * SST (Solomon Island Time) GMT+11:00. SST is actually Samoa Standard Time,
+ * GMT-11:00. Solomon Island time is SBT.
+ *
+ * NST (New Zealand Time) GMT+12:00. NST is the abbreviation for
+ * Newfoundland Standard Time, GMT-3:30. New Zealanders use NZST.
+ *
+ * AST (Alaska Standard Time) GMT-9:00. [This has already been noted in
+ * another bug.] It should be "AKST". AST is Atlantic Standard Time,
+ * GMT-4:00.
+ *
+ * PNT (Phoenix Time) GMT-7:00. PNT usually means Pitcairn Time,
+ * GMT-8:30. There is no standard abbreviation for Phoenix time, as distinct
+ * from MST with daylight savings.
+ *
+ * In addition to these problems, a number of zones are FAKE. That is, they
+ * don't match what people use in the real world.
+ *
+ * FAKE zones:
+ *
+ * EET (should be EEST)
+ * ART (should be EET)
+ * MET (should be IRST)
+ * NET (should be AMST)
+ * PLT (should be PKT)
+ * BST (should be BDT)
+ * VST (should be ICT)
+ * CTT (should be CST) +
+ * ACT (should be CST) +
+ * AET (should be EST) +
+ * MIT (should be WST) +
+ * IET (should be EST) +
+ * PRT (should be AST) +
+ * CNT (should be NST)
+ * AGT (should be ARST)
+ * BET (should be EST) +
+ *
+ * + A zone with the correct name already exists and means something
+ * else. E.g., EST usually indicates the US Eastern zone, so it cannot be
+ * used for Brazil (BET).
+ */
+ public void TestShortZoneIDs() throws Exception {
+
+ ZoneDescriptor[] JDK_116_REFERENCE_LIST = {
+ new ZoneDescriptor("MIT", 780, true),
+ new ZoneDescriptor("HST", -600, false),
+ new ZoneDescriptor("AST", -540, true),
+ new ZoneDescriptor("PST", -480, true),
+ new ZoneDescriptor("PNT", -420, false),
+ new ZoneDescriptor("MST", -420, false),
+ new ZoneDescriptor("CST", -360, true),
+ new ZoneDescriptor("IET", -300, true),
+ new ZoneDescriptor("EST", -300, false),
+ new ZoneDescriptor("PRT", -240, false),
+ new ZoneDescriptor("CNT", -210, true),
+ new ZoneDescriptor("AGT", -180, false),
+ new ZoneDescriptor("BET", -180, true),
+ // new ZoneDescriptor("CAT", -60, false), // Wrong:
+ // As of bug 4130885, fix CAT (Central Africa)
+ new ZoneDescriptor("CAT", 120, false), // Africa/Harare
+ new ZoneDescriptor("GMT", 0, false),
+ new ZoneDescriptor("UTC", 0, false),
+ new ZoneDescriptor("ECT", 60, true),
+ new ZoneDescriptor("ART", 120, false),
+ new ZoneDescriptor("EET", 120, true),
+ new ZoneDescriptor("EAT", 180, false),
+ new ZoneDescriptor("MET", 60, true),
+ new ZoneDescriptor("NET", 240, false),
+ new ZoneDescriptor("PLT", 300, false),
+ new ZoneDescriptor("IST", 330, false),
+ new ZoneDescriptor("BST", 360, false),
+ new ZoneDescriptor("VST", 420, false),
+ new ZoneDescriptor("CTT", 480, false),
+ new ZoneDescriptor("JST", 540, false),
+ new ZoneDescriptor("ACT", 570, false),
+ new ZoneDescriptor("AET", 600, true),
+ new ZoneDescriptor("SST", 660, false),
+ // new ZoneDescriptor("NST", 720, false),
+ // As of bug 4130885, fix NST (New Zealand)
+ new ZoneDescriptor("NST", 720, true), // Pacific/Auckland
+ };
+
+ Map hash = new HashMap<>();
+
+ String[] ids = TimeZone.getAvailableIDs();
+ for (String id : ids) {
+ if (id.length() == 3) {
+ hash.put(id, new ZoneDescriptor(TimeZone.getTimeZone(id)));
+ }
+ }
+
+ for (int i = 0; i < JDK_116_REFERENCE_LIST.length; ++i) {
+ ZoneDescriptor referenceZone = JDK_116_REFERENCE_LIST[i];
+ ZoneDescriptor currentZone = hash.get(referenceZone.getID());
+ if (referenceZone.equals(currentZone)) {
+ logln("ok " + referenceZone);
+ }
+ else {
+ errln("Fail: Expected " + referenceZone +
+ "; got " + currentZone);
+ }
+ }
+ }
+
+ /**
+ * A descriptor for a zone; used to regress the short zone IDs.
+ */
+ static class ZoneDescriptor {
+ String id;
+ int offset; // In minutes
+ boolean daylight;
+
+ ZoneDescriptor(TimeZone zone) {
+ this.id = zone.getID();
+ this.offset = zone.getRawOffset() / 60000;
+ this.daylight = zone.useDaylightTime();
+ }
+
+ ZoneDescriptor(String id, int offset, boolean daylight) {
+ this.id = id;
+ this.offset = offset;
+ this.daylight = daylight;
+ }
+
+ public String getID() { return id; }
+
+ @Override
+ public boolean equals(Object o) {
+ ZoneDescriptor that = (ZoneDescriptor)o;
+ return that != null &&
+ id.equals(that.id) &&
+ offset == that.offset &&
+ daylight == that.daylight;
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode() ^ offset | (daylight ? 1 : 0);
+ }
+
+ @Override
+ public String toString() {
+ int min = offset;
+ char sign = '+';
+ if (min < 0) { sign = '-'; min = -min; }
+
+ return "Zone[\"" + id + "\", GMT" + sign + (min/60) + ':' +
+ (min%60<10?"0":"") + (min%60) + ", " +
+ (daylight ? "Daylight" : "Standard") + "]";
+ }
+
+ public static int compare(Object o1, Object o2) {
+ ZoneDescriptor i1 = (ZoneDescriptor)o1;
+ ZoneDescriptor i2 = (ZoneDescriptor)o2;
+ if (i1.offset > i2.offset) return 1;
+ if (i1.offset < i2.offset) return -1;
+ if (i1.daylight && !i2.daylight) return 1;
+ if (!i1.daylight && i2.daylight) return -1;
+ return i1.id.compareTo(i2.id);
+ }
+ }
+
+ static final String formatMinutes(int min) {
+ char sign = '+';
+ if (min < 0) { sign = '-'; min = -min; }
+ int h = min/60;
+ min = min%60;
+ return "" + sign + h + ":" + ((min<10) ? "0" : "") + min;
+ }
+ /**
+ * As part of the VM fix (see CCC approved RFE 4028006, bug
+ * 4044013), TimeZone.getTimeZone() has been modified to recognize
+ * generic IDs of the form GMT[+-]hh:mm, GMT[+-]hhmm, and
+ * GMT[+-]hh. Test this behavior here.
+ *
+ * Bug 4044013
+ *
+ * ID "Custom" is no longer used for TimeZone objects created with
+ * a custom time zone ID, such as "GMT-8". See 4322313.
+ */
+ public void TestCustomParse() throws Exception {
+ Object[] DATA = {
+ // ID Expected offset in minutes
+ "GMT", null,
+ "GMT+0", new Integer(0),
+ "GMT+1", new Integer(60),
+ "GMT-0030", new Integer(-30),
+ "GMT+15:99", null,
+ "GMT+", null,
+ "GMT-", null,
+ "GMT+0:", null,
+ "GMT-:", null,
+ "GMT+0010", new Integer(10), // Interpret this as 00:10
+ "GMT-10", new Integer(-10*60),
+ "GMT+30", null,
+ "GMT-3:30", new Integer(-(3*60+30)),
+ "GMT-230", new Integer(-(2*60+30)),
+ };
+ for (int i=0; i generic GMT");
+ // When TimeZone.getTimeZone() can't parse the id, it
+ // returns GMT -- a dubious practice, but required for
+ // backward compatibility.
+ if (exp != null) {
+ throw new Exception("Expected offset of " + formatMinutes(exp.intValue()) +
+ " for " + id + ", got parse failure");
+ }
+ }
+ else {
+ int ioffset = zone.getRawOffset()/60000;
+ String offset = formatMinutes(ioffset);
+ logln(id + " -> " + zone.getID() + " GMT" + offset);
+ if (exp == null) {
+ throw new Exception("Expected parse failure for " + id +
+ ", got offset of " + offset +
+ ", id " + zone.getID());
+ }
+ else if (ioffset != exp.intValue()) {
+ throw new Exception("Expected offset of " + formatMinutes(exp.intValue()) +
+ ", id Custom, for " + id +
+ ", got offset of " + offset +
+ ", id " + zone.getID());
+ }
+ }
+ }
+ }
+
+ /**
+ * Test the basic functionality of the getDisplayName() API.
+ *
+ * Bug 4112869
+ * Bug 4028006
+ *
+ * See also API change request A41.
+ *
+ * 4/21/98 - make smarter, so the test works if the ext resources
+ * are present or not.
+ */
+ public void TestDisplayName() {
+ TimeZone zone = TimeZone.getTimeZone("PST");
+ String name = zone.getDisplayName(Locale.ENGLISH);
+ logln("PST->" + name);
+ if (!name.equals("Pacific Standard Time"))
+ errln("Fail: Expected \"Pacific Standard Time\"");
+
+ //*****************************************************************
+ // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
+ // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
+ // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
+ //*****************************************************************
+ Object[] DATA = {
+ new Boolean(false), new Integer(TimeZone.SHORT), "PST",
+ new Boolean(true), new Integer(TimeZone.SHORT), "PDT",
+ new Boolean(false), new Integer(TimeZone.LONG), "Pacific Standard Time",
+ new Boolean(true), new Integer(TimeZone.LONG), "Pacific Daylight Time",
+ };
+
+ for (int i=0; i" + zone2.inDaylightTime(new Date()));
+ name = zone2.getDisplayName(Locale.ENGLISH);
+ logln("Modified PST->" + name);
+ if (!name.equals("Pacific Standard Time"))
+ errln("Fail: Expected \"Pacific Standard Time\"");
+
+ // Make sure we get the default display format for Locales
+ // with no display name data.
+ Locale zh_CN = Locale.SIMPLIFIED_CHINESE;
+ name = zone.getDisplayName(zh_CN);
+ //*****************************************************************
+ // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
+ // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
+ // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
+ //*****************************************************************
+ logln("PST(zh_CN)->" + name);
+
+ // Now be smart -- check to see if zh resource is even present.
+ // If not, we expect the en fallback behavior.
+ ResourceBundle enRB = LocaleData.getBundle("sun.util.resources.TimeZoneNames",
+ Locale.ENGLISH);
+ ResourceBundle zhRB = LocaleData.getBundle("sun.util.resources.TimeZoneNames",
+ zh_CN);
+
+ boolean noZH = enRB == zhRB;
+
+ if (noZH) {
+ logln("Warning: Not testing the zh_CN behavior because resource is absent");
+ if (!name.equals("Pacific Standard Time"))
+ errln("Fail: Expected Pacific Standard Time");
+ }
+ else if (!name.equals("Pacific Standard Time") &&
+ !name.equals("\u592a\u5e73\u6d0b\u6807\u51c6\u65f6\u95f4") &&
+ !name.equals("GMT-08:00") &&
+ !name.equals("GMT-8:00") &&
+ !name.equals("GMT-0800") &&
+ !name.equals("GMT-800")) {
+ errln("Fail: Expected GMT-08:00 or something similar");
+ errln("************************************************************");
+ errln("THE ABOVE FAILURE MAY JUST MEAN THE LOCALE DATA HAS CHANGED");
+ errln("************************************************************");
+ }
+
+ // Now try a non-existent zone
+ zone2 = new SimpleTimeZone(90*60*1000, "xyzzy");
+ name = zone2.getDisplayName(Locale.ENGLISH);
+ logln("GMT+90min->" + name);
+ if (!name.equals("GMT+01:30") &&
+ !name.equals("GMT+1:30") &&
+ !name.equals("GMT+0130") &&
+ !name.equals("GMT+130"))
+ errln("Fail: Expected GMT+01:30 or something similar");
+ }
+
+ public void TestGenericAPI() {
+ String id = "NewGMT";
+ int offset = 12345;
+
+ SimpleTimeZone zone = new SimpleTimeZone(offset, id);
+ if (zone.useDaylightTime()) {
+ errln("FAIL: useDaylightTime should return false");
+ }
+
+ TimeZone zoneclone = (TimeZone)zone.clone();
+ if (!zoneclone.equals(zone)) {
+ errln("FAIL: clone or operator== failed");
+ }
+ zoneclone.setID("abc");
+ if (zoneclone.equals(zone)) {
+ errln("FAIL: clone or operator!= failed");
+ }
+
+ zoneclone = (TimeZone)zone.clone();
+ if (!zoneclone.equals(zone)) {
+ errln("FAIL: clone or operator== failed");
+ }
+ zoneclone.setRawOffset(45678);
+ if (zoneclone.equals(zone)) {
+ errln("FAIL: clone or operator!= failed");
+ }
+
+ TimeZone saveDefault = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(zone);
+ TimeZone defaultzone = TimeZone.getDefault();
+ if (defaultzone == zone) {
+ errln("FAIL: Default object is identical, not clone");
+ }
+ if (!defaultzone.equals(zone)) {
+ errln("FAIL: Default object is not equal");
+ }
+ }
+ finally {
+ TimeZone.setDefault(saveDefault);
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public void TestRuleAPI()
+ {
+ // ErrorCode status = ZERO_ERROR;
+
+ int offset = (int)(60*60*1000*1.75); // Pick a weird offset
+ SimpleTimeZone zone = new SimpleTimeZone(offset, "TestZone");
+ if (zone.useDaylightTime()) errln("FAIL: useDaylightTime should return false");
+
+ // Establish our expected transition times. Do this with a non-DST
+ // calendar with the (above) declared local offset.
+ GregorianCalendar gc = new GregorianCalendar(zone);
+ gc.clear();
+ gc.set(1990, Calendar.MARCH, 1);
+ long marchOneStd = gc.getTime().getTime(); // Local Std time midnight
+ gc.clear();
+ gc.set(1990, Calendar.JULY, 1);
+ long julyOneStd = gc.getTime().getTime(); // Local Std time midnight
+
+ // Starting and ending hours, WALL TIME
+ int startHour = (int)(2.25 * 3600000);
+ int endHour = (int)(3.5 * 3600000);
+
+ zone.setStartRule(Calendar.MARCH, 1, 0, startHour);
+ zone.setEndRule (Calendar.JULY, 1, 0, endHour);
+
+ gc = new GregorianCalendar(zone);
+ // if (failure(status, "new GregorianCalendar")) return;
+
+ long marchOne = marchOneStd + startHour;
+ long julyOne = julyOneStd + endHour - 3600000; // Adjust from wall to Std time
+
+ long expMarchOne = 636251400000L;
+ if (marchOne != expMarchOne)
+ {
+ errln("FAIL: Expected start computed as " + marchOne +
+ " = " + new Date(marchOne));
+ logln(" Should be " + expMarchOne +
+ " = " + new Date(expMarchOne));
+ }
+
+ long expJulyOne = 646793100000L;
+ if (julyOne != expJulyOne)
+ {
+ errln("FAIL: Expected start computed as " + julyOne +
+ " = " + new Date(julyOne));
+ logln(" Should be " + expJulyOne +
+ " = " + new Date(expJulyOne));
+ }
+
+ testUsingBinarySearch(zone, new Date(90, Calendar.JANUARY, 1).getTime(),
+ new Date(90, Calendar.JUNE, 15).getTime(), marchOne);
+ testUsingBinarySearch(zone, new Date(90, Calendar.JUNE, 1).getTime(),
+ new Date(90, Calendar.DECEMBER, 31).getTime(), julyOne);
+
+ if (zone.inDaylightTime(new Date(marchOne - 1000)) ||
+ !zone.inDaylightTime(new Date(marchOne)))
+ errln("FAIL: Start rule broken");
+ if (!zone.inDaylightTime(new Date(julyOne - 1000)) ||
+ zone.inDaylightTime(new Date(julyOne)))
+ errln("FAIL: End rule broken");
+
+ zone.setStartYear(1991);
+ if (zone.inDaylightTime(new Date(marchOne)) ||
+ zone.inDaylightTime(new Date(julyOne - 1000)))
+ errln("FAIL: Start year broken");
+
+ // failure(status, "TestRuleAPI");
+ // delete gc;
+ // delete zone;
+ }
+
+ void testUsingBinarySearch(SimpleTimeZone tz, long min, long max, long expectedBoundary)
+ {
+ // ErrorCode status = ZERO_ERROR;
+ boolean startsInDST = tz.inDaylightTime(new Date(min));
+ // if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
+ if (tz.inDaylightTime(new Date(max)) == startsInDST) {
+ logln("Error: inDaylightTime(" + new Date(max) + ") != " + (!startsInDST));
+ return;
+ }
+ // if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
+ while ((max - min) > INTERVAL) {
+ long mid = (min + max) / 2;
+ if (tz.inDaylightTime(new Date(mid)) == startsInDST) {
+ min = mid;
+ }
+ else {
+ max = mid;
+ }
+ // if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
+ }
+ logln("Binary Search Before: " + min + " = " + new Date(min));
+ logln("Binary Search After: " + max + " = " + new Date(max));
+ long mindelta = expectedBoundary - min;
+ long maxdelta = max - expectedBoundary;
+ if (mindelta >= 0 &&
+ mindelta <= INTERVAL &&
+ mindelta >= 0 &&
+ mindelta <= INTERVAL)
+ logln("PASS: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary));
+ else
+ errln("FAIL: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary));
+ }
+
+ static final int INTERVAL = 100;
+
+ // Bug 006; verify the offset for a specific zone.
+ public void TestPRTOffset()
+ {
+ TimeZone tz = TimeZone.getTimeZone( "PRT" );
+ if( tz == null ) {
+ errln( "FAIL: TimeZone(PRT) is null" );
+ }
+ else{
+ if (tz.getRawOffset() != (-4*millisPerHour))
+ errln("FAIL: Offset for PRT should be -4");
+ }
+
+ }
+
+ // Test various calls
+ @SuppressWarnings("deprecation")
+ public void TestVariousAPI518()
+ {
+ TimeZone time_zone = TimeZone.getTimeZone("PST");
+ Date d = new Date(97, Calendar.APRIL, 30);
+
+ logln("The timezone is " + time_zone.getID());
+
+ if (time_zone.inDaylightTime(d) != true)
+ errln("FAIL: inDaylightTime returned false");
+
+ if (time_zone.useDaylightTime() != true)
+ errln("FAIL: useDaylightTime returned false");
+
+ if (time_zone.getRawOffset() != -8*millisPerHour)
+ errln( "FAIL: getRawOffset returned wrong value");
+
+ GregorianCalendar gc = new GregorianCalendar();
+ gc.setTime(d);
+ if (time_zone.getOffset(gc.AD, gc.get(gc.YEAR), gc.get(gc.MONTH),
+ gc.get(gc.DAY_OF_MONTH),
+ gc.get(gc.DAY_OF_WEEK), 0)
+ != -7*millisPerHour)
+ errln("FAIL: getOffset returned wrong value");
+ }
+
+ // Test getAvailableID API
+ public void TestGetAvailableIDs913()
+ {
+ StringBuffer buf = new StringBuffer("TimeZone.getAvailableIDs() = { ");
+ String[] s = TimeZone.getAvailableIDs();
+ for (int i=0; i 0) buf.append(", ");
+ buf.append(s[i]);
+ }
+ buf.append(" };");
+ logln(buf.toString());
+
+ buf.setLength(0);
+ buf.append("TimeZone.getAvailableIDs(GMT+02:00) = { ");
+ s = TimeZone.getAvailableIDs(+2 * 60 * 60 * 1000);
+ for (int i=0; i 0) buf.append(", ");
+ buf.append(s[i]);
+ }
+ buf.append(" };");
+ logln(buf.toString());
+
+ TimeZone tz = TimeZone.getTimeZone("PST");
+ if (tz != null)
+ logln("getTimeZone(PST) = " + tz.getID());
+ else
+ errln("FAIL: getTimeZone(PST) = null");
+
+ tz = TimeZone.getTimeZone("America/Los_Angeles");
+ if (tz != null)
+ logln("getTimeZone(America/Los_Angeles) = " + tz.getID());
+ else
+ errln("FAIL: getTimeZone(PST) = null");
+
+ // Bug 4096694
+ tz = TimeZone.getTimeZone("NON_EXISTENT");
+ if (tz == null)
+ errln("FAIL: getTimeZone(NON_EXISTENT) = null");
+ else if (!tz.getID().equals("GMT"))
+ errln("FAIL: getTimeZone(NON_EXISTENT) = " + tz.getID());
+ }
+
+ /**
+ * Bug 4107276
+ */
+ public void TestDSTSavings() {
+ // It might be better to find a way to integrate this test into the main TimeZone
+ // tests above, but I don't have time to figure out how to do this (or if it's
+ // even really a good idea). Let's consider that a future. --rtg 1/27/98
+ SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "dstSavingsTest",
+ Calendar.MARCH, 1, 0, 0, Calendar.SEPTEMBER, 1, 0, 0,
+ (int)(0.5 * millisPerHour));
+
+ if (tz.getRawOffset() != -5 * millisPerHour)
+ errln("Got back a raw offset of " + (tz.getRawOffset() / millisPerHour) +
+ " hours instead of -5 hours.");
+ if (!tz.useDaylightTime())
+ errln("Test time zone should use DST but claims it doesn't.");
+ if (tz.getDSTSavings() != 0.5 * millisPerHour)
+ errln("Set DST offset to 0.5 hour, but got back " + (tz.getDSTSavings() /
+ millisPerHour) + " hours instead.");
+
+ int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,
+ Calendar.THURSDAY, 10 * millisPerHour);
+ if (offset != -5 * millisPerHour)
+ errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "
+ + (offset / millisPerHour) + " hours.");
+
+ offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,
+ 10 * millisPerHour);
+ if (offset != -4.5 * millisPerHour)
+ errln("The offset for 10 AM, 6/1/98 should have been -4.5 hours, but we got "
+ + (offset / millisPerHour) + " hours.");
+
+ tz.setDSTSavings(millisPerHour);
+ offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,
+ Calendar.THURSDAY, 10 * millisPerHour);
+ if (offset != -5 * millisPerHour)
+ errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "
+ + (offset / millisPerHour) + " hours.");
+
+ offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,
+ 10 * millisPerHour);
+ if (offset != -4 * millisPerHour)
+ errln("The offset for 10 AM, 6/1/98 (with a 1-hour DST offset) should have been -4 hours, but we got "
+ + (offset / millisPerHour) + " hours.");
+ }
+
+ /**
+ * Bug 4107570
+ */
+ public void TestAlternateRules() {
+ // Like TestDSTSavings, this test should probably be integrated somehow with the main
+ // test at the top of this class, but I didn't have time to figure out how to do that.
+ // --rtg 1/28/98
+
+ SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "alternateRuleTest");
+
+ // test the day-of-month API
+ tz.setStartRule(Calendar.MARCH, 10, 12 * millisPerHour);
+ tz.setEndRule(Calendar.OCTOBER, 20, 12 * millisPerHour);
+
+ int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 5,
+ Calendar.THURSDAY, 10 * millisPerHour);
+ if (offset != -5 * millisPerHour)
+ errln("The offset for 10AM, 3/5/98 should have been -5 hours, but we got "
+ + (offset / millisPerHour) + " hours.");
+
+ offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 15,
+ Calendar.SUNDAY, 10 * millisPerHour);
+ if (offset != -4 * millisPerHour)
+ errln("The offset for 10AM, 3/15/98 should have been -4 hours, but we got "
+ + (offset / millisPerHour) + " hours.");
+
+ offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,
+ Calendar.THURSDAY, 10 * millisPerHour);
+ if (offset != -4 * millisPerHour)
+ errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "
+ + (offset / millisPerHour) + " hours.");
+
+ offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 25,
+ Calendar.SUNDAY, 10 * millisPerHour);
+ if (offset != -5 * millisPerHour)
+ errln("The offset for 10AM, 10/25/98 should have been -5 hours, but we got "
+ + (offset / millisPerHour) + " hours.");
+
+ // test the day-of-week-after-day-in-month API
+ tz.setStartRule(Calendar.MARCH, 10, Calendar.FRIDAY, 12 * millisPerHour, true);
+ tz.setEndRule(Calendar.OCTOBER, 20, Calendar.FRIDAY, 12 * millisPerHour, false);
+
+ offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 11,
+ Calendar.WEDNESDAY, 10 * millisPerHour);
+ if (offset != -5 * millisPerHour)
+ errln("The offset for 10AM, 3/11/98 should have been -5 hours, but we got "
+ + (offset / millisPerHour) + " hours.");
+
+ offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 14,
+ Calendar.SATURDAY, 10 * millisPerHour);
+ if (offset != -4 * millisPerHour)
+ errln("The offset for 10AM, 3/14/98 should have been -4 hours, but we got "
+ + (offset / millisPerHour) + " hours.");
+
+ offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,
+ Calendar.THURSDAY, 10 * millisPerHour);
+ if (offset != -4 * millisPerHour)
+ errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "
+ + (offset / millisPerHour) + " hours.");
+
+ offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 17,
+ Calendar.SATURDAY, 10 * millisPerHour);
+ if (offset != -5 * millisPerHour)
+ errln("The offset for 10AM, 10/17/98 should have been -5 hours, but we got "
+ + (offset / millisPerHour) + " hours.");
+ }
+}
+
+//eof
diff --git a/jdk/test/java/util/TimeZone/TransitionTest.java b/jdk/test/java/util/TimeZone/TransitionTest.java
new file mode 100644
index 00000000000..5f012d09d72
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/TransitionTest.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2002, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4278609 4761696
+ * @library /java/text/testlib
+ * @summary Make sure to handle DST transition ending at 0:00 January 1.
+ */
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+
+public class TransitionTest extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new TransitionTest().run(args);
+ }
+
+ public void Test4278609() {
+ SimpleTimeZone tz = new SimpleTimeZone(0, "MyTimeZone",
+ /* DST start day: August, 1, 0:00 */
+ Calendar.AUGUST, 1, 0, 0,
+ /* DST end day: January, 1, 0:00 (wall-clock)*/
+ Calendar.JANUARY, 1, 0, 0,
+ 60 * 60 * 1000);
+
+ Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+
+ // setting a date using GMT zone just after the end rule of tz zone
+ cal.clear();
+ cal.set(Calendar.ERA, GregorianCalendar.AD);
+ cal.set(1998, Calendar.DECEMBER, 31, 23, 01, 00);
+
+ Date date = cal.getTime();
+
+ int millis = cal.get(Calendar.HOUR_OF_DAY) * 3600000
+ + cal.get(Calendar.MINUTE) * 60000
+ + cal.get(Calendar.SECOND) * 1000
+ + cal.get(Calendar.MILLISECOND);
+ /* we must use standard local time */
+ millis += tz.getRawOffset();
+
+ int offset = tz.getOffset(cal.get(Calendar.ERA),
+ cal.get(Calendar.YEAR),
+ cal.get(Calendar.MONTH),
+ cal.get(Calendar.DATE),
+ cal.get(Calendar.DAY_OF_WEEK),
+ millis);
+
+ if (offset != 0) {
+ SimpleDateFormat format = new SimpleDateFormat("dd MMM HH:mm:ss zzz",
+ Locale.US);
+ format.setTimeZone(tz);
+ errln("Wrong DST transition: " + tz
+ + "\na date just after DST = " + format.format(date)
+ + "\ngetOffset = " + offset);
+ }
+ }
+
+ /*
+ * 4761696: Rewrite SimpleTimeZone to support correct DST transitions
+ *
+ * Derived from JCK test cases some of which specify wrong day of week values.
+ */
+ public void Test4761696() {
+ GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+
+ // test#1
+ int rawOffset = -43200000;
+ int saving = 1800000;
+ int timeOfDay = 84600001;
+ SimpleTimeZone tz = new SimpleTimeZone(rawOffset, "stz",
+ Calendar.JULY, 1, 0, 0,
+ Calendar.JANUARY, 1, 0, 0,
+ saving);
+ int year = Integer.MIN_VALUE;
+ tz.setStartYear(year);
+ int offset = tz.getOffset(GregorianCalendar.AD,
+ year,
+ Calendar.DECEMBER,
+ 31,
+ 1, // should be SATURDAY
+ timeOfDay);
+ int y = (int) mod((long)year, 28L); // 28-year cycle
+ cal.clear();
+ cal.set(cal.ERA, cal.AD);
+ cal.set(y, Calendar.DECEMBER, 31);
+ cal.set(cal.MILLISECOND, timeOfDay);
+ long localtime = cal.getTimeInMillis() + rawOffset; // local standard time
+
+ cal.clear();
+ cal.set(cal.ERA, cal.AD);
+ cal.set(y + 1, Calendar.JANUARY, 1);
+ cal.set(cal.MILLISECOND, -saving);
+ long endTime = cal.getTimeInMillis() + rawOffset;
+ long expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset;
+ if (offset != expectedOffset) {
+ errln("test#1: wrong offset: got "+offset+", expected="+expectedOffset);
+ }
+
+ // test#2
+ saving = 1;
+ timeOfDay = 0;
+ tz = new SimpleTimeZone(rawOffset, "stz",
+ Calendar.JULY, 1, 0, 0,
+ Calendar.JANUARY, 1, 0, 0,
+ saving);
+ tz.setStartYear(year);
+ offset = tz.getOffset(GregorianCalendar.AD,
+ year,
+ Calendar.AUGUST,
+ 15,
+ 1, // should be MONDAY
+ timeOfDay);
+ y = (int) mod((long)year, 28L); // 28-year cycle
+ cal.clear();
+ cal.set(y, Calendar.AUGUST, 15);
+ cal.set(cal.MILLISECOND, timeOfDay);
+ localtime = cal.getTimeInMillis() + rawOffset; // local standard time
+
+ cal.clear();
+ cal.set(y + 1, Calendar.JANUARY, 1);
+ cal.set(cal.MILLISECOND, -saving);
+ endTime = cal.getTimeInMillis() + rawOffset;
+ expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset;
+ if (offset != expectedOffset) {
+ errln("Wrong offset: got "+offset+", expected="+expectedOffset);
+ }
+
+ rawOffset = 43200000;
+ saving = 1;
+ timeOfDay = 3599998;
+ tz = new SimpleTimeZone(rawOffset, "stz",
+ Calendar.JULY, 1, 0, 3600000,
+ Calendar.JANUARY, 1, 0, 3600000,
+ saving);
+ tz.setStartYear(year);
+ offset = tz.getOffset(GregorianCalendar.AD,
+ year,
+ Calendar.JANUARY,
+ 1,
+ 1,
+ timeOfDay);
+ y = (int) mod((long)year, 28L); // 28-year cycle
+ cal.clear();
+ cal.set(y, Calendar.JANUARY, 1);
+ cal.set(cal.MILLISECOND, timeOfDay);
+ localtime = cal.getTimeInMillis() + rawOffset; // local standard time
+
+ cal.clear();
+ cal.set(y + 1, Calendar.JANUARY, 1);
+ cal.set(cal.MILLISECOND, 3600000-saving);
+ endTime = cal.getTimeInMillis() + rawOffset;
+ expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset;
+ if (offset != expectedOffset) {
+ errln("test#2: wrong offset: got "+offset+", expected="+expectedOffset);
+ }
+
+ // test#3
+ rawOffset = -43200000;
+ saving = 1800000;
+ timeOfDay = 84600001;
+ tz = new SimpleTimeZone(rawOffset, "stz",
+ Calendar.SEPTEMBER, 1, 0, 0,
+ Calendar.MARCH, 1, 0, 0,
+ saving);
+ tz.setStartYear(year);
+ offset = tz.getOffset(GregorianCalendar.AD,
+ year,
+ Calendar.FEBRUARY,
+ 28,
+ 1,
+ timeOfDay);
+ y = (int) mod((long)year, 28L); // 28-year cycle
+ cal.clear();
+ cal.set(y, Calendar.FEBRUARY, 28);
+ cal.set(cal.MILLISECOND, timeOfDay);
+ localtime = cal.getTimeInMillis() + rawOffset; // local standard time
+
+ cal.clear();
+ cal.set(y, Calendar.MARCH, 1);
+ cal.set(cal.MILLISECOND, -saving);
+ endTime = cal.getTimeInMillis() + rawOffset;
+ expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset;
+ if (offset != expectedOffset) {
+ errln("test#3: wrong offset: got "+offset+", expected="+expectedOffset);
+ }
+
+ // test#4
+ rawOffset = -43200000;
+ saving = 1;
+ timeOfDay = 0;
+ tz = new SimpleTimeZone(rawOffset, "stz",
+ Calendar.JANUARY, -4, 1, 3600000,
+ Calendar.JULY, -4, 1, 3600000,
+ saving);
+ tz.setStartYear(year);
+ offset = tz.getOffset(GregorianCalendar.AD,
+ year,
+ Calendar.JANUARY,
+ 10,
+ 2, // should be 1 (SUNDAY)
+ timeOfDay);
+ y = (int) mod((long)year, 28L); // 28-year cycle
+ cal.clear();
+ cal.set(y, Calendar.JANUARY, 10);
+ cal.set(cal.MILLISECOND, timeOfDay);
+ localtime = cal.getTimeInMillis() + rawOffset; // local standard time
+
+ cal.clear();
+ cal.set(cal.YEAR, y);
+ cal.set(cal.MONTH, Calendar.JANUARY);
+ cal.set(cal.DAY_OF_MONTH, 8);
+ cal.set(cal.WEEK_OF_MONTH, cal.getActualMaximum(cal.WEEK_OF_MONTH)-4+1);
+ cal.set(cal.DAY_OF_WEEK, 1);
+ cal.set(cal.MILLISECOND, 3600000-saving);
+ long startTime = cal.getTimeInMillis() + rawOffset;
+ expectedOffset = (localtime >= startTime) ? rawOffset + saving : rawOffset;
+ if (offset != expectedOffset) {
+ errln("test#4: wrong offset: got "+offset+", expected="+expectedOffset);
+ }
+
+ // test#5
+ rawOffset = 0;
+ saving = 3600000;
+ timeOfDay = 7200000;
+ year = 1982;
+ tz = new SimpleTimeZone(rawOffset, "stz",
+ Calendar.APRIL, 1, 0, 7200000,
+ Calendar.OCTOBER, 10, 0, 7200000,
+ saving);
+ offset = tz.getOffset(GregorianCalendar.AD,
+ year,
+ Calendar.OCTOBER,
+ 10,
+ 1,
+ timeOfDay);
+ cal.clear();
+ cal.set(year, Calendar.OCTOBER, 10);
+ cal.set(cal.MILLISECOND, timeOfDay);
+ localtime = cal.getTimeInMillis() + rawOffset; // local standard time
+
+ cal.clear();
+ cal.set(year, Calendar.OCTOBER, 10);
+ cal.set(cal.MILLISECOND, 7200000-saving);
+ endTime = cal.getTimeInMillis() + rawOffset;
+ expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset;
+ if (offset != expectedOffset) {
+ errln("test#5: wrong offset: got "+offset+", expected="+expectedOffset);
+ }
+ }
+
+ public static final long floorDivide(long n, long d) {
+ return ((n >= 0) ?
+ (n / d) : (((n + 1L) / d) - 1L));
+ }
+
+ public static final long mod(long x, long y) {
+ return (x - y * floorDivide(x, y));
+ }
+}
diff --git a/jdk/test/java/util/TimeZone/UTCAliasTest.java b/jdk/test/java/util/TimeZone/UTCAliasTest.java
new file mode 100644
index 00000000000..aa7079326c0
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/UTCAliasTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2005, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6282072
+ * @summary Make sure that "UTC" is an alias of "Etc/UTC" as defined in the tzdata backward.
+ * @modules java.base/sun.util.calendar
+ * @compile -XDignore.symbol.file UTCAliasTest.java
+ */
+
+import java.util.*;
+import sun.util.calendar.ZoneInfo;
+
+public class UTCAliasTest {
+ public static void main(String[] args) {
+ Map map = ZoneInfo.getAliasTable();
+ String alias = map.get("UTC");
+ if (!alias.equals("Etc/UTC")) {
+ throw new RuntimeException("got " + alias + ", expected Etc/UTC");
+ }
+ TimeZone GMT = TimeZone.getTimeZone("GMT");
+ TimeZone UTC = TimeZone.getTimeZone("UTC");
+ if (!GMT.hasSameRules(UTC)) {
+ throw new RuntimeException("GMT and UTC have different rules");
+ }
+ TimeZone EtcUTC = TimeZone.getTimeZone("Etc/UTC");
+ if (!UTC.hasSameRules(EtcUTC)) {
+ throw new RuntimeException("UTC and Etc/UTC have different rules");
+ }
+ }
+}
diff --git a/jdk/test/java/util/TimeZone/bug4096952.java b/jdk/test/java/util/TimeZone/bug4096952.java
new file mode 100644
index 00000000000..20ccc685ac6
--- /dev/null
+++ b/jdk/test/java/util/TimeZone/bug4096952.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1998, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4096952
+ * @summary simple serialization/deserialization test
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.TimeZone;
+
+public class bug4096952 {
+
+ public static void main(String[] args) {
+ int errors = 0;
+ String[] ZONES = { "GMT", "MET", "IST" };
+ for (String id : ZONES) {
+ TimeZone zone = TimeZone.getTimeZone(id);
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try (ObjectOutputStream ostream = new ObjectOutputStream(baos)) {
+ ostream.writeObject(zone);
+ }
+ try (ObjectInputStream istream
+ = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
+ if (!zone.equals(istream.readObject())) {
+ errors++;
+ System.out.println("Time zone " + id + " are not equal to serialized/deserialized one.");
+ } else {
+ System.out.println("Time zone " + id + " ok.");
+ }
+ }
+ } catch (IOException | ClassNotFoundException e) {
+ errors++;
+ System.out.println(e);
+ }
+ }
+ if (errors > 0) {
+ throw new RuntimeException("test failed");
+ }
+ }
+}
diff --git a/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java b/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java
index 82f9ead09f5..913aea78c46 100644
--- a/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java
+++ b/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java
@@ -25,13 +25,10 @@
* @test
* @bug 6503247 6574123
* @summary Test resilience to tryAcquire methods that throw
- * @library /lib/testlibrary/
* @author Martin Buchholz
*/
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-
-import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -39,7 +36,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
-import jdk.testlibrary.Utils;
/**
* This uses a variant of the standard Mutex demo, except with a
@@ -48,22 +44,10 @@ import jdk.testlibrary.Utils;
*/
@SuppressWarnings("serial")
public class FlakyMutex implements Lock {
- static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static class MyError extends Error {}
static class MyException extends Exception {}
static class MyRuntimeException extends RuntimeException {}
- static final Random rnd = new Random();
-
- static void maybeThrow() {
- switch (rnd.nextInt(10)) {
- case 0: throw new MyError();
- case 1: throw new MyRuntimeException();
- case 2: FlakyMutex.uncheckedThrow(new MyException());
- default: /* Do nothing */ break;
- }
- }
-
static void checkThrowable(Throwable t) {
check((t instanceof MyError) ||
(t instanceof MyException) ||
@@ -72,31 +56,35 @@ public class FlakyMutex implements Lock {
static void realMain(String[] args) throws Throwable {
final int nThreads = 3;
- final CyclicBarrier barrier = new CyclicBarrier(nThreads + 1);
- final FlakyMutex m = new FlakyMutex();
+ final int iterations = 10_000;
+ final CyclicBarrier startingGate = new CyclicBarrier(nThreads);
+ final FlakyMutex mutex = new FlakyMutex();
final ExecutorService es = Executors.newFixedThreadPool(nThreads);
- for (int i = 0; i < nThreads; i++) {
- es.submit(new Runnable() { public void run() {
- try {
- barrier.await();
- for (int i = 0; i < 10000; i++) {
- for (;;) {
- try { m.lock(); break; }
- catch (Throwable t) { checkThrowable(t); }
- }
-
- try { check(! m.tryLock()); }
+ final Runnable task = () -> {
+ try {
+ startingGate.await();
+ for (int i = 0; i < iterations; i++) {
+ for (;;) {
+ try { mutex.lock(); break; }
catch (Throwable t) { checkThrowable(t); }
-
- try { check(! m.tryLock(1, TimeUnit.MICROSECONDS)); }
- catch (Throwable t) { checkThrowable(t); }
-
- m.unlock();
}
- } catch (Throwable t) { unexpected(t); }}});}
- barrier.await();
+
+ try { check(! mutex.tryLock()); }
+ catch (Throwable t) { checkThrowable(t); }
+
+ try { check(! mutex.tryLock(1, TimeUnit.MICROSECONDS)); }
+ catch (Throwable t) { checkThrowable(t); }
+
+ mutex.unlock();
+ }
+ } catch (Throwable t) { unexpected(t); }
+ };
+
+ for (int i = 0; i < nThreads; i++)
+ es.submit(task);
es.shutdown();
- check(es.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+ // Let test harness handle timeout
+ check(es.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS));
}
private static class FlakySync extends AbstractQueuedLongSynchronizer {
@@ -116,8 +104,12 @@ public class FlakyMutex implements Lock {
do {} while (hasQueuedPredecessors() != hasQueuedThreads());
}
- maybeThrow();
- return compareAndSetState(0, 1);
+ switch (ThreadLocalRandom.current().nextInt(10)) {
+ case 0: throw new MyError();
+ case 1: throw new MyRuntimeException();
+ case 2: FlakyMutex.uncheckedThrow(new MyException());
+ default: return compareAndSetState(0, 1);
+ }
}
public boolean tryRelease(long releases) {
diff --git a/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java b/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java
index 5ad9d068a2a..2d82c455574 100644
--- a/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java
+++ b/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java
@@ -35,16 +35,10 @@
* @test
* @bug 8074773
* @summary Stress test looks for lost unparks
- * @library /lib/testlibrary/
- * @modules java.management
- * @run main/timeout=1200 ParkLoops
*/
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
-import java.lang.management.ManagementFactory;
-import java.lang.management.ThreadInfo;
import java.util.SplittableRandom;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
@@ -52,11 +46,8 @@ import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.locks.LockSupport;
-import jdk.testlibrary.Utils;
public final class ParkLoops {
- static final long TEST_TIMEOUT_SECONDS = Utils.adjustTimeout(1000);
- static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static final int THREADS = 4;
static final int ITERS = 30_000;
@@ -126,28 +117,13 @@ public final class ParkLoops {
final AtomicReferenceArray threads
= new AtomicReferenceArray<>(THREADS);
final CountDownLatch done = new CountDownLatch(THREADS);
- final Runnable parker = new Parker(threads, done, rnd.split());
- final Runnable unparker = new Unparker(threads, done, rnd.split());
for (int i = 0; i < THREADS; i++) {
- pool.submit(parker);
- pool.submit(unparker);
- }
- try {
- if (!done.await(TEST_TIMEOUT_SECONDS, SECONDS)) {
- dumpAllStacks();
- throw new AssertionError("lost unpark");
- }
- } finally {
- pool.shutdown();
- pool.awaitTermination(LONG_DELAY_MS, MILLISECONDS);
- }
- }
-
- static void dumpAllStacks() {
- ThreadInfo[] threadInfos =
- ManagementFactory.getThreadMXBean().dumpAllThreads(true, true);
- for (ThreadInfo threadInfo : threadInfos) {
- System.err.print(threadInfo);
+ pool.submit(new Parker(threads, done, rnd.split()));
+ pool.submit(new Unparker(threads, done, rnd.split()));
}
+ // Let test harness handle timeout
+ done.await();
+ pool.shutdown();
+ pool.awaitTermination(Long.MAX_VALUE, SECONDS);
}
}
diff --git a/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java b/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java
index 340e7f972a4..4149559adad 100644
--- a/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java
+++ b/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java
@@ -3322,7 +3322,7 @@ public class CompletableFutureTest extends JSR166TestCase {
() -> f.obtrudeException(null),
() -> CompletableFuture.delayedExecutor(1L, SECONDS, null),
- () -> CompletableFuture.delayedExecutor(1L, null, new ThreadExecutor()),
+ () -> CompletableFuture.delayedExecutor(1L, null, exec),
() -> CompletableFuture.delayedExecutor(1L, null),
() -> f.orTimeout(1L, null),
@@ -3552,7 +3552,7 @@ public class CompletableFutureTest extends JSR166TestCase {
long timeoutMillis = timeoutMillis();
CompletableFuture f = new CompletableFuture<>();
long startTime = System.nanoTime();
- f.orTimeout(timeoutMillis, MILLISECONDS);
+ assertSame(f, f.orTimeout(timeoutMillis, MILLISECONDS));
checkCompletedWithTimeoutException(f);
assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
}
@@ -3567,8 +3567,8 @@ public class CompletableFutureTest extends JSR166TestCase {
CompletableFuture g = new CompletableFuture<>();
long startTime = System.nanoTime();
f.complete(v1);
- f.orTimeout(LONG_DELAY_MS, MILLISECONDS);
- g.orTimeout(LONG_DELAY_MS, MILLISECONDS);
+ assertSame(f, f.orTimeout(LONG_DELAY_MS, MILLISECONDS));
+ assertSame(g, g.orTimeout(LONG_DELAY_MS, MILLISECONDS));
g.complete(v1);
checkCompletedNormally(f, v1);
checkCompletedNormally(g, v1);
@@ -3583,11 +3583,14 @@ public class CompletableFutureTest extends JSR166TestCase {
() -> testCompleteOnTimeout_timesOut(null));
}
+ /**
+ * completeOnTimeout completes with given value if not complete
+ */
public void testCompleteOnTimeout_timesOut(Integer v) {
long timeoutMillis = timeoutMillis();
CompletableFuture f = new CompletableFuture<>();
long startTime = System.nanoTime();
- f.completeOnTimeout(v, timeoutMillis, MILLISECONDS);
+ assertSame(f, f.completeOnTimeout(v, timeoutMillis, MILLISECONDS));
assertSame(v, f.join());
assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
f.complete(99); // should have no effect
@@ -3604,8 +3607,8 @@ public class CompletableFutureTest extends JSR166TestCase {
CompletableFuture g = new CompletableFuture<>();
long startTime = System.nanoTime();
f.complete(v1);
- f.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS);
- g.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS);
+ assertSame(f, f.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS));
+ assertSame(g, g.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS));
g.complete(v1);
checkCompletedNormally(f, v1);
checkCompletedNormally(g, v1);
diff --git a/jdk/test/java/util/concurrent/tck/ExecutorCompletionService9Test.java b/jdk/test/java/util/concurrent/tck/ExecutorCompletionService9Test.java
new file mode 100644
index 00000000000..8169d5fa5f6
--- /dev/null
+++ b/jdk/test/java/util/concurrent/tck/ExecutorCompletionService9Test.java
@@ -0,0 +1,137 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea and Martin Buchholz with assistance from
+ * members of JCP JSR-166 Expert Group and released to the public
+ * domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ExecutorCompletionService9Test extends JSR166TestCase {
+ public static void main(String[] args) {
+ main(suite(), args);
+ }
+ public static Test suite() {
+ return new TestSuite(ExecutorCompletionService9Test.class);
+ }
+
+ void solveAll(Executor e,
+ Collection> solvers)
+ throws InterruptedException, ExecutionException {
+ CompletionService cs
+ = new ExecutorCompletionService<>(e);
+ solvers.forEach(cs::submit);
+ for (int i = solvers.size(); i > 0; i--) {
+ Integer r = cs.take().get();
+ if (r != null)
+ use(r);
+ }
+ }
+
+ void solveAny(Executor e,
+ Collection> solvers)
+ throws InterruptedException {
+ CompletionService cs
+ = new ExecutorCompletionService<>(e);
+ int n = solvers.size();
+ List> futures = new ArrayList<>(n);
+ Integer result = null;
+ try {
+ solvers.forEach((solver) -> futures.add(cs.submit(solver)));
+ for (int i = n; i > 0; i--) {
+ try {
+ Integer r = cs.take().get();
+ if (r != null) {
+ result = r;
+ break;
+ }
+ } catch (ExecutionException ignore) {}
+ }
+ } finally {
+ futures.forEach((future) -> future.cancel(true));
+ }
+
+ if (result != null)
+ use(result);
+ }
+
+ HashSet results;
+
+ void use(Integer x) {
+ if (results == null) results = new HashSet();
+ results.add(x);
+ }
+
+ /**
+ * The first "solvers" sample code in the class javadoc works.
+ */
+ public void testSolveAll()
+ throws InterruptedException, ExecutionException {
+ Set> solvers = Set.of(
+ () -> null,
+ () -> 1,
+ () -> 2,
+ () -> 3,
+ () -> null);
+ solveAll(cachedThreadPool, solvers);
+ assertEquals(Set.of(1, 2, 3), results);
+ }
+
+ /**
+ * The second "solvers" sample code in the class javadoc works.
+ */
+ public void testSolveAny()
+ throws InterruptedException {
+ Set> solvers = Set.of(
+ () -> { throw new ArithmeticException(); },
+ () -> null,
+ () -> 1,
+ () -> 2);
+ solveAny(cachedThreadPool, solvers);
+ assertEquals(1, results.size());
+ Integer elt = results.iterator().next();
+ assertTrue(elt.equals(1) || elt.equals(2));
+ }
+
+}
diff --git a/jdk/test/java/util/concurrent/tck/ExecutorCompletionServiceTest.java b/jdk/test/java/util/concurrent/tck/ExecutorCompletionServiceTest.java
index 29db17a7a0d..6e4d00f3d0f 100644
--- a/jdk/test/java/util/concurrent/tck/ExecutorCompletionServiceTest.java
+++ b/jdk/test/java/util/concurrent/tck/ExecutorCompletionServiceTest.java
@@ -37,8 +37,11 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorCompletionService;
-import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
@@ -59,7 +62,7 @@ public class ExecutorCompletionServiceTest extends JSR166TestCase {
}
/**
- * Creating a new ECS with null Executor throw NPE
+ * new ExecutorCompletionService(null) throws NullPointerException
*/
public void testConstructorNPE() {
try {
@@ -69,111 +72,147 @@ public class ExecutorCompletionServiceTest extends JSR166TestCase {
}
/**
- * Creating a new ECS with null queue throw NPE
+ * new ExecutorCompletionService(e, null) throws NullPointerException
*/
public void testConstructorNPE2() {
try {
- ExecutorService e = Executors.newCachedThreadPool();
- new ExecutorCompletionService(e, null);
+ new ExecutorCompletionService(cachedThreadPool, null);
shouldThrow();
} catch (NullPointerException success) {}
}
/**
- * Submitting a null callable throws NPE
+ * ecs.submit(null) throws NullPointerException
*/
- public void testSubmitNPE() {
- final ExecutorService e = Executors.newCachedThreadPool();
- final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
- try (PoolCleaner cleaner = cleaner(e)) {
- Callable c = null;
- try {
- ecs.submit(c);
- shouldThrow();
- } catch (NullPointerException success) {}
- }
+ public void testSubmitNullCallable() {
+ CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+ try {
+ cs.submit((Callable) null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
}
/**
- * Submitting a null runnable throws NPE
+ * ecs.submit(null, val) throws NullPointerException
*/
- public void testSubmitNPE2() {
- final ExecutorService e = Executors.newCachedThreadPool();
- final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
- try (PoolCleaner cleaner = cleaner(e)) {
- Runnable r = null;
- try {
- ecs.submit(r, Boolean.TRUE);
- shouldThrow();
- } catch (NullPointerException success) {}
- }
+ public void testSubmitNullRunnable() {
+ CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+ try {
+ cs.submit((Runnable) null, Boolean.TRUE);
+ shouldThrow();
+ } catch (NullPointerException success) {}
}
/**
* A taken submitted task is completed
*/
- public void testTake() throws InterruptedException {
- final ExecutorService e = Executors.newCachedThreadPool();
- final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
- try (PoolCleaner cleaner = cleaner(e)) {
- Callable c = new StringTask();
- ecs.submit(c);
- Future f = ecs.take();
- assertTrue(f.isDone());
- }
+ public void testTake()
+ throws InterruptedException, ExecutionException {
+ CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+ cs.submit(new StringTask());
+ Future f = cs.take();
+ assertTrue(f.isDone());
+ assertSame(TEST_STRING, f.get());
}
/**
* Take returns the same future object returned by submit
*/
public void testTake2() throws InterruptedException {
- final ExecutorService e = Executors.newCachedThreadPool();
- final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
- try (PoolCleaner cleaner = cleaner(e)) {
- Callable c = new StringTask();
- Future f1 = ecs.submit(c);
- Future f2 = ecs.take();
- assertSame(f1, f2);
- }
+ CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+ Future f1 = cs.submit(new StringTask());
+ Future f2 = cs.take();
+ assertSame(f1, f2);
}
/**
- * If poll returns non-null, the returned task is completed
+ * poll returns non-null when the returned task is completed
*/
- public void testPoll1() throws Exception {
- final ExecutorService e = Executors.newCachedThreadPool();
- final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
- try (PoolCleaner cleaner = cleaner(e)) {
- assertNull(ecs.poll());
- Callable c = new StringTask();
- ecs.submit(c);
+ public void testPoll1()
+ throws InterruptedException, ExecutionException {
+ CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+ assertNull(cs.poll());
+ cs.submit(new StringTask());
- long startTime = System.nanoTime();
- Future f;
- while ((f = ecs.poll()) == null) {
- if (millisElapsedSince(startTime) > LONG_DELAY_MS)
- fail("timed out");
- Thread.yield();
+ long startTime = System.nanoTime();
+ Future f;
+ while ((f = cs.poll()) == null) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ fail("timed out");
+ Thread.yield();
+ }
+ assertTrue(f.isDone());
+ assertSame(TEST_STRING, f.get());
+ }
+
+ /**
+ * timed poll returns non-null when the returned task is completed
+ */
+ public void testPoll2()
+ throws InterruptedException, ExecutionException {
+ CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+ assertNull(cs.poll());
+ cs.submit(new StringTask());
+
+ long startTime = System.nanoTime();
+ Future f;
+ while ((f = cs.poll(SHORT_DELAY_MS, MILLISECONDS)) == null) {
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ fail("timed out");
+ Thread.yield();
+ }
+ assertTrue(f.isDone());
+ assertSame(TEST_STRING, f.get());
+ }
+
+ /**
+ * poll returns null before the returned task is completed
+ */
+ public void testPollReturnsNull()
+ throws InterruptedException, ExecutionException {
+ CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+ final CountDownLatch proceed = new CountDownLatch(1);
+ cs.submit(new Callable() { public String call() throws Exception {
+ proceed.await();
+ return TEST_STRING;
+ }});
+ assertNull(cs.poll());
+ assertNull(cs.poll(0L, MILLISECONDS));
+ assertNull(cs.poll(Long.MIN_VALUE, MILLISECONDS));
+ long startTime = System.nanoTime();
+ assertNull(cs.poll(timeoutMillis(), MILLISECONDS));
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+ proceed.countDown();
+ assertSame(TEST_STRING, cs.take().get());
+ }
+
+ /**
+ * successful and failed tasks are both returned
+ */
+ public void testTaskAssortment()
+ throws InterruptedException, ExecutionException {
+ CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+ ArithmeticException ex = new ArithmeticException();
+ for (int i = 0; i < 2; i++) {
+ cs.submit(new StringTask());
+ cs.submit(callableThrowing(ex));
+ cs.submit(runnableThrowing(ex), null);
+ }
+ int normalCompletions = 0;
+ int exceptionalCompletions = 0;
+ for (int i = 0; i < 3 * 2; i++) {
+ try {
+ if (cs.take().get() == TEST_STRING)
+ normalCompletions++;
+ }
+ catch (ExecutionException expected) {
+ assertTrue(expected.getCause() instanceof ArithmeticException);
+ exceptionalCompletions++;
}
- assertTrue(f.isDone());
- assertSame(TEST_STRING, f.get());
- }
- }
-
- /**
- * If timed poll returns non-null, the returned task is completed
- */
- public void testPoll2() throws InterruptedException {
- final ExecutorService e = Executors.newCachedThreadPool();
- final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
- try (PoolCleaner cleaner = cleaner(e)) {
- assertNull(ecs.poll());
- Callable c = new StringTask();
- ecs.submit(c);
- Future f = ecs.poll(SHORT_DELAY_MS, MILLISECONDS);
- if (f != null)
- assertTrue(f.isDone());
}
+ assertEquals(2 * 1, normalCompletions);
+ assertEquals(2 * 2, exceptionalCompletions);
+ assertNull(cs.poll());
}
/**
@@ -184,7 +223,7 @@ public class ExecutorCompletionServiceTest extends JSR166TestCase {
final AtomicBoolean done = new AtomicBoolean(false);
class MyCallableFuture extends FutureTask {
MyCallableFuture(Callable c) { super(c); }
- protected void done() { done.set(true); }
+ @Override protected void done() { done.set(true); }
}
final ExecutorService e =
new ThreadPoolExecutor(1, 1,
@@ -193,15 +232,14 @@ public class ExecutorCompletionServiceTest extends JSR166TestCase {
protected RunnableFuture newTaskFor(Callable c) {
return new MyCallableFuture(c);
}};
- ExecutorCompletionService ecs =
- new ExecutorCompletionService(e);
+ CompletionService cs = new ExecutorCompletionService<>(e);
try (PoolCleaner cleaner = cleaner(e)) {
- assertNull(ecs.poll());
+ assertNull(cs.poll());
Callable c = new StringTask();
- Future f1 = ecs.submit(c);
+ Future f1 = cs.submit(c);
assertTrue("submit must return MyCallableFuture",
f1 instanceof MyCallableFuture);
- Future f2 = ecs.take();
+ Future f2 = cs.take();
assertSame("submit and take must return same objects", f1, f2);
assertTrue("completed task must have set done", done.get());
}
@@ -215,7 +253,7 @@ public class ExecutorCompletionServiceTest extends JSR166TestCase {
final AtomicBoolean done = new AtomicBoolean(false);
class MyRunnableFuture extends FutureTask {
MyRunnableFuture(Runnable t, V r) { super(t, r); }
- protected void done() { done.set(true); }
+ @Override protected void done() { done.set(true); }
}
final ExecutorService e =
new ThreadPoolExecutor(1, 1,
@@ -224,15 +262,14 @@ public class ExecutorCompletionServiceTest extends JSR166TestCase {
protected RunnableFuture newTaskFor(Runnable t, T r) {
return new MyRunnableFuture(t, r);
}};
- final ExecutorCompletionService ecs =
- new ExecutorCompletionService(e);
+ CompletionService cs = new ExecutorCompletionService<>(e);
try (PoolCleaner cleaner = cleaner(e)) {
- assertNull(ecs.poll());
+ assertNull(cs.poll());
Runnable r = new NoOpRunnable();
- Future f1 = ecs.submit(r, null);
+ Future f1 = cs.submit(r, null);
assertTrue("submit must return MyRunnableFuture",
f1 instanceof MyRunnableFuture);
- Future f2 = ecs.take();
+ Future f2 = cs.take();
assertSame("submit and take must return same objects", f1, f2);
assertTrue("completed task must have set done", done.get());
}
diff --git a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java
index b189ce6b128..14907badc6f 100644
--- a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java
+++ b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java
@@ -39,6 +39,7 @@
* @modules java.management
* @build *
* @run junit/othervm/timeout=1000 -Djsr166.testImplementationDetails=true JSR166TestCase
+ * @run junit/othervm/timeout=1000 -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 -Djsr166.testImplementationDetails=true JSR166TestCase
*/
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -85,6 +86,7 @@ import java.util.concurrent.RecursiveAction;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.Semaphore;
+import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeoutException;
@@ -546,7 +548,7 @@ public class JSR166TestCase extends TestCase {
// Java9+ test classes
if (atLeastJava9()) {
String[] java9TestClassNames = {
- // Currently empty, but expecting varhandle tests
+ "ExecutorCompletionService9Test",
};
addNamedTestClasses(suite, java9TestClassNames);
}
@@ -1860,4 +1862,19 @@ public class JSR166TestCase extends TestCase {
} catch (NoSuchElementException success) {}
assertFalse(it.hasNext());
}
+
+ public Callable callableThrowing(final Exception ex) {
+ return new Callable() { public T call() throws Exception { throw ex; }};
+ }
+
+ public Runnable runnableThrowing(final RuntimeException ex) {
+ return new Runnable() { public void run() { throw ex; }};
+ }
+
+ /** A reusable thread pool to be shared by tests. */
+ static final ExecutorService cachedThreadPool =
+ new ThreadPoolExecutor(0, Integer.MAX_VALUE,
+ 1000L, MILLISECONDS,
+ new SynchronousQueue());
+
}
diff --git a/jdk/test/java/util/logging/XMLFormatterDate.java b/jdk/test/java/util/logging/XMLFormatterDate.java
index 28eb1246694..ee0eeb98b57 100644
--- a/jdk/test/java/util/logging/XMLFormatterDate.java
+++ b/jdk/test/java/util/logging/XMLFormatterDate.java
@@ -21,10 +21,18 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-import java.util.Calendar;
-import java.util.GregorianCalendar;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.time.Month;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
import java.util.Locale;
+import java.util.Properties;
+import java.util.function.Supplier;
import java.util.logging.Level;
+import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.XMLFormatter;
@@ -33,9 +41,25 @@ import java.util.logging.XMLFormatter;
* @bug 8028185
* @summary XMLFormatter.format emits incorrect year (year + 1900)
* @author dfuchs
+ * @run main/othervm XMLFormatterDate
*/
public class XMLFormatterDate {
+ static final class TimeStamp {
+
+ final ZonedDateTime zdt;
+ TimeStamp(ZoneId zoneId) {
+ zdt = ZonedDateTime.now(zoneId);
+ }
+ int getYear() {
+ return zdt.getYear();
+ }
+ boolean isJanuaryFirst() {
+ return zdt.getMonth() == Month.JANUARY && zdt.getDayOfMonth() == 1;
+ }
+ }
+
+
/**
* Before the fix, JDK8 prints: {@code
*
@@ -64,39 +88,62 @@ public class XMLFormatterDate {
try {
Locale.setDefault(Locale.ENGLISH);
- final GregorianCalendar cal1 = new GregorianCalendar();
- final int year1 = cal1.get(Calendar.YEAR);
+ // Test with default format: by default date is in UTC.
+ System.out.println("Testing with UTC");
+ test(() -> new TimeStamp(ZoneOffset.UTC));
- LogRecord record = new LogRecord(Level.INFO, "test");
- XMLFormatter formatter = new XMLFormatter();
- final String formatted = formatter.format(record);
- System.out.println(formatted);
-
- final GregorianCalendar cal2 = new GregorianCalendar();
- final int year2 = cal2.get(Calendar.YEAR);
- if (year2 < 1900) {
- throw new Error("Invalid system year: " + year2);
+ // Change LogManager configuration so that new
+ // XMLFormatter prints date in the pre Java 9 local zone format
+ try {
+ Properties props = new Properties();
+ props.setProperty("java.util.logging.XMLFormatter.useInstant", "false");
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ props.store(baos, "");
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ LogManager.getLogManager().updateConfiguration(bais, (k) -> (o,n) -> n!=null?n:o);
+ } catch (IOException io) {
+ throw new RuntimeException(io);
}
- StringBuilder buf2 = new StringBuilder()
- .append("").append(year2).append("-");
- if (!formatted.contains(buf2.toString())) {
- StringBuilder buf1 = new StringBuilder()
- .append("").append(year1).append("-");
- if (formatted.contains(buf1)
- && year2 == year1 + 1
- && cal2.get(Calendar.MONTH) == Calendar.JANUARY
- && cal2.get(Calendar.DAY_OF_MONTH) == 1) {
- // Oh! The year just switched in the midst of the test...
- System.out.println("Happy new year!");
- } else {
- throw new Error("Expected year " + year2
- + " not found in log:\n" + formatted);
- }
- }
+ // re test with the old format: date will be in the local time zone.
+ System.out.println("Testing with old format");
+ test(() -> new TimeStamp(ZoneId.systemDefault()));
+
} finally {
Locale.setDefault(locale);
}
}
+ static void test(Supplier timeStampSupplier) {
+
+ TimeStamp t1 = timeStampSupplier.get();
+ int year1 = t1.getYear();
+
+ LogRecord record = new LogRecord(Level.INFO, "test");
+ XMLFormatter formatter = new XMLFormatter();
+ final String formatted = formatter.format(record);
+ System.out.println(formatted);
+
+ final TimeStamp t2 = timeStampSupplier.get();
+ final int year2 = t2.getYear();
+ if (year2 < 1900) {
+ throw new Error("Invalid system year: " + year2);
+ }
+
+ final StringBuilder buf2 = new StringBuilder()
+ .append("").append(year2).append("-");
+ if (!formatted.contains(buf2.toString())) {
+ StringBuilder buf1 = new StringBuilder()
+ .append("").append(year1).append("-");
+ if (formatted.contains(buf1) && year2 == year1 + 1
+ && t2.isJanuaryFirst()) {
+ // Oh! The year just switched in the midst of the test...
+ System.out.println("Happy new year!");
+ } else {
+ throw new Error("Expected year " + year2
+ + " not found in log:\n" + formatted);
+ }
+ }
+ }
+
}
diff --git a/jdk/test/jdk/internal/jrtfs/Basic.java b/jdk/test/jdk/internal/jrtfs/Basic.java
index 0af30c5e2f7..9c29d8c1428 100644
--- a/jdk/test/jdk/internal/jrtfs/Basic.java
+++ b/jdk/test/jdk/internal/jrtfs/Basic.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -65,15 +65,31 @@ public class Basic {
private FileSystem theFileSystem;
private FileSystem fs;
+ private boolean isExplodedBuild = false;
@BeforeClass
public void setup() {
+ theFileSystem = FileSystems.getFileSystem(URI.create("jrt:/"));
+ Path javaHomeDir = Paths.get(System.getProperty("java.home"));
+ Path jrtJarPath = javaHomeDir.resolve("jrt-fs.jar");
+ Path modulesPath = javaHomeDir.resolve("lib/modules");
+ isExplodedBuild = !Files.exists(jrtJarPath)
+ && !Files.exists(modulesPath);
+ if (Files.notExists(jrtJarPath)
+ && Files.notExists(modulesPath)) {
+ System.out.printf("Following files not exist: %s, %s",
+ jrtJarPath.toString(), modulesPath.toString());
+ System.out.println();
+ System.out.println("It is most probably an exploded build."
+ + " Skip non-default FileSystem testing.");
+ return;
+ }
+
+ Map env = new HashMap<>();
+ // set java.home property to be underlying java.home
+ // so that jrt-fs.jar loading is exercised.
+ env.put("java.home", System.getProperty("java.home"));
try {
- theFileSystem = FileSystems.getFileSystem(URI.create("jrt:/"));
- Map env = new HashMap<>();
- // set java.home property to be underlying java.home
- // so that jrt-fs.jar loading is exercised.
- env.put("java.home", System.getProperty("java.home"));
fs = FileSystems.newFileSystem(URI.create("jrt:/"), env);
} catch (IOException ioExp) {
throw new RuntimeException(ioExp);
@@ -131,6 +147,12 @@ public class Basic {
@Test
public void testNewFileSystemWithJavaHome() throws Exception {
+ if (isExplodedBuild) {
+ System.out.println("Skip testNewFileSystemWithJavaHome"
+ + " since this is an exploded build");
+ return;
+ }
+
Map env = new HashMap<>();
// set java.home property to be underlying java.home
// so that jrt-fs.jar loading is exercised.
@@ -154,6 +176,11 @@ public class Basic {
@Test(dataProvider = "knownClassFiles")
public void testKnownClassFiles(String path, boolean theDefault) throws Exception {
+ if (isExplodedBuild && !theDefault) {
+ System.out.println("Skip testKnownClassFiles with non-default FileSystem");
+ return;
+ }
+
FileSystem fs = selectFileSystem(theDefault);
Path classFile = fs.getPath(path);
@@ -201,6 +228,11 @@ public class Basic {
@Test(dataProvider = "knownDirectories")
public void testKnownDirectories(String path, boolean theDefault) throws Exception {
+ if (isExplodedBuild && !theDefault) {
+ System.out.println("Skip testKnownDirectories with non-default FileSystem");
+ return;
+ }
+
FileSystem fs = selectFileSystem(theDefault);
Path dir = fs.getPath(path);
@@ -684,3 +716,4 @@ public class Basic {
assertEquals(dirPrefixOkayCount, childCount);
}
}
+
diff --git a/jdk/test/jdk/net/SocketFlow/SocketFlowBasic.java b/jdk/test/jdk/net/SocketFlow/SocketFlowBasic.java
index ca02ad931d6..f882e88e30a 100644
--- a/jdk/test/jdk/net/SocketFlow/SocketFlowBasic.java
+++ b/jdk/test/jdk/net/SocketFlow/SocketFlowBasic.java
@@ -25,6 +25,7 @@
* @test
* @bug 8765432
* @summary Basic test for SocketFlow API
+ * @modules jdk.net
* @run testng SocketFlowBasic
*/
diff --git a/jdk/test/jdk/net/Sockets/SupportedOptions.java b/jdk/test/jdk/net/Sockets/SupportedOptions.java
index 0ef21204629..caf4d025d67 100644
--- a/jdk/test/jdk/net/Sockets/SupportedOptions.java
+++ b/jdk/test/jdk/net/Sockets/SupportedOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 8062744
+ * @modules jdk.net
* @run main SupportedOptions
*/
diff --git a/jdk/test/jdk/net/Sockets/Test.java b/jdk/test/jdk/net/Sockets/Test.java
index 8bb03c54919..bd76fff4e67 100644
--- a/jdk/test/jdk/net/Sockets/Test.java
+++ b/jdk/test/jdk/net/Sockets/Test.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -25,24 +25,35 @@
* @test
* @bug 8032808 8044773
* @modules jdk.net
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
* @run main/othervm -Xcheck:jni Test success
* @run main/othervm/policy=policy.fail -Xcheck:jni Test fail
* @run main/othervm/policy=policy.success -Xcheck:jni Test success
*/
-import java.net.*;
+import jdk.net.ExtendedSocketOptions;
+import jdk.net.SocketFlow;
+import jdk.net.Sockets;
+import jdk.testlibrary.OSInfo;
+
import java.io.IOException;
-import java.nio.channels.*;
-import java.util.concurrent.*;
-import java.util.Set;
-import jdk.net.*;
+import java.net.*;
+import java.nio.channels.AsynchronousSocketChannel;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.Future;
+
import static java.lang.System.out;
+import static jdk.net.ExtendedSocketOptions.SO_FLOW_SLA;
public class Test {
interface Runner { void run() throws Exception; }
static boolean expectSuccess;
+ private static final boolean expectSupport = checkExpectedOptionSupport();
+ private static final double solarisVersionToCheck = 11.2;
public static void main(String[] args) throws Exception {
@@ -54,9 +65,8 @@ public class Test {
expectSuccess = args[0].equals("success");
// Main thing is to check for JNI problems
- // Doesn't matter if current system does not support the option
- // and currently setting the option with the loopback interface
- // doesn't work either
+ // Doesn't matter if currently setting the option with the loopback
+ // interface doesn't work
boolean sm = System.getSecurityManager() != null;
out.println("Security Manager enabled: " + sm);
@@ -75,56 +85,70 @@ public class Test {
final int udp_port = dg.getLocalPort();
- // If option not available, end test
- Set> options = dg.supportedOptions();
- if (!options.contains(ExtendedSocketOptions.SO_FLOW_SLA)) {
- System.out.println("SO_FLOW_SLA not supported");
- return;
- }
-
final Socket s = new Socket("127.0.0.1", tcp_port);
final SocketChannel sc = SocketChannel.open();
sc.connect(new InetSocketAddress("127.0.0.1", tcp_port));
doTest("Sockets.setOption Socket", () -> {
out.println(flowIn);
- Sockets.setOption(s, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ if (s.supportedOptions().contains(SO_FLOW_SLA) != expectSupport) {
+ throw new RuntimeException("Unexpected supportedOptions()");
+ }
+ Sockets.setOption(s, SO_FLOW_SLA, flowIn);
out.println(flowIn);
});
- doTest("Sockets.getOption Socket",() -> {
- Sockets.getOption(s, ExtendedSocketOptions.SO_FLOW_SLA);
+
+ doTest("Sockets.getOption Socket", () -> {
+ Sockets.getOption(s, SO_FLOW_SLA);
out.println(flowIn);
});
- doTest("Sockets.setOption SocketChannel",() ->
- sc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn)
+
+ doTest("Sockets.setOption SocketChannel", () -> {
+ if (sc.supportedOptions().contains(SO_FLOW_SLA) != expectSupport) {
+ throw new RuntimeException("Unexpected supportedOptions()");
+ }
+ sc.setOption(SO_FLOW_SLA, flowIn);
+ });
+ doTest("Sockets.getOption SocketChannel", () ->
+ sc.getOption(SO_FLOW_SLA)
);
- doTest("Sockets.getOption SocketChannel",() ->
- sc.getOption(ExtendedSocketOptions.SO_FLOW_SLA)
- );
- doTest("Sockets.setOption DatagramSocket",() -> {
+ doTest("Sockets.setOption DatagramSocket", () -> {
try (DatagramSocket dg1 = new DatagramSocket(0)) {
+ if (dg1.supportedOptions().contains(SO_FLOW_SLA) != expectSupport) {
+ throw new RuntimeException("Unexpected supportedOptions()");
+ }
+
dg1.connect(loop, udp_port);
- Sockets.setOption(dg1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ Sockets.setOption(dg1, SO_FLOW_SLA, flowIn);
}
});
doTest("Sockets.setOption DatagramSocket 2", () -> {
try (DatagramChannel dg2 = DatagramChannel.open()) {
+ if (dg2.supportedOptions().contains(SO_FLOW_SLA) != expectSupport) {
+ throw new RuntimeException("Unexpected supportedOptions()");
+ }
dg2.bind(new InetSocketAddress(loop, 0));
dg2.connect(new InetSocketAddress(loop, udp_port));
- dg2.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ dg2.setOption(SO_FLOW_SLA, flowIn);
}
});
doTest("Sockets.setOption MulticastSocket", () -> {
try (MulticastSocket mc1 = new MulticastSocket(0)) {
+ if (mc1.supportedOptions().contains(SO_FLOW_SLA) != expectSupport) {
+ throw new RuntimeException("Unexpected supportedOptions()");
+ }
mc1.connect(loop, udp_port);
- Sockets.setOption(mc1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ Sockets.setOption(mc1, SO_FLOW_SLA, flowIn);
}
});
doTest("Sockets.setOption AsynchronousSocketChannel", () -> {
try (AsynchronousSocketChannel asc = AsynchronousSocketChannel.open()) {
+ if (asc.supportedOptions().contains(SO_FLOW_SLA) != expectSupport) {
+ throw new RuntimeException("Unexpected supportedOptions()");
+ }
Future f = asc.connect(loopad);
f.get();
- asc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ asc.setOption(SO_FLOW_SLA, flowIn);
}
});
}
@@ -144,14 +168,43 @@ public class Test {
throw new RuntimeException("Unexpected SecurityException", e);
} else {
out.println("Caught expected: " + e);
+ return;
}
} catch (UnsupportedOperationException e) {
- System.out.println(e);
+ if (expectSupport) {
+ throw new RuntimeException("Test failed: " +
+ "unexpected UnsupportedOperationException");
+ }
+ out.println("UnsupportedOperationException as expected");
+ return;
} catch (IOException e) {
// Probably a permission error, but we're not
// going to check unless a specific permission exception
// is defined.
System.out.println(e);
}
+ if (!expectSupport) {
+ throw new RuntimeException("Test failed: " +
+ "UnsupportedOperationException was not thrown");
+ }
}
+
+ private static boolean checkExpectedOptionSupport() {
+ if (OSInfo.getOSType().equals(OSInfo.OSType.SOLARIS)) {
+ double solarisVersion = OSInfo.getSolarisVersion();
+ if (solarisVersion >= solarisVersionToCheck) {
+ System.out.println("This Solaris version (" + solarisVersion
+ + ") should support SO_FLOW_SLA option");
+ return true;
+ } else {
+ System.out.println("This Solaris version (" + solarisVersion
+ + ") should not support SO_FLOW_SLA option");
+ }
+ } else {
+ System.out.println("Not Solaris, SO_FLOW_SLA should not be " +
+ "supported");
+ }
+ return false;
+ }
+
}
diff --git a/jdk/test/jdk/net/Sockets/policy.fail b/jdk/test/jdk/net/Sockets/policy.fail
index 29d1215e708..1c9b57d90d7 100644
--- a/jdk/test/jdk/net/Sockets/policy.fail
+++ b/jdk/test/jdk/net/Sockets/policy.fail
@@ -1,4 +1,8 @@
grant {
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.io.FilePermission "<>", "execute";
+ permission java.util.PropertyPermission "line.separator", "read";
+ permission java.io.FilePermission "/etc/release", "read";
permission java.net.SocketPermission "127.0.0.1", "connect,accept" ;
permission java.net.SocketPermission "localhost", "listen" ;
};
diff --git a/jdk/test/jdk/net/Sockets/policy.success b/jdk/test/jdk/net/Sockets/policy.success
index 6f99151a38f..653b755b338 100644
--- a/jdk/test/jdk/net/Sockets/policy.success
+++ b/jdk/test/jdk/net/Sockets/policy.success
@@ -1,4 +1,8 @@
grant {
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.io.FilePermission "<>", "execute";
+ permission java.util.PropertyPermission "line.separator", "read";
+ permission java.io.FilePermission "/etc/release", "read";
permission java.net.SocketPermission "127.0.0.1", "connect,accept" ;
permission java.net.SocketPermission "localhost", "listen" ;
permission jdk.net.NetworkPermission "setOption.SO_FLOW_SLA";
diff --git a/jdk/test/jdk/nio/zipfs/Basic.java b/jdk/test/jdk/nio/zipfs/Basic.java
index f29e4bd123e..60ac2e7e0ad 100644
--- a/jdk/test/jdk/nio/zipfs/Basic.java
+++ b/jdk/test/jdk/nio/zipfs/Basic.java
@@ -31,6 +31,7 @@ import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.nio.file.ProviderMismatchException;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
@@ -39,14 +40,15 @@ import java.net.URI;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
-
+import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
/**
* @test
- * @bug 8038500 8040059 8150366 8150496
+ * @bug 8038500 8040059 8150366 8150496 8147539
* @summary Basic test for zip provider
*
* @run main Basic
* @run main/othervm/java.security.policy=test.policy Basic
+ * @modules jdk.zipfs
*/
public class Basic {
@@ -89,7 +91,7 @@ public class Basic {
found = false;
try (DirectoryStream stream = Files.newDirectoryStream(fs.getPath("/"))) {
for (Path entry: stream) {
- found = entry.toString().equals("/META-INF/");
+ found = entry.toString().equals("/META-INF");
if (found) break;
}
}
@@ -117,6 +119,13 @@ public class Basic {
if (!store.supportsFileAttributeView("basic"))
throw new RuntimeException("BasicFileAttributeView should be supported");
+ // Test: watch register should throw PME
+ try {
+ fs.getPath("/")
+ .register(FileSystems.getDefault().newWatchService(), ENTRY_CREATE);
+ throw new RuntimeException("watch service is not supported");
+ } catch (ProviderMismatchException x) { }
+
// Test: ClosedFileSystemException
fs.close();
if (fs.isOpen())
diff --git a/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java b/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java
index 7f5f37b44fa..6e483c6e21a 100644
--- a/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java
+++ b/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java
@@ -28,6 +28,9 @@
* @library /lib/testlibrary/java/util/jar
* @build Compiler JarBuilder CreateMultiReleaseTestJars
* @run testng MultiReleaseJarTest
+ * @modules java.compiler
+ * jdk.jartool
+ * jdk.zipfs
*/
import java.io.IOException;
diff --git a/jdk/test/jdk/nio/zipfs/PathOps.java b/jdk/test/jdk/nio/zipfs/PathOps.java
index 8f428515cbc..1bd72f7bf9c 100644
--- a/jdk/test/jdk/nio/zipfs/PathOps.java
+++ b/jdk/test/jdk/nio/zipfs/PathOps.java
@@ -31,11 +31,12 @@ import java.nio.file.Path;
/**
*
* @test
- * @bug 8038500 8040059
+ * @bug 8038500 8040059 8139956 8146754
* @summary Tests path operations for zip provider.
*
* @run main PathOps
* @run main/othervm/java.security.policy=test.policy PathOps
+ * @modules jdk.zipfs
*/
public class PathOps {
@@ -424,6 +425,11 @@ public class PathOps {
test("/")
.relativize("/a", "a")
.relativize("/a/c", "a/c");
+ // 8146754
+ test("/tmp/path")
+ .relativize("/tmp/path/a.txt", "a.txt");
+ test("/tmp/path/")
+ .relativize("/tmp/path/a.txt", "a.txt");
// normalize
test("/")
@@ -486,7 +492,16 @@ public class PathOps {
// isSameFile
test("/fileDoesNotExist")
.isSameFile("/fileDoesNotExist");
- }
+
+ // 8139956
+ out.println("check getNameCount");
+ int nc = fs.getPath("/").relativize(fs.getPath("/")).getNameCount();
+ if (nc != 1) {
+ out.format("\tExpected: 1\n");
+ out.format("\tActual: %d\n", nc);
+ throw new RuntimeException("getNameCount of empty path failed");
+ }
+ }
static void npes() {
header("NullPointerException");
diff --git a/jdk/test/jdk/nio/zipfs/ZFSTests.java b/jdk/test/jdk/nio/zipfs/ZFSTests.java
index 8febcf2730d..d9542601afe 100644
--- a/jdk/test/jdk/nio/zipfs/ZFSTests.java
+++ b/jdk/test/jdk/nio/zipfs/ZFSTests.java
@@ -22,11 +22,12 @@
*/
/* @test
- * @bug 7156873 8040059 8028480 8034773
+ * @bug 7156873 8040059 8028480 8034773 8153248
* @summary ZipFileSystem regression tests
*
* @run main ZFSTests
* @run main/othervm/java.security.policy=test.policy ZFSTests
+ * @modules jdk.zipfs
*/
@@ -42,7 +43,7 @@ public class ZFSTests {
public static void main(String[] args) throws Throwable {
test7156873();
- testOpenOptions();
+ tests();
}
static void test7156873() throws Throwable {
@@ -61,7 +62,7 @@ public class ZFSTests {
}
}
- static void testOpenOptions() throws Throwable {
+ static void tests() throws Throwable {
Path path = Paths.get("file.zip");
try {
URI uri = URI.create("jar:" + path.toUri());
@@ -95,6 +96,18 @@ public class ZFSTests {
} catch (IllegalArgumentException x) {
// expected x.printStackTrace();
}
+
+ //8153248
+ Path dir = fs.getPath("/dir");
+ Path subdir = fs.getPath("/dir/subdir");
+ Files.createDirectory(dir);
+ Files.createDirectory(subdir);
+ Files.list(dir)
+ .forEach( child -> {
+ System.out.println("child:" + child);
+ if (child.toString().endsWith("/"))
+ throw new RuntimeException("subdir names ends with /");
+ });
}
} finally {
Files.deleteIfExists(path);
diff --git a/jdk/test/jdk/nio/zipfs/ZipFSTester.java b/jdk/test/jdk/nio/zipfs/ZipFSTester.java
index 58389250e43..683bcae00b6 100644
--- a/jdk/test/jdk/nio/zipfs/ZipFSTester.java
+++ b/jdk/test/jdk/nio/zipfs/ZipFSTester.java
@@ -74,6 +74,7 @@ import static java.nio.file.StandardCopyOption.*;
* @summary Test Zip filesystem provider
* @run main ZipFSTester
* @run main/othervm/java.security.policy=test.policy ZipFSTester
+ * @modules jdk.zipfs
*/
public class ZipFSTester {
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/OSInfo.java b/jdk/test/lib/testlibrary/jdk/testlibrary/OSInfo.java
index f95fdeefc1b..7cdc714b0fd 100644
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/OSInfo.java
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/OSInfo.java
@@ -28,6 +28,9 @@ package jdk.testlibrary;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.InputStreamReader;
import static jdk.testlibrary.OSInfo.OSType.*;
@@ -147,6 +150,28 @@ public class OSInfo {
}
}
+ public static double getSolarisVersion() {
+ try {
+ OutputAnalyzer output = ProcessTools.executeProcess("uname", "-v");
+ System.out.println("'uname -v' finished with code "
+ + output.getExitValue());
+ return Double.parseDouble(output.getOutput());
+ } catch (Exception e) {
+ System.out.println("First attempt failed with: " + e.getMessage());
+ }
+
+ //Try to get Solaris version from /etc/release
+ try (BufferedReader in =
+ new BufferedReader(new FileReader("/etc/release"))) {
+ String line = in.readLine().trim().split(" ")[2];
+ return Double.parseDouble(line);
+ } catch (Exception e) {
+ System.out.println("Second attempt failed with: " + e.getMessage());
+ }
+
+ throw new RuntimeException("Unable to get Solaris version");
+ }
+
public static class WindowsVersion implements Comparable {
private final int major;
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
index 35cffc1c994..e2c2f110fc5 100644
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
@@ -423,7 +423,7 @@ public final class ProcessTools {
* @param cmds The command line to execute.
* @return The output from the process.
*/
- public static OutputAnalyzer executeProcess(String... cmds) throws Throwable {
+ public static OutputAnalyzer executeProcess(String... cmds) throws Exception {
return executeProcess(new ProcessBuilder(cmds));
}
diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/SimpleSSLContext.java b/jdk/test/lib/testlibrary/jdk/testlibrary/SimpleSSLContext.java
index 4fedb362c5c..17e50c70354 100644
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/SimpleSSLContext.java
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/SimpleSSLContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -23,8 +23,6 @@
package jdk.testlibrary;
-import com.sun.net.httpserver.*;
-
import java.util.*;
import java.util.concurrent.*;
import java.io.*;
@@ -54,7 +52,7 @@ public class SimpleSSLContext {
* loads default keystore from SimpleSSLContext
* source directory
*/
- public SimpleSSLContext () throws IOException {
+ public SimpleSSLContext() throws IOException {
String paths = System.getProperty("test.src.path");
StringTokenizer st = new StringTokenizer(paths, File.pathSeparator);
boolean securityExceptions = false;
@@ -63,8 +61,10 @@ public class SimpleSSLContext {
try {
File f = new File(path, "jdk/testlibrary/testkeys");
if (f.exists()) {
- init (new FileInputStream(f));
- return;
+ try (FileInputStream fis = new FileInputStream(f)) {
+ init(fis);
+ return;
+ }
}
} catch (SecurityException e) {
// catch and ignore because permission only required
@@ -80,13 +80,14 @@ public class SimpleSSLContext {
/**
* loads default keystore from given directory
*/
- public SimpleSSLContext (String dir) throws IOException {
+ public SimpleSSLContext(String dir) throws IOException {
String file = dir+"/testkeys";
- FileInputStream fis = new FileInputStream(file);
- init(fis);
+ try (FileInputStream fis = new FileInputStream(file)) {
+ init(fis);
+ }
}
- private void init (InputStream i) throws IOException {
+ private void init(InputStream i) throws IOException {
try {
char[] passphrase = "passphrase".toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
@@ -98,22 +99,22 @@ public class SimpleSSLContext {
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);
- ssl = SSLContext.getInstance ("TLS");
+ ssl = SSLContext.getInstance("TLS");
ssl.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
} catch (KeyManagementException e) {
- throw new RuntimeException (e.getMessage());
+ throw new RuntimeException(e.getMessage());
} catch (KeyStoreException e) {
- throw new RuntimeException (e.getMessage());
+ throw new RuntimeException(e.getMessage());
} catch (UnrecoverableKeyException e) {
- throw new RuntimeException (e.getMessage());
+ throw new RuntimeException(e.getMessage());
} catch (CertificateException e) {
- throw new RuntimeException (e.getMessage());
+ throw new RuntimeException(e.getMessage());
} catch (NoSuchAlgorithmException e) {
- throw new RuntimeException (e.getMessage());
+ throw new RuntimeException(e.getMessage());
}
}
- public SSLContext get () {
+ public SSLContext get() {
return ssl;
}
}
diff --git a/jdk/test/sun/net/InetAddress/nameservice/dns/cname.sh b/jdk/test/sun/net/InetAddress/nameservice/dns/cname.sh
index b47a5efcf0c..a93f2652613 100644
--- a/jdk/test/sun/net/InetAddress/nameservice/dns/cname.sh
+++ b/jdk/test/sun/net/InetAddress/nameservice/dns/cname.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 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
@@ -26,6 +26,7 @@
# @test
# @bug 4763315
+# @modules java.naming
# @build CanonicalName Lookup
# @run shell/timeout=120 cname.sh
# @summary Test DNS provider's handling of CNAME records
diff --git a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedEncodingTest.java b/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedEncodingTest.java
index 8791b4e27af..1d837841fb4 100644
--- a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedEncodingTest.java
+++ b/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedEncodingTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -24,6 +24,7 @@
/**
* @test
* @bug 4333920
+ * @modules jdk.httpserver
* @run main ChunkedEncodingTest
* @summary ChunkedEncodingTest unit test
*/
diff --git a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java b/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java
index 35b76396930..6affe7a767c 100644
--- a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java
+++ b/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -26,6 +26,7 @@
* @bug 4333920 4994372
* @summary ChunkedEncoding unit test; MeteredStream/ProgressData problem
* @modules java.base/sun.net
+ * jdk.httpserver
* @run main ChunkedEncodingWithProgressMonitorTest
*/
diff --git a/jdk/test/sun/net/www/http/ChunkedInputStream/TestAvailable.java b/jdk/test/sun/net/www/http/ChunkedInputStream/TestAvailable.java
index 0423c81060f..a1737d79c23 100644
--- a/jdk/test/sun/net/www/http/ChunkedInputStream/TestAvailable.java
+++ b/jdk/test/sun/net/www/http/ChunkedInputStream/TestAvailable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 6446990
+ * @modules jdk.httpserver
* @run main/othervm TestAvailable
* @summary HttpURLConnection#available() reads more and more data into memory
*/
diff --git a/jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java b/jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java
index a017e6eca9e..82b4e36d01c 100644
--- a/jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java
+++ b/jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -24,6 +24,7 @@
/**
* @test
* @bug 5026745 6631048
+ * @modules jdk.httpserver
* @run main/othervm/timeout=500 Test
* @summary Cannot flush output stream when writing to an HttpUrlConnection
*/
diff --git a/jdk/test/sun/net/www/http/HttpClient/B7025238.java b/jdk/test/sun/net/www/http/HttpClient/B7025238.java
index 313972594a4..1af7ec83d5f 100644
--- a/jdk/test/sun/net/www/http/HttpClient/B7025238.java
+++ b/jdk/test/sun/net/www/http/HttpClient/B7025238.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -30,6 +30,7 @@ import java.util.concurrent.Executors;
/*
* @test
* @bug 7025238
+ * @modules jdk.httpserver
* @summary HttpURLConnection does not handle URLs with an empty path component
*/
public class B7025238 {
diff --git a/jdk/test/sun/net/www/http/HttpURLConnection/DigestAuth.java b/jdk/test/sun/net/www/http/HttpURLConnection/DigestAuth.java
index 11d6729ae21..7eaa4f74ed4 100644
--- a/jdk/test/sun/net/www/http/HttpURLConnection/DigestAuth.java
+++ b/jdk/test/sun/net/www/http/HttpURLConnection/DigestAuth.java
@@ -41,6 +41,7 @@ import java.util.List;
* @summary Tests for HTTP Digest auth
* The impl maintains a cache for auth info,
* the testcases run in a separate JVM to avoid cache hits
+ * @modules jdk.httpserver
* @run main/othervm DigestAuth good
* @run main/othervm DigestAuth only_nonce
* @run main/othervm DigestAuth sha1
diff --git a/jdk/test/sun/net/www/http/HttpURLConnection/NTLMAuthWithSM.java b/jdk/test/sun/net/www/http/HttpURLConnection/NTLMAuthWithSM.java
index d5dfde58233..6423de7e409 100644
--- a/jdk/test/sun/net/www/http/HttpURLConnection/NTLMAuthWithSM.java
+++ b/jdk/test/sun/net/www/http/HttpURLConnection/NTLMAuthWithSM.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -40,6 +40,7 @@ import sun.net.www.protocol.http.ntlm.NTLMAuthenticationCallback;
* @test
* @bug 8137174
* @modules java.base/sun.net.www.protocol.http.ntlm
+ * jdk.httpserver
* @summary Checks if NTLM auth works fine if security manager set
* @run main/othervm/java.security.policy=NTLMAuthWithSM.policy NTLMAuthWithSM
*/
diff --git a/jdk/test/sun/net/www/http/HttpURLConnection/PostOnDelete.java b/jdk/test/sun/net/www/http/HttpURLConnection/PostOnDelete.java
index 07d353cba85..104be1d6d94 100644
--- a/jdk/test/sun/net/www/http/HttpURLConnection/PostOnDelete.java
+++ b/jdk/test/sun/net/www/http/HttpURLConnection/PostOnDelete.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -30,6 +30,7 @@ import java.net.*;
/*
* @test
* @bug 7157360
+ * @modules jdk.httpserver
* @summary HttpURLConnection: HTTP method DELETE doesn't support output
*/
public class PostOnDelete {
diff --git a/jdk/test/sun/net/www/protocol/http/6550798/test.java b/jdk/test/sun/net/www/protocol/http/6550798/test.java
index 9bcf5f91548..95f70f58911 100644
--- a/jdk/test/sun/net/www/protocol/http/6550798/test.java
+++ b/jdk/test/sun/net/www/protocol/http/6550798/test.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -25,6 +25,7 @@
* @test
* @bug 6550798
* @summary Using InputStream.skip with ResponseCache will cause partial data to be cached
+ * @modules jdk.httpserver
* @run main/othervm test
*/
diff --git a/jdk/test/sun/net/www/protocol/http/AsyncDisconnect.java b/jdk/test/sun/net/www/protocol/http/AsyncDisconnect.java
index d052b018ffa..250557e9c55 100644
--- a/jdk/test/sun/net/www/protocol/http/AsyncDisconnect.java
+++ b/jdk/test/sun/net/www/protocol/http/AsyncDisconnect.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 6358532
+ * @modules jdk.httpserver
* @run main/othervm AsyncDisconnect
* @summary HttpURLConnection.disconnect doesn't really do the job
*/
diff --git a/jdk/test/sun/net/www/protocol/http/B5017051.java b/jdk/test/sun/net/www/protocol/http/B5017051.java
index 8e1218d1a3a..1859be41a61 100644
--- a/jdk/test/sun/net/www/protocol/http/B5017051.java
+++ b/jdk/test/sun/net/www/protocol/http/B5017051.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 5017051 6360774
+ * @modules jdk.httpserver
* @run main/othervm B5017051
* @summary Tests CR 5017051 & 6360774
*/
diff --git a/jdk/test/sun/net/www/protocol/http/B6299712.java b/jdk/test/sun/net/www/protocol/http/B6299712.java
index cf7be47e3ef..24c78d64bfa 100644
--- a/jdk/test/sun/net/www/protocol/http/B6299712.java
+++ b/jdk/test/sun/net/www/protocol/http/B6299712.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 6299712 7150552
+ * @modules jdk.httpserver
* @run main/othervm B6299712
* @summary NullPointerException in sun.net.www.protocol.http.HttpURLConnection.followRedirect
*/
diff --git a/jdk/test/sun/net/www/protocol/http/B6369510.java b/jdk/test/sun/net/www/protocol/http/B6369510.java
index 7757f091d7b..2068b04b5b2 100644
--- a/jdk/test/sun/net/www/protocol/http/B6369510.java
+++ b/jdk/test/sun/net/www/protocol/http/B6369510.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 6369510
+ * @modules jdk.httpserver
* @run main/othervm B6369510
* @summary HttpURLConnection sets Content-Type to application/x-www-form-urlencoded
*/
diff --git a/jdk/test/sun/net/www/protocol/http/B6518816.java b/jdk/test/sun/net/www/protocol/http/B6518816.java
index d74db8ef2aa..929387c3e7b 100644
--- a/jdk/test/sun/net/www/protocol/http/B6518816.java
+++ b/jdk/test/sun/net/www/protocol/http/B6518816.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 6518816
+ * @modules jdk.httpserver
* @run main/othervm B6518816
*/
diff --git a/jdk/test/sun/net/www/protocol/http/B6641309.java b/jdk/test/sun/net/www/protocol/http/B6641309.java
index 9da4da3aef0..25952c65cd7 100644
--- a/jdk/test/sun/net/www/protocol/http/B6641309.java
+++ b/jdk/test/sun/net/www/protocol/http/B6641309.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 6641309
+ * @modules jdk.httpserver
* @summary Wrong Cookie separator used in HttpURLConnection
*/
diff --git a/jdk/test/sun/net/www/protocol/http/B6660405.java b/jdk/test/sun/net/www/protocol/http/B6660405.java
index 8cde84eca9f..50b5838e2c5 100644
--- a/jdk/test/sun/net/www/protocol/http/B6660405.java
+++ b/jdk/test/sun/net/www/protocol/http/B6660405.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 6660405
+ * @modules jdk.httpserver
* @summary HttpURLConnection returns the wrong InputStream
*/
diff --git a/jdk/test/sun/net/www/protocol/http/B8012625.java b/jdk/test/sun/net/www/protocol/http/B8012625.java
index c8c8ef0c033..8145941530c 100644
--- a/jdk/test/sun/net/www/protocol/http/B8012625.java
+++ b/jdk/test/sun/net/www/protocol/http/B8012625.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -24,6 +24,7 @@
/**
* @test
* @bug 8012625
+ * @modules jdk.httpserver
* @run main B8012625
*/
diff --git a/jdk/test/sun/net/www/protocol/http/BasicLongCredentials.java b/jdk/test/sun/net/www/protocol/http/BasicLongCredentials.java
index 5e8bb8e4c41..02e54b1529d 100644
--- a/jdk/test/sun/net/www/protocol/http/BasicLongCredentials.java
+++ b/jdk/test/sun/net/www/protocol/http/BasicLongCredentials.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -24,6 +24,7 @@
/**
* @test
* @bug 6947917
+ * @modules jdk.httpserver
* @summary Error in basic authentication when user name and password are long
*/
diff --git a/jdk/test/sun/net/www/protocol/http/ChunkedErrorStream.java b/jdk/test/sun/net/www/protocol/http/ChunkedErrorStream.java
index 33a143b5b5c..e673080306f 100644
--- a/jdk/test/sun/net/www/protocol/http/ChunkedErrorStream.java
+++ b/jdk/test/sun/net/www/protocol/http/ChunkedErrorStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 6488669 6595324 6993490
+ * @modules jdk.httpserver
* @run main/othervm ChunkedErrorStream
* @summary Chunked ErrorStream tests
*/
diff --git a/jdk/test/sun/net/www/protocol/http/HttpOnly.java b/jdk/test/sun/net/www/protocol/http/HttpOnly.java
index 6a2ce8256d9..d377ebf7c15 100644
--- a/jdk/test/sun/net/www/protocol/http/HttpOnly.java
+++ b/jdk/test/sun/net/www/protocol/http/HttpOnly.java
@@ -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
@@ -23,6 +23,7 @@
/**
* @test
* @bug 7095980 8007315
+ * @modules jdk.httpserver
* @summary Ensure HttpURLConnection (and supporting APIs) don't expose
* HttpOnly cookies
*/
diff --git a/jdk/test/sun/net/www/protocol/http/HttpStreams.java b/jdk/test/sun/net/www/protocol/http/HttpStreams.java
index 897cd6572b5..9b94b53e09b 100644
--- a/jdk/test/sun/net/www/protocol/http/HttpStreams.java
+++ b/jdk/test/sun/net/www/protocol/http/HttpStreams.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -24,6 +24,7 @@
/**
* @test
* @bug 8011719
+ * @modules jdk.httpserver
* @summary Basic checks to verify behavior of returned input streams
*/
diff --git a/jdk/test/sun/net/www/protocol/http/NoCache.java b/jdk/test/sun/net/www/protocol/http/NoCache.java
index f452bc3d497..f60efcb1ed8 100644
--- a/jdk/test/sun/net/www/protocol/http/NoCache.java
+++ b/jdk/test/sun/net/www/protocol/http/NoCache.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 7133367
+ * @modules jdk.httpserver
* @summary ResponseCache.put should not be called when setUseCaches(false)
*/
diff --git a/jdk/test/sun/net/www/protocol/http/RedirectOnPost.java b/jdk/test/sun/net/www/protocol/http/RedirectOnPost.java
index 6582a67744f..8c485af01ac 100644
--- a/jdk/test/sun/net/www/protocol/http/RedirectOnPost.java
+++ b/jdk/test/sun/net/www/protocol/http/RedirectOnPost.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -24,6 +24,7 @@
/**
* @test
* @library /lib/testlibrary/
+ * @modules jdk.httpserver
* @build jdk.testlibrary.SimpleSSLContext
* @compile RedirectOnPost.java
* @run main/othervm RedirectOnPost
diff --git a/jdk/test/sun/net/www/protocol/http/StreamingOutputStream.java b/jdk/test/sun/net/www/protocol/http/StreamingOutputStream.java
index 31954bb17d0..dad3d29e7a4 100644
--- a/jdk/test/sun/net/www/protocol/http/StreamingOutputStream.java
+++ b/jdk/test/sun/net/www/protocol/http/StreamingOutputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 6472250
+ * @modules jdk.httpserver
* @run main/othervm StreamingOutputStream
* @summary HttpURLConnection.getOutputStream streaming mode bug when called multiple times
*/
diff --git a/jdk/test/sun/net/www/protocol/http/UserAuth.java b/jdk/test/sun/net/www/protocol/http/UserAuth.java
index 4d5b2de12d0..81432a8086f 100644
--- a/jdk/test/sun/net/www/protocol/http/UserAuth.java
+++ b/jdk/test/sun/net/www/protocol/http/UserAuth.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 6421122
+ * @modules jdk.httpserver
* @run main/othervm UserAuth
* @summary Authorization header removed for preemptive authentication by user code
*/
diff --git a/jdk/test/sun/net/www/protocol/http/UserCookie.java b/jdk/test/sun/net/www/protocol/http/UserCookie.java
index 2216385f312..ee5e15285cf 100644
--- a/jdk/test/sun/net/www/protocol/http/UserCookie.java
+++ b/jdk/test/sun/net/www/protocol/http/UserCookie.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -24,6 +24,7 @@
/*
* @test
* @bug 6439651
+ * @modules jdk.httpserver
* @run main/othervm UserAuth
* @summary Sending "Cookie" header with JRE 1.5.0_07 doesn't work anymore
*/
diff --git a/jdk/test/sun/net/www/protocol/http/ZoneId.java b/jdk/test/sun/net/www/protocol/http/ZoneId.java
index fb611a4ea52..6d8b7d1b628 100644
--- a/jdk/test/sun/net/www/protocol/http/ZoneId.java
+++ b/jdk/test/sun/net/www/protocol/http/ZoneId.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -26,6 +26,7 @@
* @bug 8027308
* @key intermittent
* @modules java.base/sun.net.www.protocol.http
+ * jdk.httpserver
* @summary verifies that HttpURLConnection does not send the zone id in the
* 'Host' field of the header:
* Host: [fe80::a00:27ff:aaaa:aaaa] instead of
diff --git a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/HttpsCreateSockTest.java b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/HttpsCreateSockTest.java
index a7e0bc3ab14..68b20803ae9 100644
--- a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/HttpsCreateSockTest.java
+++ b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/HttpsCreateSockTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -26,6 +26,7 @@
* @bug 6771432
* @summary createSocket() - smpatch fails using 1.6.0_10 because of
* "Unconnected sockets not implemented"
+ * @modules jdk.httpserver
* @run main/othervm HttpsCreateSockTest
*
* SunJSSE does not support dynamic system properties, no way to re-use
diff --git a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java
index 4011cea722e..6e1414f8cdd 100644
--- a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java
+++ b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -25,6 +25,7 @@
* @test
* @bug 6614957
* @summary HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
+ * @modules jdk.httpserver
* @run main/othervm HttpsSocketFacTest
*
* SunJSSE does not support dynamic system properties, no way to re-use
diff --git a/jdk/test/sun/net/www/protocol/jar/MultiReleaseJarURLConnection.java b/jdk/test/sun/net/www/protocol/jar/MultiReleaseJarURLConnection.java
index f6b01a08d40..e97de717772 100644
--- a/jdk/test/sun/net/www/protocol/jar/MultiReleaseJarURLConnection.java
+++ b/jdk/test/sun/net/www/protocol/jar/MultiReleaseJarURLConnection.java
@@ -26,6 +26,9 @@
* @bug 8132734 8144062
* @summary Test that URL connections to multi-release jars can be runtime versioned
* @library /lib/testlibrary/java/util/jar
+ * @modules java.compiler
+ * jdk.httpserver
+ * jdk.jartool
* @build Compiler JarBuilder CreateMultiReleaseTestJars SimpleHttpServer
* @run testng MultiReleaseJarURLConnection
*/
diff --git a/jdk/test/sun/nio/ch/TestMaxCachedBufferSize.java b/jdk/test/sun/nio/ch/TestMaxCachedBufferSize.java
index 8c8049bdf5c..9ec2dbfd019 100644
--- a/jdk/test/sun/nio/ch/TestMaxCachedBufferSize.java
+++ b/jdk/test/sun/nio/ch/TestMaxCachedBufferSize.java
@@ -43,6 +43,7 @@ import java.util.Random;
/*
* @test
* @requires sun.arch.data.model == "64"
+ * @modules java.management
* @build TestMaxCachedBufferSize
* @run main/othervm TestMaxCachedBufferSize
* @run main/othervm -Djdk.nio.maxCachedBufferSize=0 TestMaxCachedBufferSize
diff --git a/jdk/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java b/jdk/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java
index bd2fcdadc31..45a7c178455 100644
--- a/jdk/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java
+++ b/jdk/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java
@@ -33,6 +33,7 @@ import java.security.spec.DSAParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.util.Arrays;
import java.util.List;
+import java.util.stream.Collectors;
/*
* @test
@@ -41,26 +42,15 @@ import java.util.List;
* @summary Verify that DSAGenParameterSpec can and can only be used to generate
* DSA within some certain range of key sizes as described in the class
* specification (L, N) as (1024, 160), (2048, 224), (2048, 256) and
- * (3072, 256) should be OK for DSAGenParameterSpec. But the real
- * implementation SUN doesn't support (3072, 256).
- * @run main TestDSAGenParameterSpec
+ * (3072, 256) should be OK for DSAGenParameterSpec.
+ * @run main TestDSAGenParameterSpec 2048,256,true 2048,224,true 1024,160,true 4096,256 3072,224 2048,160 1024,224 512,160
+ * @run main TestDSAGenParameterSpec 3072,256,true
*/
public class TestDSAGenParameterSpec {
private static final String ALGORITHM_NAME = "DSA";
private static final String PROVIDER_NAME = "SUN";
- private static final List DATA = Arrays.asList(
- new DataTuple(1024, 160, true, true),
- new DataTuple(2048, 224, true, true),
- new DataTuple(2048, 256, true, true),
- new DataTuple(3072, 256, true, false),
- new DataTuple(1024, 224),
- new DataTuple(2048, 160),
- new DataTuple(4096, 256),
- new DataTuple(512, 160),
- new DataTuple(3072, 224));
-
private static void testDSAGenParameterSpec(DataTuple dataTuple)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidParameterSpecException, InvalidAlgorithmParameterException {
@@ -84,14 +74,7 @@ public class TestDSAGenParameterSpec {
checkParam(param, genParamSpec);
System.out.println("Test case passed");
} catch (InvalidParameterException ipe) {
- // The DSAGenParameterSpec API support this, but the real
- // implementation in SUN doesn't
- if (!dataTuple.isSunProviderSupported) {
- System.out.println("Test case passed: expected "
- + "InvalidParameterException is caught");
- } else {
- throw new RuntimeException("Test case failed.", ipe);
- }
+ throw new RuntimeException("Test case failed.", ipe);
}
}
@@ -127,11 +110,9 @@ public class TestDSAGenParameterSpec {
throw new RuntimeException("Wrong seed length");
}
- // use the parameters to generate real DSA keys
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM_NAME,
PROVIDER_NAME);
keyGen.initialize(spec);
- keyGen.generateKeyPair();
}
private static DSAGenParameterSpec createGenParameterSpec(
@@ -158,10 +139,21 @@ public class TestDSAGenParameterSpec {
}
public static void main(String[] args) throws Exception {
- for (DataTuple dataTuple : DATA) {
+ List dataTuples = Arrays.stream(args)
+ .map(arg -> arg.split(",")).map(params -> {
+ int primePLen = Integer.valueOf(params[0]);
+ int subprimeQLen = Integer.valueOf(params[1]);
+ boolean isDSASpecSupported = false;
+ if (params.length == 3) {
+ isDSASpecSupported = Boolean.valueOf(params[2]);
+ }
+ return new DataTuple(primePLen, subprimeQLen,
+ isDSASpecSupported);
+ }).collect(Collectors.toList());
+
+ for (DataTuple dataTuple : dataTuples) {
testDSAGenParameterSpec(dataTuple);
}
- System.out.println("All tests passed");
}
private static class DataTuple {
@@ -169,18 +161,13 @@ public class TestDSAGenParameterSpec {
private int primePLen;
private int subprimeQLen;
private boolean isDSASpecSupported;
- private boolean isSunProviderSupported;
private DataTuple(int primePLen, int subprimeQLen,
- boolean isDSASpecSupported, boolean isSunProviderSupported) {
+ boolean isDSASpecSupported) {
this.primePLen = primePLen;
this.subprimeQLen = subprimeQLen;
this.isDSASpecSupported = isDSASpecSupported;
- this.isSunProviderSupported = isSunProviderSupported;
- }
-
- private DataTuple(int primePLen, int subprimeQLen) {
- this(primePLen, subprimeQLen, false, false);
}
}
}
+
diff --git a/jdk/test/sun/security/provider/PolicyFile/Modules.java b/jdk/test/sun/security/provider/PolicyFile/Modules.java
index 855441e036a..914ef05790d 100644
--- a/jdk/test/sun/security/provider/PolicyFile/Modules.java
+++ b/jdk/test/sun/security/provider/PolicyFile/Modules.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -25,6 +25,19 @@
* @test
* @bug 8047771
* @summary check permissions and principals from various modules
+ * @modules java.desktop
+ * java.logging
+ * java.management
+ * java.security.jgss
+ * java.smartcardio
+ * java.sql
+ * java.xml
+ * java.xml.bind
+ * jdk.attach
+ * jdk.jdi
+ * jdk.net
+ * jdk.security.auth
+ * jdk.security.jgss
* @compile -addmods java.xml.ws,java.smartcardio Modules.java
* @run main/othervm/java.security.policy==modules.policy
* -addmods java.xml.ws,java.smartcardio Modules
diff --git a/jdk/test/sun/text/IntHashtable/Bug4170614Test.java b/jdk/test/sun/text/IntHashtable/Bug4170614Test.java
new file mode 100644
index 00000000000..97e08a1bdd4
--- /dev/null
+++ b/jdk/test/sun/text/IntHashtable/Bug4170614Test.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 1999, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ (this test doesn't have an at-test tag because it's run by a shell
+ script instead of directly by the test harness)
+*/
+
+/*
+ *
+ *
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
+ *
+ * Portions copyright (c) 2007 Sun Microsystems, Inc.
+ * All Rights Reserved.
+ *
+ * The original version of this source code and documentation
+ * is copyrighted and owned by Taligent, Inc., a wholly-owned
+ * subsidiary of IBM. These materials are provided under terms
+ * of a License Agreement between Taligent and Sun. This technology
+ * is protected by multiple US and International patents.
+ *
+ * This notice and attribution to Taligent may not be removed.
+ * Taligent is a registered trademark of Taligent, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies. Please refer to the file "copyright.html"
+ * for further important copyright and licensing information.
+ *
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+ *
+ */
+package java.text;
+import sun.text.IntHashtable;
+
+
+/**
+ * This class tests some internal hashCode() functions.
+ * Bug #4170614 complained that we had two iternal classes that
+ * break the invariant that if a.equals(b) than a.hashCode() ==
+ * b.hashCode(). This is because these classes overrode equals()
+ * but not hashCode(). These are both purely internal classes, and
+ * the library itself doesn't actually call hashCode(), so this isn't
+ * actually causing anyone problems yet. But if these classes are
+ * ever exposed in the API, their hashCode() methods need to work right.
+ * PatternEntry will never be exposed in the API, but IntHashtable
+ * might be. This is a shell test to allow us to access classes that
+ * are declared package private.
+ * @author Richard Gillam
+ */
+public class Bug4170614Test {
+ public static void main(String[] args) throws Exception {
+ testIntHashtable();
+ testPatternEntry();
+ }
+
+
+ public static void testIntHashtable() throws Exception {
+ IntHashtable fred = new IntHashtable();
+ fred.put(1, 10);
+ fred.put(2, 20);
+ fred.put(3, 30);
+
+ IntHashtable barney = new IntHashtable();
+ barney.put(1, 10);
+ barney.put(3, 30);
+ barney.put(2, 20);
+
+ IntHashtable homer = new IntHashtable();
+ homer.put(3, 30);
+ homer.put(1, 10);
+ homer.put(7, 900);
+
+ if (fred.equals(barney)) {
+ System.out.println("fred.equals(barney)");
+ }
+ else {
+ System.out.println("!fred.equals(barney)");
+ }
+ System.out.println("fred.hashCode() == " + fred.hashCode());
+ System.out.println("barney.hashCode() == " + barney.hashCode());
+
+ if (!fred.equals(barney)) {
+ throw new Exception("equals() failed on two hashtables that are equal");
+ }
+
+ if (fred.hashCode() != barney.hashCode()) {
+ throw new Exception("hashCode() failed on two hashtables that are equal");
+ }
+
+ System.out.println();
+ if (fred.equals(homer)) {
+ System.out.println("fred.equals(homer)");
+ }
+ else {
+ System.out.println("!fred.equals(homer)");
+ }
+ System.out.println("fred.hashCode() == " + fred.hashCode());
+ System.out.println("homer.hashCode() == " + homer.hashCode());
+
+ if (fred.equals(homer)) {
+ throw new Exception("equals() failed on two hashtables that are not equal");
+ }
+
+ if (fred.hashCode() == homer.hashCode()) {
+ throw new Exception("hashCode() failed on two hashtables that are not equal");
+ }
+
+ System.out.println();
+ System.out.println("testIntHashtable() passed.\n");
+ }
+
+ public static void testPatternEntry() throws Exception {
+ PatternEntry fred = new PatternEntry(1,
+ new StringBuffer("hello"),
+ new StringBuffer("up"));
+ PatternEntry barney = new PatternEntry(1,
+ new StringBuffer("hello"),
+ new StringBuffer("down"));
+ // (equals() only considers the "chars" field, so fred and barney are equal)
+ PatternEntry homer = new PatternEntry(1,
+ new StringBuffer("goodbye"),
+ new StringBuffer("up"));
+
+ if (fred.equals(barney)) {
+ System.out.println("fred.equals(barney)");
+ }
+ else {
+ System.out.println("!fred.equals(barney)");
+ }
+ System.out.println("fred.hashCode() == " + fred.hashCode());
+ System.out.println("barney.hashCode() == " + barney.hashCode());
+
+ if (!fred.equals(barney)) {
+ throw new Exception("equals() failed on two hashtables that are equal");
+ }
+
+ if (fred.hashCode() != barney.hashCode()) {
+ throw new Exception("hashCode() failed on two hashtables that are equal");
+ }
+
+ System.out.println();
+ if (fred.equals(homer)) {
+ System.out.println("fred.equals(homer)");
+ }
+ else {
+ System.out.println("!fred.equals(homer)");
+ }
+ System.out.println("fred.hashCode() == " + fred.hashCode());
+ System.out.println("homer.hashCode() == " + homer.hashCode());
+
+ if (fred.equals(homer)) {
+ throw new Exception("equals() failed on two hashtables that are not equal");
+ }
+
+ if (fred.hashCode() == homer.hashCode()) {
+ throw new Exception("hashCode() failed on two hashtables that are not equal");
+ }
+
+ System.out.println();
+ System.out.println("testPatternEntry() passed.\n");
+ }
+}
diff --git a/jdk/test/sun/text/IntHashtable/Bug4170614Test.sh b/jdk/test/sun/text/IntHashtable/Bug4170614Test.sh
new file mode 100644
index 00000000000..b8dad0084a6
--- /dev/null
+++ b/jdk/test/sun/text/IntHashtable/Bug4170614Test.sh
@@ -0,0 +1,81 @@
+#!/bin/sh
+
+#
+# Copyright (c) 1999, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# @test
+# @bug 4170614
+# @summary Test internal hashCode() functions
+#
+
+set -x
+if [ "${TESTSRC}" = "" ]
+then
+ echo "TESTSRC not set. Test cannot execute. Failed."
+ exit 1
+fi
+echo "TESTSRC=${TESTSRC}"
+if [ "${TESTJAVA}" = "" ]
+then
+ echo "TESTJAVA not set. Test cannot execute. Failed."
+ exit 1
+fi
+echo "TESTJAVA=${TESTJAVA}"
+if [ "${COMPILEJAVA}" = "" ]; then
+ COMPILEJAVA="${TESTJAVA}"
+fi
+echo "COMPILEJAVA=${COMPILEJAVA}"
+if [ "${TESTCLASSES}" = "" ]
+then
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
+ exit 1
+fi
+echo "TESTCLASSES=${TESTCLASSES}"
+
+goback=`pwd`
+
+cd ${TESTSRC}
+
+TEST_JAVABASE=${TESTCLASSES}/java.base
+mkdir -p ${TEST_JAVABASE}
+${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
+ -Xmodule:java.base \
+ -d ${TEST_JAVABASE} Bug4170614Test.java
+
+${TESTJAVA}/bin/java ${TESTVMOPTS} -Xpatch:java.base=${TEST_JAVABASE} java.text.Bug4170614Test
+
+result=$?
+
+cd ${goback}
+
+if [ $result -eq 0 ]
+then
+ echo "Passed"
+else
+ echo "Failed"
+fi
+exit $result
+
+
+
diff --git a/jdk/test/sun/text/IntHashtable/Bug4705389.java b/jdk/test/sun/text/IntHashtable/Bug4705389.java
new file mode 100644
index 00000000000..d2f6e49a829
--- /dev/null
+++ b/jdk/test/sun/text/IntHashtable/Bug4705389.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2002, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4705389
+ * @summary Make sure to find removed slots, which test case will be timed out without the fix.
+ * @modules java.base/sun.text
+ * @run main/timeout=10 Bug4705389
+ */
+
+import sun.text.IntHashtable;
+
+public class Bug4705389 {
+ public static void main(String args[]) {
+ IntHashtable table = new IntHashtable();
+ for (int i = 1; i < 132; ++i) {
+ table.put(i, 0);
+ table.remove(i);
+ }
+ table.put(132, 0);
+ }
+}
diff --git a/jdk/test/sun/util/logging/SourceClassName.java b/jdk/test/sun/util/logging/SourceClassName.java
index 0de431a1a20..f3023122618 100644
--- a/jdk/test/sun/util/logging/SourceClassName.java
+++ b/jdk/test/sun/util/logging/SourceClassName.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -28,6 +28,7 @@
* logger.
*
* @modules java.base/sun.util.logging
+ * java.logging
* @compile -XDignore.symbol.file SourceClassName.java
* @run main/othervm SourceClassName
*/
diff --git a/make/Images.gmk b/make/Images.gmk
index 92adf3013db..c3e93a47a97 100644
--- a/make/Images.gmk
+++ b/make/Images.gmk
@@ -115,9 +115,12 @@ JMODS := $(wildcard $(IMAGES_OUTPUTDIR)/jmods/*.jmod)
# Use this file inside the image as target for make rule
JIMAGE_TARGET_FILE := bin/java$(EXE_SUFFIX)
-JLINK_ORDER_RESOURCES := \
- *module-info.class* \
- @$(SUPPORT_OUTPUTDIR)/classlist/classlist,/java.base/java/* \
+JLINK_ORDER_RESOURCES := *module-info.class*
+ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
+ JLINK_ORDER_RESOURCES += @$(SUPPORT_OUTPUTDIR)/classlist/classlist
+endif
+JLINK_ORDER_RESOURCES += \
+ /java.base/java/* \
/java.base/jdk/* \
/java.base/sun/* \
/java.base/com/* \
@@ -125,9 +128,10 @@ JLINK_ORDER_RESOURCES := \
#
JLINK_TOOL := $(JLINK) --modulepath $(IMAGES_OUTPUTDIR)/jmods \
- --endian $(OPENJDK_BUILD_CPU_ENDIAN) \
- --order-resources=$(call CommaList, $(JLINK_ORDER_RESOURCES)) \
- --release-info $(BASE_RELEASE_FILE)
+ --endian $(OPENJDK_BUILD_CPU_ENDIAN) \
+ --release-info $(BASE_RELEASE_FILE) \
+ --order-resources=$(call CommaList, $(JLINK_ORDER_RESOURCES)) \
+ #
ifeq ($(JLINK_KEEP_PACKAGED_MODULES), true)
JLINK_EXTRA_OPTS := --keep-packaged-modules $(JDK_IMAGE_DIR)/jmods
@@ -369,19 +373,21 @@ JDK_TARGETS += $(JDK_IMAGE_DIR)/src.zip
################################################################################
# classlist
-$(eval $(call SetupCopyFiles, JDK_COPY_CLASSLIST, \
- FILES := $(SUPPORT_OUTPUTDIR)/classlist/classlist, \
- DEST := $(JDK_IMAGE_DIR)/lib, \
-))
+ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
+ $(eval $(call SetupCopyFiles, JDK_COPY_CLASSLIST, \
+ FILES := $(SUPPORT_OUTPUTDIR)/classlist/classlist, \
+ DEST := $(JDK_IMAGE_DIR)/lib, \
+ ))
-JDK_TARGETS += $(JDK_COPY_CLASSLIST)
+ JDK_TARGETS += $(JDK_COPY_CLASSLIST)
-$(eval $(call SetupCopyFiles, JRE_COPY_CLASSLIST, \
- FILES := $(SUPPORT_OUTPUTDIR)/classlist/classlist, \
- DEST := $(JRE_IMAGE_DIR)/lib, \
-))
+ $(eval $(call SetupCopyFiles, JRE_COPY_CLASSLIST, \
+ FILES := $(SUPPORT_OUTPUTDIR)/classlist/classlist, \
+ DEST := $(JRE_IMAGE_DIR)/lib, \
+ ))
-JRE_TARGETS += $(JRE_COPY_CLASSLIST)
+ JRE_TARGETS += $(JRE_COPY_CLASSLIST)
+endif
################################################################################
# /demo dir
diff --git a/make/Main.gmk b/make/Main.gmk
index cbde81f552c..d703a266fa1 100644
--- a/make/Main.gmk
+++ b/make/Main.gmk
@@ -373,8 +373,10 @@ ALL_TARGETS += create-buildjdk-copy create-buildjdk-interim-image
interim-image:
+($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f InterimImage.gmk)
-generate-classlist:
+ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
+ generate-classlist:
+($(CD) $(JDK_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f GenerateClasslist.gmk)
+endif
ALL_TARGETS += interim-image generate-classlist
@@ -640,18 +642,22 @@ else
jrtfs-jar: interim-langtools
- ifeq ($(CREATE_BUILDJDK), true)
- # If creating a buildjdk, the interim image needs to be based on that.
- generate-classlist: create-buildjdk
- else ifeq ($(EXTERNAL_BUILDJDK), false)
- # If an external buildjdk has been provided, we skip generating an
- # interim-image and just use the external buildjdk for generating
- # classlist.
- generate-classlist: interim-image
- endif
- generate-classlist: buildtools-jdk
+ ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
+ ifeq ($(CREATE_BUILDJDK), true)
+ # If creating a buildjdk, the interim image needs to be based on that.
+ generate-classlist: create-buildjdk
+ else ifeq ($(EXTERNAL_BUILDJDK), false)
+ # If an external buildjdk has been provided, we skip generating an
+ # interim-image and just use the external buildjdk for generating
+ # classlist.
+ generate-classlist: interim-image
+ endif
+ generate-classlist: buildtools-jdk
- jimages: jmods zip-source source-tips demos samples jrtfs-jar generate-classlist
+ jimages: generate-classlist
+ endif
+
+ jimages: jmods zip-source source-tips demos samples jrtfs-jar
profiles: jmods zip-source source-tips jrtfs-jar
diff --git a/nashorn/.hgtags b/nashorn/.hgtags
index 4aa4df6e17e..d14800deeb1 100644
--- a/nashorn/.hgtags
+++ b/nashorn/.hgtags
@@ -353,3 +353,4 @@ ba21793a0e4816283cc0ecdab5142a4959363529 jdk-9+114
5267e91811614bac129817e566f730e9d63cf22a jdk-9+117
05679aac2f7ec3d8dd2a96d7e7899906224bf5cf jdk-9+118
621ad507bf9b07e7c6da2150aa619fe7e78ec5a0 jdk-9+119
+7ab7fc00b147e5b50d6bd5516147680f11c0b165 jdk-9+120
diff --git a/nashorn/samples/test.js b/nashorn/samples/test.js
index dfe4b7b937a..217cab164ba 100644
--- a/nashorn/samples/test.js
+++ b/nashorn/samples/test.js
@@ -31,4 +31,4 @@
print("Hello World");
var System = Java.type("java.lang.System");
-print(System.getProperty("jdk.launcher.patch.0"));
+print(System.getProperty("java.home"));
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java
index b2090dcca6b..0fb867f91ce 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java
@@ -238,7 +238,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
@Override
public MethodHandle call() {
return Bootstrap.createDynamicCallInvoker(double.class,
- ScriptFunction.class, Object.class, Object.class, Object.class);
+ Object.class, Object.class, Object.class, Object.class);
}
});
}
@@ -1210,23 +1210,23 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
return copy;
}
- private static ScriptFunction compareFunction(final Object comparefn) {
+ private static Object compareFunction(final Object comparefn) {
if (comparefn == ScriptRuntime.UNDEFINED) {
return null;
}
- if (! (comparefn instanceof ScriptFunction)) {
+ if (!Bootstrap.isCallable(comparefn)) {
throw typeError("not.a.function", ScriptRuntime.safeToString(comparefn));
}
- return (ScriptFunction)comparefn;
+ return comparefn;
}
private static Object[] sort(final Object[] array, final Object comparefn) {
- final ScriptFunction cmp = compareFunction(comparefn);
+ final Object cmp = compareFunction(comparefn);
final List list = Arrays.asList(array);
- final Object cmpThis = cmp == null || cmp.isStrict() ? ScriptRuntime.UNDEFINED : Global.instance();
+ final Object cmpThis = cmp == null || Bootstrap.isStrictCallable(cmp) ? ScriptRuntime.UNDEFINED : Global.instance();
try {
Collections.sort(list, new Comparator() {
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSON.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSON.java
index b5e139c79bc..b8141a9b5fb 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSON.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSON.java
@@ -47,7 +47,6 @@ import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.JSONFunctions;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java
index 3b5998063af..3bf1663933a 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java
@@ -45,7 +45,6 @@ import jdk.nashorn.internal.runtime.BitVector;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ParserException;
import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
@@ -655,7 +654,7 @@ public final class NativeRegExp extends ScriptObject {
* @param replacement Replacement string.
* @return String with substitutions.
*/
- String replace(final String string, final String replacement, final ScriptFunction function) throws Throwable {
+ String replace(final String string, final String replacement, final Object function) throws Throwable {
final RegExpMatcher matcher = regexp.match(string);
if (matcher == null) {
@@ -671,7 +670,7 @@ public final class NativeRegExp extends ScriptObject {
sb.append(string, 0, matcher.start());
if (function != null) {
- final Object self = function.isStrict() ? UNDEFINED : Global.instance();
+ final Object self = Bootstrap.isStrictCallable(function) ? UNDEFINED : Global.instance();
sb.append(callReplaceValue(getReplaceValueInvoker(), function, self, matcher, string));
} else {
appendReplacement(matcher, string, replacement, sb);
@@ -691,7 +690,7 @@ public final class NativeRegExp extends ScriptObject {
final StringBuilder sb = new StringBuilder();
final MethodHandle invoker = function == null ? null : getReplaceValueInvoker();
- final Object self = function == null || function.isStrict() ? UNDEFINED : Global.instance();
+ final Object self = function == null || Bootstrap.isStrictCallable(function) ? UNDEFINED : Global.instance();
do {
sb.append(string, thisIndex, matcher.start());
@@ -807,12 +806,12 @@ public final class NativeRegExp extends ScriptObject {
new Callable() {
@Override
public MethodHandle call() {
- return Bootstrap.createDynamicCallInvoker(String.class, ScriptFunction.class, Object.class, Object[].class);
+ return Bootstrap.createDynamicCallInvoker(String.class, Object.class, Object.class, Object[].class);
}
});
}
- private String callReplaceValue(final MethodHandle invoker, final ScriptFunction function, final Object self, final RegExpMatcher matcher, final String string) throws Throwable {
+ private String callReplaceValue(final MethodHandle invoker, final Object function, final Object self, final RegExpMatcher matcher, final String string) throws Throwable {
final Object[] groups = groups(matcher);
final Object[] args = Arrays.copyOf(groups, groups.length + 2);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeString.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeString.java
index 33e087bde80..ec1619e1b88 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeString.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeString.java
@@ -58,10 +58,10 @@ import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.OptimisticBuiltins;
import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
import jdk.nashorn.internal.runtime.linker.NashornGuards;
import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
@@ -743,8 +743,8 @@ public final class NativeString extends ScriptObject implements OptimisticBuilti
nativeRegExp = NativeRegExp.flatRegExp(JSType.toString(string));
}
- if (replacement instanceof ScriptFunction) {
- return nativeRegExp.replace(str, "", (ScriptFunction)replacement);
+ if (Bootstrap.isCallable(replacement)) {
+ return nativeRegExp.replace(str, "", replacement);
}
return nativeRegExp.replace(str, JSType.toString(replacement), null);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakMap.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakMap.java
index 6e11734e20a..7b08a78f807 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakMap.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakMap.java
@@ -31,7 +31,6 @@ import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
-import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakSet.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakSet.java
index 19e5f1c8405..fb27bffc7a7 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakSet.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakSet.java
@@ -31,7 +31,6 @@ import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
-import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSONFunctions.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSONFunctions.java
index 5f56c364c6b..32cdc09d661 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSONFunctions.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSONFunctions.java
@@ -46,7 +46,7 @@ public final class JSONFunctions {
@Override
public MethodHandle call() {
return Bootstrap.createDynamicCallInvoker(Object.class,
- ScriptFunction.class, ScriptObject.class, String.class, Object.class);
+ Object.class, Object.class, String.class, Object.class);
}
});
}
@@ -90,16 +90,16 @@ public final class JSONFunctions {
// apply 'reviver' function if available
private static Object applyReviver(final Global global, final Object unfiltered, final Object reviver) {
- if (reviver instanceof ScriptFunction) {
+ if (Bootstrap.isCallable(reviver)) {
final ScriptObject root = global.newObject();
root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
- return walk(root, "", (ScriptFunction)reviver);
+ return walk(root, "", reviver);
}
return unfiltered;
}
// This is the abstract "Walk" operation from the spec.
- private static Object walk(final ScriptObject holder, final Object name, final ScriptFunction reviver) {
+ private static Object walk(final ScriptObject holder, final Object name, final Object reviver) {
final Object val = holder.get(name);
if (val instanceof ScriptObject) {
final ScriptObject valueObj = (ScriptObject)val;
@@ -131,7 +131,7 @@ public final class JSONFunctions {
try {
// Object.class, ScriptFunction.class, ScriptObject.class, String.class, Object.class);
- return getREVIVER_INVOKER().invokeExact(reviver, holder, JSType.toString(name), val);
+ return getREVIVER_INVOKER().invokeExact(reviver, (Object)holder, JSType.toString(name), val);
} catch(Error|RuntimeException t) {
throw t;
} catch(final Throwable t) {
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java
index 9648da3e0f2..cdbbb0fea22 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java
@@ -171,7 +171,9 @@ public final class Bootstrap {
return ((JSObject)callable).isStrictFunction();
} else if (callable instanceof BoundCallable) {
return isStrictCallable(((BoundCallable)callable).getCallable());
- } else if (BeansLinker.isDynamicMethod(callable) || callable instanceof StaticClass) {
+ } else if (BeansLinker.isDynamicMethod(callable) ||
+ callable instanceof StaticClass ||
+ isFunctionalInterfaceObject(callable)) {
return false;
}
throw notFunction(callable);
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
index b81cd2add9e..d2a46eae78f 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
@@ -186,7 +186,7 @@ public class NashornBeansLinker implements GuardingDynamicLinker {
if (iface.isAnnotationPresent(FunctionalInterface.class)) {
// return the first abstract method
for (final Method m : iface.getMethods()) {
- if (Modifier.isAbstract(m.getModifiers())) {
+ if (Modifier.isAbstract(m.getModifiers()) && !isOverridableObjectMethod(m)) {
return m.getName();
}
}
@@ -197,6 +197,23 @@ public class NashornBeansLinker implements GuardingDynamicLinker {
return findFunctionalInterfaceMethodName(clazz.getSuperclass());
}
+ // is this an overridable java.lang.Object method?
+ private static boolean isOverridableObjectMethod(final Method m) {
+ switch (m.getName()) {
+ case "equals":
+ if (m.getReturnType() == boolean.class) {
+ final Class>[] params = m.getParameterTypes();
+ return params.length == 1 && params[0] == Object.class;
+ }
+ return false;
+ case "hashCode":
+ return m.getReturnType() == int.class && m.getParameterCount() == 0;
+ case "toString":
+ return m.getReturnType() == String.class && m.getParameterCount() == 0;
+ }
+ return false;
+ }
+
// Returns @FunctionalInterface annotated interface's single abstract
// method name. If not found, returns null.
static String getFunctionalInterfaceMethodName(final Class> clazz) {
diff --git a/nashorn/test/script/basic/JDK-8157680.js b/nashorn/test/script/basic/JDK-8157680.js
new file mode 100644
index 00000000000..02c868ecfcd
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8157680.js
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8157680: Callback parameter of any JS builtin implementation should accept any Callable
+ *
+ * @option -scripting
+ * @test
+ * @run
+ */
+
+var SM = Java.type("javax.script.ScriptEngineManager")
+var engine = new SM().getEngineByName("nashorn")
+
+engine.put("output", print);
+var reviver = engine.eval(< " + value)
+ return value
+ }
+})
+
+// compare function from the mirror world
+var arr = [34,567,-3, 53].sort(engine.eval(< y)? 1 : 0)
+EOF))
+print(arr)
+
+// compare function as a JSObject function
+arr = [34,57,-3, 53, 670, 33].sort(new AJO() {
+ isFunction: function() true,
+ call: function(thiz, args) {
+ var x = args[0], y = args[1]
+ return x < y? -1 : ((x > y)? 1 : 0)
+ }
+})
+print(arr)
+
+// replacer function from mirror world
+var str = "hello".replace(/l/g, engine.eval(< hello
+-3,34,53,567
+-3,33,34,53,57,670
+he__o
+hELLo
diff --git a/nashorn/test/script/basic/JDK-8157819.js b/nashorn/test/script/basic/JDK-8157819.js
new file mode 100644
index 00000000000..869aa15f8d2
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8157819.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8157819: TypeError when a java.util.Comparator object is invoked as a function
+ *
+ * @test
+ * @run
+ */
+
+var compare = java.util.Comparator.naturalOrder()
+Assert.assertTrue(compare("nashorn", "ecmascript") > 0)
+Assert.assertTrue(compare("abc", "xyz") < 0)
+Assert.assertTrue(compare("hello", "hello") == 0)
+
+var rcompare = java.util.Comparator.reverseOrder()
+Assert.assertTrue(rcompare("nashorn", "ecmascript") < 0)
+Assert.assertTrue(rcompare("abc", "xyz") > 0)
+Assert.assertTrue(rcompare("hello", "hello") == 0)
+
+var arr = [ "nashorn", "JavaScript", "ECMAScript", "ecmascript", "js" ]
+Assert.assertEquals(arr.sort(compare).join(),
+ "ECMAScript,JavaScript,ecmascript,js,nashorn")
+Assert.assertEquals(arr.sort(rcompare).join(),
+ "nashorn,js,ecmascript,JavaScript,ECMAScript")
+