aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxiaofeya <unknown>2018-08-09 15:42:48 +0800
committerbell-sw <liberica@bell-sw.com>2019-04-20 16:52:24 +0300
commit2a46ffd5c30a25dd2d91c2d27e6b1d849b4ccd97 (patch)
tree151489c539dccc22c784e11dcf8ceb310f3e5e2c
parentb20165cd1846e5d312f12e239b272f0d39a4b661 (diff)
downloadjdk8u_jdk-2a46ffd5c30a25dd2d91c2d27e6b1d849b4ccd97.tar.gz
8208656: Move java/util/Calendar/CalendarTestScripts tests into OpenJDK
Reviewed-by: naoto
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/CalendarAdapter.java437
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/CalendarTestEngine.java782
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/CalendarTestException.java36
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/Exceptions.java46
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/GregorianAdapter.java125
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/JapaneseRollDayOfWeekTestGenerator.java131
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/JapaneseRollTests.java88
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/JapaneseTests.java100
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/README566
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/Result.java53
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/Symbol.java328
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/Variable.java76
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/japanese/japanese.cts331
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/japanese/japanese_add.cts521
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/japanese/japanese_exceptions.cts204
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/japanese/japanese_minmax.cts336
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/japanese/japanese_normalization.cts97
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/japanese/japanese_roll.cts556
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/params/lenient.cts5
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/params/non-lenient.cts5
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/timezones/tz_japan.cts5
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/timezones/tz_novosibirsk.cts5
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/timezones/tz_pst.cts5
-rw-r--r--test/java/util/Calendar/CalendarTestScripts/timezones/tz_sydney.cts5
24 files changed, 4843 insertions, 0 deletions
diff --git a/test/java/util/Calendar/CalendarTestScripts/CalendarAdapter.java b/test/java/util/Calendar/CalendarTestScripts/CalendarAdapter.java
new file mode 100644
index 0000000000..1f3f1d0f2c
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/CalendarAdapter.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright (c) 2007, 2018, 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.Calendar;
+import sun.util.calendar.CalendarUtils;
+
+public class CalendarAdapter extends Calendar {
+ public static enum Type {
+ GREGORIAN, BUDDHIST, JAPANESE;
+ }
+
+ 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"
+ };
+
+ Calendar cal;
+ GregorianAdapter gcal;
+ private Type type;
+
+ public CalendarAdapter(Calendar cal) {
+ if (cal == null)
+ throw new NullPointerException();
+
+ this.cal = cal;
+ if (cal instanceof sun.util.BuddhistCalendar) {
+ type = Type.BUDDHIST;
+ } else if (cal instanceof GregorianAdapter) {
+ type = Type.GREGORIAN;
+ gcal = (GregorianAdapter) cal;
+ } else {
+ type = Type.JAPANESE;
+ }
+ }
+
+ public void setFirstDayOfWeek(int w) {
+ cal.setFirstDayOfWeek(w);
+ }
+
+ public int getFirstDayOfWeek() {
+ return cal.getFirstDayOfWeek();
+ }
+
+ public void setMinimalDaysInFirstWeek(int value) {
+ cal.setMinimalDaysInFirstWeek(value);
+ }
+
+ public int getMinimalDaysInFirstWeek() {
+ return getMinimalDaysInFirstWeek();
+ }
+
+ public long getTimeInMillis() {
+ return cal.getTimeInMillis();
+ }
+
+ public void setTimeInMillis(long millis) {
+ cal.setTimeInMillis(millis);
+ }
+
+ public int get(int field) {
+ return cal.get(field);
+ }
+
+ public void set(int field, int value) {
+ cal.set(field, value);
+ }
+
+ public void add(int field, int amount) {
+ cal.add(field, amount);
+ }
+
+ public void roll(int field, boolean dir) {
+ cal.roll(field, dir);
+ }
+
+ public void roll(int field, int amount) {
+ cal.roll(field, amount);
+ }
+
+ public void setDate(int year, int month, int date)
+ {
+ cal.set(year, month, date);
+ }
+
+ public void setDate(int era, int year, int month, int date) {
+ cal.set(ERA, era);
+ cal.set(year, month, date);
+ }
+
+ public void setDateTime(int year, int month, int date, int hourOfDay, int minute, int second)
+ {
+ cal.set(year, month, date, hourOfDay, minute, second);
+ }
+
+ public void clearAll() {
+ cal.clear();
+ }
+
+ public void clearField(int field)
+ {
+ cal.clear(field);
+ }
+
+ public boolean isSetField(int field)
+ {
+ return cal.isSet(field);
+ }
+
+ public int getMaximum(int field) {
+ return cal.getMaximum(field);
+ }
+
+ public int getLeastMaximum(int field) {
+ return cal.getLeastMaximum(field);
+ }
+
+ public int getActualMaximum(int field) {
+ return cal.getActualMaximum(field);
+ }
+
+ public int getMinimum(int field) {
+ return cal.getMinimum(field);
+ }
+
+ public int getGreatestMinimum(int field) {
+ return cal.getGreatestMinimum(field);
+ }
+
+ public int getActualMinimum(int field) {
+ return cal.getActualMinimum(field);
+ }
+
+ public void setLenient(boolean lenient) {
+ cal.setLenient(lenient);
+ }
+
+ public String toString() {
+ return cal.toString();
+ }
+
+ protected void computeFields() {
+ }
+
+ protected void computeTime() {
+ }
+
+ void setTimeOfDay(int hourOfDay, int minute, int second, int ms) {
+ cal.set(HOUR_OF_DAY, hourOfDay);
+ cal.set(MINUTE, minute);
+ cal.set(SECOND, second);
+ cal.set(MILLISECOND, ms);
+ }
+
+ // GregorianAdapter specific methods
+
+ // When gcal is null, the methods throw a NPE.
+
+ int getSetStateFields() {
+ return gcal.getSetStateFields();
+ }
+
+ int[] getFields() {
+ return gcal.getFields();
+ }
+
+ boolean checkInternalDate(int year, int month, int dayOfMonth) {
+ return gcal.checkInternalDate(year, month, dayOfMonth);
+ }
+
+ boolean checkInternalDate(int year, int month, int dayOfMonth, int dayOfWeek) {
+ return gcal.checkInternalDate(year, month, dayOfMonth, dayOfWeek);
+ }
+
+ boolean checkInternalField(int field, int expectedValue) {
+ return checkInternalField(field, expectedValue);
+ }
+
+ // check methods
+
+ boolean checkAllSet() {
+ initTest();
+ for (int i = 0; i < FIELD_COUNT; i++) {
+ checkFieldState(i, true);
+ }
+ return getStatus();
+ }
+
+ boolean checkMaximum(int field, int expectedValue) {
+ int val;
+ if ((val = getMaximum(field)) != expectedValue) {
+ appendMessage("getMaximum("+FIELD_NAMES[field]+"): got " + val
+ + " expected " + expectedValue);
+ }
+ 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 checkMinimum(int field, int expectedValue) {
+ int val;
+ if ((val = getMinimum(field)) != expectedValue) {
+ appendMessage("getMinimum("+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();
+ checkField(YEAR, year);
+ checkField(MONTH, month);
+ checkField(DAY_OF_MONTH, dayOfMonth);
+ return getStatus();
+ }
+
+ boolean checkDate(int era, int year, int month, int dayOfMonth) {
+ initTest();
+ checkField(ERA, era);
+ checkField(YEAR, year);
+ checkField(MONTH, month);
+ checkField(DAY_OF_MONTH, dayOfMonth);
+ return getStatus();
+ }
+
+ boolean checkDateTime(int year, int month, int dayOfMonth,
+ int hourOfDay, int minute, int second) {
+ initTest();
+ checkField(YEAR, year);
+ checkField(MONTH, month);
+ checkField(DAY_OF_MONTH, dayOfMonth);
+ checkField(HOUR_OF_DAY, hourOfDay);
+ checkField(MINUTE, minute);
+ checkField(SECOND, second);
+ return getStatus();
+ }
+
+ boolean checkDateTime(int year, int month, int dayOfMonth,
+ int hourOfDay, int minute, int second, int ms) {
+ initTest();
+ checkField(YEAR, year);
+ checkField(MONTH, month);
+ checkField(DAY_OF_MONTH, dayOfMonth);
+ checkField(HOUR_OF_DAY, hourOfDay);
+ checkField(MINUTE, minute);
+ checkField(SECOND, second);
+ checkField(MILLISECOND, ms);
+ return getStatus();
+ }
+
+ boolean checkTimeOfDay(int hourOfDay, int minute, int second, int ms) {
+ initTest();
+ checkField(HOUR_OF_DAY, hourOfDay);
+ checkField(MINUTE, minute);
+ checkField(SECOND, second);
+ checkField(MILLISECOND, ms);
+ return getStatus();
+ }
+
+ boolean checkMillis(long millis) {
+ initTest();
+ long t = cal.getTimeInMillis();
+ if (t != millis) {
+ appendMessage("wrong millis: got " + t + ", expected " + millis);
+ return false;
+ }
+ return true;
+ }
+
+ boolean checkFieldState(int field, boolean expectedState) {
+ if (isSet(field) != expectedState) {
+ appendMessage(FIELD_NAMES[field] + " state is not " + expectedState + "; ");
+ return false;
+ }
+ return true;
+ }
+
+ boolean checkField(int field, int expectedValue) {
+ int val;
+ if ((val = get(field)) != expectedValue) {
+ appendMessage("get(" + FIELD_NAMES[field] + "): got " + val +
+ ", expected " + expectedValue + "; ");
+ return false;
+ }
+ return true;
+ }
+
+ static final String fieldName(int field) {
+ return FIELD_NAMES[field];
+ }
+
+ String toDateString() {
+ StringBuffer sb = new StringBuffer();
+ String[] eraNames = null;
+ switch (type) {
+ case GREGORIAN:
+ eraNames = new String[] { "BCE", "" };
+ break;
+
+ case BUDDHIST:
+ eraNames = new String[] { "Before BE", "BE"};
+ break;
+
+ case JAPANESE:
+ eraNames = new String[] {
+ "BeforeMeiji",
+ "Meiji",
+ "Taisho",
+ "Showa",
+ "Heisei",
+ "NewEra"
+ };
+ break;
+ }
+
+ sb.append(eraNames[cal.get(ERA)]);
+ if (sb.length() > 0)
+ sb.append(' ');
+ CalendarUtils.sprintf0d(sb, cal.get(YEAR), 4).append('-');
+ CalendarUtils.sprintf0d(sb, cal.get(MONTH)+1, 2).append('-');
+ CalendarUtils.sprintf0d(sb, cal.get(DAY_OF_MONTH), 2);
+ return sb.toString();
+ }
+
+ String toTimeString() {
+ StringBuffer sb = new StringBuffer();
+ CalendarUtils.sprintf0d(sb, cal.get(HOUR_OF_DAY), 2).append(':');
+ CalendarUtils.sprintf0d(sb, cal.get(MINUTE), 2).append(':');
+ CalendarUtils.sprintf0d(sb, cal.get(SECOND),2 ).append('.');
+ CalendarUtils.sprintf0d(sb, cal.get(MILLISECOND), 3);
+ int zoneOffset = cal.get(ZONE_OFFSET) + cal.get(DST_OFFSET);
+ if (zoneOffset == 0) {
+ sb.append('Z');
+ } else {
+ int offset;
+ char sign;
+ if (zoneOffset > 0) {
+ offset = zoneOffset;
+ sign = '+';
+ } else {
+ offset = -zoneOffset;
+ sign = '-';
+ }
+ offset /= 60000;
+ sb.append(sign);
+ CalendarUtils.sprintf0d(sb, offset / 60, 2);
+ CalendarUtils.sprintf0d(sb, offset % 60, 2);
+ }
+ return sb.toString();
+ }
+
+ String toDateTimeString() {
+ return toDateString() + "T" + toTimeString();
+ }
+
+ // Message handling
+
+ StringBuffer msg = new StringBuffer();
+
+ private void initTest() {
+ msg = new StringBuffer();
+ }
+
+ String getMessage() {
+ String s = msg.toString();
+ msg = new StringBuffer();
+ return " " + s;
+ }
+
+ private void setMessage(String msg) {
+ this.msg = new StringBuffer(msg);
+ }
+
+ private void appendMessage(String msg) {
+ this.msg.append(msg);
+ }
+
+ boolean getStatus() {
+ return msg.length() == 0;
+ }
+}
diff --git a/test/java/util/Calendar/CalendarTestScripts/CalendarTestEngine.java b/test/java/util/Calendar/CalendarTestScripts/CalendarTestEngine.java
new file mode 100644
index 0000000000..05359952e1
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/CalendarTestEngine.java
@@ -0,0 +1,782 @@
+/*
+ * Copyright (c) 2007, 2018, 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.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.*;
+
+public class CalendarTestEngine {
+ private static File file;
+ private static BufferedReader in;
+ private static int testCount;
+ private static int lineno;
+ private static Locale locale;
+ private static TimeZone timezone;
+ private static boolean leniency = true;
+
+ public static void main(String[] args) throws Exception {
+ Locale loc = Locale.getDefault();
+ TimeZone tz = TimeZone.getDefault();
+ locale = loc;
+ timezone = tz;
+ try {
+ for (String arg : args) {
+ file = new File(arg);
+ FileInputStream fis = new FileInputStream(file);
+ System.out.println("Starting " + file.getName() + "...");
+ in = new BufferedReader(new InputStreamReader(fis));
+ testCount = lineno = 0;
+ run();
+ System.out.println("Completed " + file.getName());
+ }
+ } finally {
+ Locale.setDefault(loc);
+ TimeZone.setDefault(tz);
+ }
+ }
+
+ private static void run() throws Exception {
+ String line;
+ int section = 0;
+ Map<String, CalendarAdapter> cals = new HashMap<String, CalendarAdapter>();
+ CalendarAdapter calendar = null;
+ Result result = new Result();
+
+ while ((line = in.readLine()) != null) {
+ lineno++;
+ line = line.trim();
+ // Skip blank and comment lines
+ if (line.length() == 0 || line.charAt(0) == '#') {
+ continue;
+ }
+ int comment = line.indexOf('#');
+ if (comment != -1) {
+ line = line.substring(0, comment).trim();
+ }
+ Scanner sc = new Scanner(line);
+ String token = sc.next();
+ Symbol operation = symbol(token);
+ if (operation == null) {
+ throw new RuntimeException(lineno() + "wrong op? " + token);
+ }
+
+
+ if (operation.type == Symbol.Type.EXCEPTION) {
+ String className = sc.next();
+ Class clazz = Exceptions.get(className);
+ Exception e = result.getException();
+ if (!clazz.isInstance(e)) {
+ throw new RuntimeException(lineno() + "unexpected exception: got: " + e
+ + ", expected=" + clazz);
+ }
+ }
+
+ Exception x = result.getException();
+ if (x != null) {
+ throw new RuntimeException(lineno(result.getLineno()) + "Unexpected exception", x);
+ }
+
+ try {
+ switch (operation.type) {
+ case LOCALE:
+ {
+ String lang = sc.next();
+ String country = "", var = "";
+ if (sc.hasNext()) {
+ country = sc.next();
+ if (sc.hasNext()) {
+ var = sc.next();
+ }
+ }
+ locale = new Locale(lang, country, var);
+ }
+ break;
+
+ case TIMEZONE:
+ {
+ if (sc.hasNext()) {
+ String id = sc.next();
+ timezone = TimeZone.getTimeZone(id);
+ if (!timezone.getID().equals(id)) {
+ System.err.printf("Warning: line %d: may get wrong time zone? "
+ +"(specified: %s vs. actual: %s)%n",
+ lineno, id, timezone.getID());
+ }
+ }
+ }
+ break;
+
+ case NEW:
+ {
+ Symbol op = symbol(sc.next());
+ Calendar cal = null;
+ switch (op.type) {
+ case INSTANCE:
+ cal = Calendar.getInstance(timezone, locale);
+ break;
+ case GREGORIAN:
+ cal = new GregorianAdapter(timezone, locale);
+ break;
+ default:
+ symbolError(op);
+ break;
+ }
+ cal.setLenient(leniency);
+ calendar = new CalendarAdapter(cal);
+ if (sc.hasNext()) {
+ String name = sc.next();
+ cals.put(name.toLowerCase(Locale.ROOT), calendar);
+ if (!leniency) {
+ System.out.printf("%s%s is non-lenient%n", lineno(), name);
+ }
+ } else {
+ throw new RuntimeException(lineno() + "Missing associated name");
+ }
+ }
+ break;
+
+ case TEST:
+ testCount++;
+ if (sc.hasNext()) {
+ System.out.printf("Test#%d:%s%n", testCount, sc.findInLine(".+"));
+ } else {
+ System.out.printf("Test#%d:%n", testCount);
+ }
+ break;
+
+ case USE:
+ {
+ String name = sc.next().toLowerCase(Locale.ROOT);
+ CalendarAdapter c = cals.get(name);
+ if (c == null) {
+ throw new CalendarTestException(lineno() + "calendar " + name
+ + " not found.");
+ }
+ calendar = c;
+ }
+ break;
+
+ case ASSIGN:
+ {
+ long v = getLong(sc);
+ String to = sc.next().toLowerCase(Locale.ROOT);
+ boolean assign = true;
+ if (sc.hasNext()) {
+ Symbol condition = symbol(sc.next());
+ if (condition.type == Symbol.Type.IF) {
+ long v1 = getLong(sc);
+ Symbol op = symbol(sc.next());
+ long v2 = getLong(sc);
+ assign = relation(v1, op, v2);
+ } else {
+ symbolError(condition);
+ }
+ }
+ if (assign)
+ Variable.newVar(to, v);
+ }
+ break;
+
+ case EVAL:
+ {
+ long v1 = getLong(sc);
+ String op = sc.next();
+ Symbol operator = symbol(op);
+ if (operator == null) {
+ throw new RuntimeException("op " + op + " invalid");
+ }
+ long v2 = getLong(sc);
+ if (operator.isArithmetic()) {
+ long value = 0;
+ switch (operator.type) {
+ case PLUS:
+ value = v1 + v2;
+ break;
+
+ case MINUS:
+ value = v1 - v2;
+ break;
+
+ case MULTIPLY:
+ value = v1 * v2;
+ break;
+
+ case DIVIDE:
+ value = v1 / v2;
+ break;
+
+ case MOD:
+ value = v1 % v2;
+ break;
+
+ default:
+ symbolError(operator);
+ break;
+ }
+ result.setValue(value);
+ } else {
+ if (!relation(v1, operator, v2)) {
+ throw new RuntimeException("not " + v1 + " " + op + " " + v2);
+ }
+ }
+ }
+ break;
+
+ case CLEAR:
+ {
+ Symbol sym = symbol(sc.next());
+ if (sym.type == Symbol.Type.ALL) {
+ calendar.clearAll();
+ } else if (sym.type == Symbol.Type.FIELD) {
+ int f = sym.value();
+ calendar.clearField(f);
+ } else {
+ symbolError(sym);
+ }
+ }
+ break;
+
+ case GET:
+ {
+ Symbol sym = symbol(sc.next());
+ switch (sym.type) {
+ case FIELD:
+ {
+ int f = sym.value();
+ int v = calendar.get(f);
+ result.setValue(v);
+ }
+ break;
+
+ case MILLIS:
+ {
+ long v = calendar.getTimeInMillis();
+ result.setValue(v);
+ }
+ break;
+
+ case MINIMUM:
+ {
+ int f = getInt(sc);
+ int v = calendar.getMinimum(f);
+ result.setValue(v);
+ }
+ break;
+
+ case GREATESTMINIMUM:
+ {
+ int f = getInt(sc);
+ int v = calendar.getGreatestMinimum(f);
+ result.setValue(v);
+ }
+ break;
+
+ case ACTUALMINIMUM:
+ {
+ int f = getInt(sc);
+ int v = calendar.getActualMinimum(f);
+ result.setValue(v);
+ }
+ break;
+
+ case MAXIMUM:
+ {
+ int f = getInt(sc);
+ int v = calendar.getMaximum(f);
+ result.setValue(v);
+ }
+ break;
+
+ case LEASTMAXIMUM:
+ {
+ int f = getInt(sc);
+ int v = calendar.getLeastMaximum(f);
+ result.setValue(v);
+ }
+ break;
+
+ case ACTUALMAXIMUM:
+ {
+ int f = getInt(sc);
+ int v = calendar.getActualMaximum(f);
+ result.setValue(v);
+ }
+ break;
+
+ case FIRSTDAYOFWEEK:
+ {
+ result.setValue(calendar.getFirstDayOfWeek());
+ }
+ break;
+
+ case MINIMALDAYSINFIRSTWEEK:
+ {
+ int v = calendar.getMinimalDaysInFirstWeek();
+ result.setValue(v);
+ }
+ break;
+
+ default:
+ symbolError(sym);
+ break;
+ }
+ }
+ break;
+
+ case ADD:
+ case ROLL:
+ {
+ Symbol sym = symbol(sc.next());
+ if (sym.type == Symbol.Type.FIELD) {
+ int f = sym.value();
+ int v = sc.nextInt();
+ switch (operation.type) {
+ case ADD:
+ calendar.add(f, v);
+ break;
+
+ case ROLL:
+ calendar.roll(f, v);
+ break;
+ }
+ } else {
+ symbolError(sym);
+ }
+ }
+ break;
+
+ case SET:
+ {
+ Symbol sym = symbol(sc.next());
+ switch (sym.type) {
+ case FIELD:
+ {
+ int f = sym.value();
+ int v = getInt(sc);
+ calendar.set(f, v);
+ }
+ break;
+
+ case MILLIS:
+ {
+ long v = getLong(sc);
+ calendar.setTimeInMillis(v);
+ }
+ break;
+
+ case DATE:
+ {
+ int a = getInt(sc);
+ int b = getInt(sc);
+ int c = getInt(sc);
+ if (sc.hasNext()) {
+ int d = getInt(sc);
+ // era, year, month, dayOfMonth
+ calendar.setDate(a, b, c, d);
+ } else {
+ // year, month, dayOfMonth
+ calendar.setDate(a, b, c);
+ }
+ }
+ break;
+
+ case DATETIME:
+ {
+ int y = getInt(sc);
+ int m = getInt(sc);
+ int d = getInt(sc);
+ int hh = getInt(sc);
+ int mm = getInt(sc);
+ int ss = getInt(sc);
+ calendar.setDateTime(y, m, d, hh, mm, ss);
+ }
+ break;
+
+ case TIMEOFDAY:
+ {
+ int hh = getInt(sc);
+ int mm = getInt(sc);
+ int ss = getInt(sc);
+ int ms = getInt(sc);
+ calendar.setTimeOfDay(hh, mm, ss, ms);
+ }
+ break;
+
+ case FIRSTDAYOFWEEK:
+ {
+ int v = getInt(sc);
+ calendar.setFirstDayOfWeek(v);
+ }
+ break;
+
+ case MINIMALDAYSINFIRSTWEEK:
+ {
+ int v = getInt(sc);
+ calendar.setMinimalDaysInFirstWeek(v);
+ }
+ break;
+
+ case LENIENT:
+ if (calendar != null) {
+ calendar.setLenient(true);
+ }
+ leniency = true;
+ break;
+
+ case NONLENIENT:
+ if (calendar != null) {
+ calendar.setLenient(false);
+ }
+ leniency = false;
+ break;
+
+ default:
+ symbolError(sym);
+ }
+ if (sc.hasNext()) {
+ throw new RuntimeException(lineno() + "extra param(s) "
+ + sc.findInLine(".+"));
+ }
+ }
+ break;
+
+ case CHECK:
+ {
+ Symbol sym = symbol(sc.next());
+ boolean stat = false;
+ switch (sym.type) {
+ case MILLIS:
+ {
+ long millis = getLong(sc);
+ stat = calendar.checkMillis(millis);
+ }
+ break;
+
+ case FIELD:
+ {
+ int f = sym.value();
+ int v = getInt(sc);
+ stat = calendar.checkField(f, v);
+ }
+ break;
+
+ case DATE:
+ {
+ int a = getInt(sc);
+ int b = getInt(sc);
+ int c = getInt(sc);
+ if (sc.hasNext()) {
+ int d = getInt(sc);
+ // era year month dayOfMonth
+ stat = calendar.checkDate(a, b, c, d);
+ } else {
+ // year month dayOfMonth
+ stat = calendar.checkDate(a, b, c);
+ }
+ }
+ break;
+
+ case DATETIME:
+ {
+ int y = getInt(sc);
+ int m = getInt(sc);
+ int d = getInt(sc);
+ int hh = getInt(sc);
+ int mm = getInt(sc);
+ int ss = getInt(sc);
+ if (sc.hasNext()) {
+ int ms = getInt(sc);
+ stat = calendar.checkDateTime(y, m, d, hh, mm, ss, ms);
+ } else {
+ stat = calendar.checkDateTime(y, m, d, hh, mm, ss);
+ }
+ }
+ break;
+
+ case TIMEOFDAY:
+ {
+ int hh = sc.nextInt();
+ int mm = sc.nextInt();
+ int ss = sc.nextInt();
+ int millis = sc.nextInt();
+ stat = calendar.checkTimeOfDay(hh, mm, ss, millis);
+ }
+ break;
+
+ case MINIMUM:
+ {
+ int f = getInt(sc);
+ int v = getInt(sc);
+ stat = calendar.checkMinimum(f, v);
+ }
+ break;
+
+ case GREATESTMINIMUM:
+ {
+ int f = getInt(sc);
+ int v = getInt(sc);
+ stat = calendar.checkGreatestMinimum(f, v);
+ }
+ break;
+
+ case ACTUALMINIMUM:
+ {
+ int f = getInt(sc);
+ int v = getInt(sc);
+ stat = calendar.checkActualMinimum(f, v);
+ }
+ break;
+
+ case MAXIMUM:
+ {
+ int f = getInt(sc);
+ int v = getInt(sc);
+ stat = calendar.checkMaximum(f, v);
+ }
+ break;
+
+ case LEASTMAXIMUM:
+ {
+ int f = getInt(sc);
+ int v = getInt(sc);
+ stat = calendar.checkLeastMaximum(f, v);
+ }
+ break;
+
+ case ACTUALMAXIMUM:
+ {
+ int f = getInt(sc);
+ int v = getInt(sc);
+ stat = calendar.checkActualMaximum(f, v);
+ }
+ break;
+
+ default:
+ throw new RuntimeException(lineno() + "Unknown operand");
+ }
+ if (!stat) {
+ throw new RuntimeException(lineno() + calendar.getMessage());
+ }
+ }
+ break;
+
+ case PRINT:
+ {
+ String s = sc.next();
+ if (s.charAt(0) == '$') {
+ Variable var = variable(s);
+ if (var == null)
+ throw new RuntimeException(lineno() + "Unknown token: " + s);
+ System.out.printf("%s%s=%d%n", lineno(), s, var.longValue());
+ break;
+ }
+
+ Symbol sym = symbol(s);
+ switch (sym.type) {
+ case INSTANCE:
+ {
+ Calendar cal = calendar;
+ String name = "current";
+ if (sc.hasNext()) {
+ name = sc.next();
+ cal = cals.get(name.toLowerCase(Locale.ROOT));
+ }
+ System.out.printf("%s%s=%s%n", lineno(), name, cal);
+ }
+ break;
+
+ case FIELD:
+ {
+ int f = sym.value();
+ String remark = "";
+ if (sc.hasNext()) {
+ remark = sc.findInLine(".+");
+ }
+ System.out.printf("%s%s=%d %s%n", lineno(), calendar.fieldName(f),
+ calendar.get(f), remark);
+ }
+ break;
+
+ case MILLIS:
+ {
+ String remark = "";
+ if (sc.hasNext()) {
+ remark = sc.findInLine(".+");
+ }
+ System.out.printf("%sMillis=%d %s%n", lineno(),
+ calendar.getTimeInMillis(), remark);
+ }
+ break;
+
+ case MINIMUM:
+ System.out.printf("%s%s=%d%n", lineno(),
+ s, calendar.getMinimum(getInt(sc)));
+ break;
+
+ case GREATESTMINIMUM:
+ System.out.printf("%s%s=%d%n", lineno(),
+ s, calendar.getGreatestMinimum(getInt(sc)));
+ break;
+
+ case ACTUALMINIMUM:
+ System.out.printf("%s%s=%d%n", lineno(),
+ s, calendar.getActualMinimum(getInt(sc)));
+ break;
+
+ case MAXIMUM:
+ System.out.printf("%s%s=%d%n", lineno(),
+ s, calendar.getMaximum(getInt(sc)));
+ break;
+
+ case LEASTMAXIMUM:
+ System.out.printf("%s%s=%d%n", lineno(),
+ s, calendar.getLeastMaximum(getInt(sc)));
+ break;
+
+ case ACTUALMAXIMUM:
+ System.out.printf("%s%s=%d%n", lineno(),
+ s, calendar.getActualMaximum(getInt(sc)));
+ break;
+
+ case DATE:
+ System.out.println(lineno() + calendar.toDateString());
+ break;
+
+ case DATETIME:
+ System.out.println(lineno() + calendar.toDateTimeString());
+ break;
+
+ case TIMEZONE:
+ System.out.println(lineno() + "timezone=" + timezone);
+ break;
+
+ case LOCALE:
+ System.out.println(lineno() + "locale=" + locale);
+ break;
+ }
+ }
+ }
+ } catch (CalendarTestException cte) {
+ throw cte;
+ } catch (NoSuchElementException nsee) {
+ throw new NoSuchElementException(lineno() + "syntax error");
+ } catch (Exception e) {
+ result.setException(e);
+ result.setLineno(lineno);
+ }
+ }
+ Exception x = result.getException();
+ if (x != null) {
+ throw new RuntimeException(lineno(result.getLineno()) + "Unexpected exception", x);
+ }
+ }
+
+ private static Symbol symbol(String s) {
+ return Symbol.get(s.toLowerCase(Locale.ROOT));
+ }
+
+ private static Variable variable(String s) {
+ return Variable.get(s.toLowerCase(Locale.ROOT));
+ }
+
+ private static int getInt(Scanner sc) {
+ if (sc.hasNextInt()) {
+ return sc.nextInt();
+ }
+
+ String s = sc.next();
+ if (s.charAt(0) == '$') {
+ Variable var = variable(s);
+ if (var == null)
+ throw new RuntimeException(lineno() + "Unknown token: " + s);
+ return var.intValue();
+ }
+ Symbol sym = symbol(s);
+ if (sym == null)
+ throw new RuntimeException(lineno() + "Unknown token: " + s);
+ return sym.value();
+ }
+
+ private static long getLong(Scanner sc) {
+ if (sc.hasNextLong()) {
+ return sc.nextLong();
+ }
+
+ String s = sc.next();
+ if (s.charAt(0) == '$') {
+ Variable var = variable(s);
+ if (var == null)
+ throw new RuntimeException(lineno() + "Unknown token: " + s);
+ return var.longValue();
+ }
+ Symbol sym = symbol(s);
+ if (sym == null)
+ throw new RuntimeException(lineno() + "Unknown token: " + s);
+ return sym.value();
+ }
+
+ private static boolean relation(long v1, Symbol relop, long v2) {
+ boolean result = false;
+ switch (relop.type) {
+ case GT:
+ result = v1 > v2;
+ break;
+
+ case GE:
+ result = v1 >= v2;
+ break;
+
+ case EQ:
+ result = v1 == v2;
+ break;
+
+ case NEQ:
+ result = v1 != v2;
+ break;
+
+ case LE:
+ result = v1 <= v2;
+ break;
+
+ case LT:
+ result = v1 < v2;
+ break;
+ }
+ return result;
+ }
+
+ private static String lineno() {
+ return lineno(lineno);
+ }
+
+ private static String lineno(int ln) {
+ return file.getName() + ":" + ln + ": ";
+ }
+
+ private static void symbolError(Symbol sym) {
+ throw new RuntimeException(lineno + ": unexpected symbol: " + sym);
+ }
+}
diff --git a/test/java/util/Calendar/CalendarTestScripts/CalendarTestException.java b/test/java/util/Calendar/CalendarTestScripts/CalendarTestException.java
new file mode 100644
index 0000000000..4c628ff4d1
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/CalendarTestException.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2007, 2018, 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.
+ */
+
+public class CalendarTestException extends RuntimeException {
+ public CalendarTestException() {
+ super();
+ }
+
+ public CalendarTestException(String msg) {
+ super(msg);
+ }
+
+ public CalendarTestException(String msg, Throwable t) {
+ super(msg, t);
+ }
+}
diff --git a/test/java/util/Calendar/CalendarTestScripts/Exceptions.java b/test/java/util/Calendar/CalendarTestScripts/Exceptions.java
new file mode 100644
index 0000000000..0ea93d21e3
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/Exceptions.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 2018, 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.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+public class Exceptions {
+ private static Map<String, Class> exceptions = new HashMap<String, Class>();
+
+ static {
+ put("nullpointerexception", NullPointerException.class);
+ put("illegalargumentexception", IllegalArgumentException.class);
+ }
+
+ private static void put(String key, Class clazz) {
+ Class c = exceptions.put(key, clazz);
+ if (c != null) {
+ throw new RuntimeException(key + " already exisits");
+ }
+ }
+
+ public static Class get(String key) {
+ return exceptions.get(key.toLowerCase(Locale.ROOT));
+ }
+}
diff --git a/test/java/util/Calendar/CalendarTestScripts/GregorianAdapter.java b/test/java/util/Calendar/CalendarTestScripts/GregorianAdapter.java
new file mode 100644
index 0000000000..9d6861f926
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/GregorianAdapter.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2007, 2018, 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.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public class GregorianAdapter extends GregorianCalendar {
+ static final int ALL_FIELDS = (1 << FIELD_COUNT) - 1;
+
+ public GregorianAdapter() {
+ super();
+ }
+
+ public GregorianAdapter(TimeZone tz) {
+ super(tz);
+ }
+
+ public GregorianAdapter(Locale loc) {
+ super(loc);
+ }
+
+ public GregorianAdapter(TimeZone tz, Locale loc) {
+ super(tz, loc);
+ }
+
+ public void computeTime() {
+ super.computeTime();
+ }
+
+ public void computeFields() {
+ super.computeFields();
+ }
+
+ public void complete() {
+ super.complete();
+ }
+
+ StringBuffer msg = new StringBuffer();
+
+ void initTest() {
+ msg = new StringBuffer();
+ }
+
+ String getMessage() {
+ String s = msg.toString();
+ msg = new StringBuffer();
+ return " " + s;
+ }
+
+ void setMessage(String msg) {
+ this.msg = new StringBuffer(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 checkInternalDate(int year, int month, int dayOfMonth) {
+ initTest();
+ checkInternalField(YEAR, year);
+ checkInternalField(MONTH, month);
+ checkInternalField(DAY_OF_MONTH, dayOfMonth);
+ return getStatus();
+ }
+
+ boolean checkInternalDate(int year, int month, int dayOfMonth, int dayOfWeek) {
+ initTest();
+ checkInternalField(YEAR, year);
+ checkInternalField(MONTH, month);
+ checkInternalField(DAY_OF_MONTH, dayOfMonth);
+ checkInternalField(DAY_OF_WEEK, dayOfWeek);
+ return getStatus();
+ }
+
+ boolean checkInternalField(int field, int expectedValue) {
+ int val;
+ if ((val = internalGet(field)) != expectedValue) {
+ appendMessage("internalGet(" + CalendarAdapter.FIELD_NAMES[field] + "): got " + val +
+ ", expected " + expectedValue + "; ");
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/test/java/util/Calendar/CalendarTestScripts/JapaneseRollDayOfWeekTestGenerator.java b/test/java/util/Calendar/CalendarTestScripts/JapaneseRollDayOfWeekTestGenerator.java
new file mode 100644
index 0000000000..92531931c9
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/JapaneseRollDayOfWeekTestGenerator.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2007, 2018, 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.PrintWriter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import static java.util.Calendar.*;
+
+
+public class JapaneseRollDayOfWeekTestGenerator {
+ private static final String[] ERAS = {
+ "BeforeMeiji", "Meiji", "Taisho", "Showa", "Heisei"
+ };
+
+ private static final String[] DAYOFWEEK = {
+ null, "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+
+ private static final int[] DAYOFMONTH = {
+ 25, 26, 27, 28, 29, 30, 31,
+ 1, 2, 3, 4, 5, 6, 7
+ };
+
+ private static final int DOM_BASE = 7;
+
+ //Usage: JapaneseRollDayOfWeekTestGenerator will generate test script into
+ // file rolldow.cts.
+ public static void generateTestScript(String[] args) throws Exception{
+ Locale.setDefault(Locale.ROOT);
+
+ //This test generator assumes that Heisei has (nYears - 1) or more years.
+ int nYears = (args.length == 1) ?
+ Math.max(3, Math.min(Integer.parseInt(args[0]), 40)) : 28;
+
+ // Start from Showa 63
+ int era = 3;
+ int year = 63;
+ Path testPath = Paths.get(System.getProperty("test.classes"));
+ String scFileName = testPath + "/rolldow.cts";
+
+ try (PrintWriter out = new PrintWriter(scFileName)){
+ out.println("locale ja JP JP\n" + "new instance jcal\n" + "use jcal");
+ for (int y = 0; y < nYears; y++) {
+ out.printf("\nTest %s %d\n", ERAS[era], year);
+ for (int fdw = SUNDAY; fdw <= SATURDAY; fdw++) {
+ int endFdw = fdw + 6;
+ if (endFdw > SATURDAY) {
+ endFdw -= 7;
+ }
+ for (int mdifw = 1; mdifw <= 7; mdifw++) {
+ int domIndex = DOM_BASE;
+ out.println(" clear all");
+ out.printf(" set FirstDayOfWeek %s\n", DAYOFWEEK[fdw]);
+ out.printf(" set MinimalDaysInFirstWeek %d\n", mdifw);
+ out.printf(" set date %s %d Jan 1\n", ERAS[era], year);
+ out.println(" get week_of_year\n" + " assign $result $woy");
+ out.println(" get day_of_week\n" + " assign $result $doy");
+
+ int gyear = year + (year >= 60 ? 1925 : 1988);
+ int next = new GregorianCalendar(gyear, JANUARY, 1).get(DAY_OF_WEEK);
+ for (int i = 0; i < 10; i++) {
+
+ out.println(" roll day_of_week 1");
+ next = nextFdw(next, fdw, endFdw);
+ if (next == fdw) {
+ domIndex -= 6;
+ } else {
+ domIndex++;
+ }
+ int dom = DAYOFMONTH[domIndex];
+ out.printf("\tcheck date %d %s %d%n", (dom >= 25) ? year - 1 : year,
+ (dom >= 25) ? "Dec" : "Jan", dom);
+ out.println("\teval $doy + 1");
+ out.println("\tassign $result $doy");
+ out.println("\tassign Sun $doy if $doy > Sat");
+ out.println("\tcheck day_of_week $doy");
+ out.println("\tcheck week_of_year $woy");
+ }
+
+ for (int i = 0; i < 10; i++) {
+ out.println("\troll day_of_week -1");
+ out.println("\teval $doy - 1");
+ out.println("\tassign $result $doy");
+ out.println("\tassign Sat $doy if $doy < Sun");
+ out.println("\tcheck day_of_week $doy");
+ out.println("\tcheck week_of_year $woy");
+ }
+ }
+ }
+
+ if (year == 64 && era == 3) {
+ era++;
+ year = 2;
+ } else {
+ year++;
+ }
+ }
+ }
+ }
+
+ private static int nextFdw(int x, int start, int end) {
+ if (x == end)
+ return start;
+ x++;
+ if (x > SATURDAY)
+ x = SUNDAY;
+ return x;
+ }
+}
diff --git a/test/java/util/Calendar/CalendarTestScripts/JapaneseRollTests.java b/test/java/util/Calendar/CalendarTestScripts/JapaneseRollTests.java
new file mode 100644
index 0000000000..611bac68e1
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/JapaneseRollTests.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2018, 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 tests Japanese Calendar.
+ * @bug 4609228
+ * @modules java.base/sun.util
+ * java.base/sun.util.calendar
+ * @compile
+ * CalendarAdapter.java
+ * CalendarTestEngine.java
+ * CalendarTestException.java
+ * Exceptions.java
+ * GregorianAdapter.java
+ * Result.java
+ * Symbol.java
+ * Variable.java
+ * JapaneseRollDayOfWeekTestGenerator.java
+ * @run main/timeout=120/othervm JapaneseRollTests
+ */
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class JapaneseRollTests {
+ private static List<String> TZ_TEST_LIST = Arrays.asList(
+ "tz_japan.cts", "tz_pst.cts");
+ private static Path srcPath = Paths.get(System.getProperty("test.src"));
+ private static Path testPath = Paths.get(System.getProperty("test.classes"));
+
+ public static void main(String[] args) throws Throwable {
+ List<String> modeList = getFileNameList("params");
+ //Test only 3 years by default
+ String[] jpyear ={"3"};
+ JapaneseRollDayOfWeekTestGenerator.generateTestScript(jpyear);
+
+ for (String tz : TZ_TEST_LIST) {
+ for(String mode:modeList){
+ String[] ts = { srcPath + "/timezones/" + tz,
+ srcPath + "/params/" + mode,
+ testPath + "/rolldow.cts"};
+
+ CalendarTestEngine.main(ts);
+ }
+ }
+ }
+
+ private static List<String> getFileNameList(String type ){
+ List<String> fileList = new ArrayList<>();
+ File dir = new File(srcPath + "/"+ type);
+ File[] testFiles = dir.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.toLowerCase().endsWith(".cts");
+ }
+ });
+ for (File f:testFiles) {
+ fileList.add(f.getName());
+ }
+
+ return fileList;
+ }
+}
diff --git a/test/java/util/Calendar/CalendarTestScripts/JapaneseTests.java b/test/java/util/Calendar/CalendarTestScripts/JapaneseTests.java
new file mode 100644
index 0000000000..e1b006fb9e
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/JapaneseTests.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2018, 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 tests Japanese Calendar.
+ * @bug 4609228
+ * @modules java.base/sun.util
+ * java.base/sun.util.calendar
+ * @compile
+ * CalendarAdapter.java
+ * CalendarTestEngine.java
+ * CalendarTestException.java
+ * Exceptions.java
+ * GregorianAdapter.java
+ * Result.java
+ * Symbol.java
+ * Variable.java
+ * @run main/othervm/timeout=120 JapaneseTests
+ */
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class JapaneseTests {
+
+ private static List<String> SET_LENIENT = Arrays.asList(
+ "japanese_minmax.cts",
+ "japanese_add.cts",
+ "japanese_roll.cts",
+ "japanese_exceptions.cts");
+ private static List<String> DEFAULT_LENIENT = Arrays.asList(
+ "japanese.cts",
+ "japanese_normalization.cts");
+
+ private static Path srcPath = Paths.get(System.getProperty("test.src"));
+
+ public static void main(String[] args) throws Throwable {
+ List<String> tzList = getFileNameList("timezones");
+ List<String> modeList = getFileNameList("params");
+
+ for (String jaTest: DEFAULT_LENIENT) {
+ for (String tz : tzList) {
+ String[] ts = { srcPath + "/timezones/" + tz,
+ srcPath + "/japanese/" + jaTest};
+ CalendarTestEngine.main(ts);
+ }
+ }
+
+ for (String jaTest: SET_LENIENT) {
+ for (String tz : tzList) {
+ for (String mode : modeList) {
+ String[] ts = { srcPath + "/timezones/" + tz,
+ srcPath + "/params/" + mode,
+ srcPath + "/japanese/" + jaTest };
+ CalendarTestEngine.main(ts);
+ }
+ }
+ }
+ }
+
+ private static List<String> getFileNameList(String type ){
+ List<String> fileList = new ArrayList<>();
+ File dir = new File(srcPath + "/"+ type);
+ File[] testFiles = dir.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.toLowerCase().endsWith(".cts");
+ }
+ });
+ for (File f:testFiles) {
+ fileList.add(f.getName());
+ }
+ return fileList;
+ }
+}
diff --git a/test/java/util/Calendar/CalendarTestScripts/README b/test/java/util/Calendar/CalendarTestScripts/README
new file mode 100644
index 0000000000..95a7f5c085
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/README
@@ -0,0 +1,566 @@
+Copyright (c) 2005, 2018, 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.
+
+ CALENDAR TEST SCRIPT
+
+ Masayoshi Okutsu
+ 2005-03-18
+
+Introduction
+------------
+
+Calendar Test Script is a simple scripting language to describe test cases
+for java.util.Calendar and its subclasses. It should be much more
+productive to use this script language than writing test programs in Java.
+
+A script looks like below.
+
+1 locale ja JP JP
+2 timezone Asia/Tokyo
+3 new instance jcal
+4 test day of week on Heisei 1 Jan 8
+5 use jcal
+6 clear all
+7 set date Heisei 1 Jan 8
+8 check day_of_week Sun
+
+The first line defines a Locale to be used for creating Calendar
+instances. Line 2 defines the current TimeZone to be Asia/Tokyo that is
+used creating Calendar instances. Line 3 creates a Calendar instance with
+the Locale and TimeZone instances. Its reference name is `jcal'. Line 4
+indicates a start point for a test case with a short test case
+description. Line 5 designates `jcal' as the current Calendar
+instance. All calendar operation commands are applied to the current
+Calendar instance. Line 6 clears all of the calendar fields (e.g., ERA,
+YEAR, MONTH, etc.). Line 7 sets the ERA, YEAR, MONTH and DAY_OF_MONTH
+fields to Heisei, 1, JANUARY and 8, respectively. Line 8 checks if the
+DAY_OF_WEEK value is SUNDAY. If it's not, then a RuntimeException is
+thrown.
+
+Script Grammar
+--------------
+
+A line is a comment, blank or command line. Any text after '#' is always
+treated as a comment and ignored, like a shell script.
+
+ # This is a comment line.
+
+A command line consists of a command and its parameters, optionally
+followed by a comment. For example,
+
+ set date Heisei 1 Jan 8 # The first day of Heisei
+
+`set' is a command to set `date' to Heisei year 1 January 8th. `Heisei' is
+a constant for the Japanese Heisei era value which is consistent with the
+Japanese imperial calendar implementation. `Jan' is a constant for
+Calendar.SUNDAY. The text after '#' is ignored.
+
+Keywords are case-insensitive.
+
+ set DAY_OF_WEEK MON
+ SET day_of_week Mon
+
+are the same thing.
+
+Lexical analysis is very simple. A command must be complete in a single
+line. Keywords and symbols must be separated by white space. For example,
+"$result+1" is parsed as one token. It must be written as "$result + 1".
+
+Variables
+---------
+
+Variables can be used in any context to store an integer value and are
+referenced in any contexts where an integer value is required. A variable
+name must start with a '$', such as `$maxyear'. The integer value is
+handled as a long.
+
+`$result' is reserved for storing a result of a get commend operation. For
+example, executing the following command:
+
+ get day_of_month
+
+sets $result to the get(Calendar.DAY_OF_MONTH) value of the current
+Calendar instance. (See NEW and USE commands for the current Calendar
+instance.)
+
+Commands
+--------
+
+The following defines each command and its syntax. Keywords are described
+in upper case below.
+
+LOCALE language [country [variant]]
+
+ Creates a Locale instance by calling new Locale(language, country,
+ variant). country and variant are optional. Defining LOCALE overrides
+ the previously defined Locale value if any. The initial Locale value
+ is Locale.getDefault().
+
+TIMEZONE tzid
+
+ Creates a TimeZone instance by calling
+ TimeZone.getTimeZone(tzid). Defining TIMEZONE overrides the previously
+ defined Locale value if any. The initial TimeZone value is
+ TimeZone.getDefault().
+
+NEW INSTANCE calendarname
+
+ Creates a Calendar instance by calling Calendar.getInstance(TimeZone,
+ Locale). TimeZone and Locale are those defined by TIMEZONE and LOCALE
+ commands (or their initial values), respectively. The instance is
+ associated with `calendarname' and becomes the current Calendar
+ instance to be used for testing.
+
+NEW GREGORIAN calendarname
+
+ Creates a Calendar instance by calling new GregorianCalendar(TimeZone,
+ Locale). TimeZone and Locale are those defined by TIMEZONE and LOCALE
+ commands (or their initial values), respectively. The instance is
+ associated with `calendarname' and becomes the current Calendar
+ instance to be used for testing.
+
+TEST [comments...]
+
+ Declares the beginning of a test case. `comments...' gives a short
+ description of a test case. (Multiple lines are not supported.) The
+ test system displays `comments...' to System.out. For example, the
+ following command:
+
+ test A test case for non-lenient mode
+
+ will output:
+
+ Test #n: A test case for non-lenient mode
+
+ where `n' is a sequence number of TEST command lines appeared in a
+ test script file.
+
+USE calendarname
+
+ Specifies the current Calendar instance to use for testing by
+ `calendarname'. If you need to use more than one Calendar instances,
+ then you have to switch those Calendar instances by the USE command.
+
+ASSIGN value variable
+
+ Assigns `value' to `variable'. `value' can be an integer literal, a
+ variable name or a constant. Examples are:
+
+ assign 2005 $year
+ assign $result $temp
+ assign Sun $Microsystems
+
+ASSIGN value variable IF condition
+
+ Assigns `value' to `variable' if `condition' is true. `condition' is a
+ relational expression as:
+
+ value1 relOp value2
+
+ `relOp' must be one of >, >=, ==, !=, <=, <.
+
+EVAL expression
+
+ Evaluates the given *simple* expression and assigns the expression
+ value to $result if `op' is one of the arithmetic operators (+, -, *,
+ /, %). If `op' is one of the relational operators (>, >=, ==, !=, <=,
+ <), then EVAL throws an exception if the expression value is false, or
+ does nothing if the value is true. Note that an operator and values
+ must be separated by white space.
+
+ The following is an example of the ASSIGN and EVAL commands usage to
+ get the next day of week value. Then, it's used to check the
+ roll(DAY_OF_WEEK) result.
+
+ get day_of_week
+ eval $result + 1
+ assign $result $nextDayOfWeek
+ assign Sun $nextDayOfWeek if $nextDayOfWeek > Sat
+ roll day_of_week 1
+ check day_of_week $nextDayOfWeek
+
+CLEAR ALL
+
+ Clears all the calendar fields of the current Calendar instance by
+ calling Calendar.clear().
+
+CLEAR field
+
+ Clears the specified calendar `field' of the current Calendar instance
+ by calling Calendar.clear(field).`field' must be one of the Calendar
+ field indices, ERA, YEAR, MONTH, DAY_OF_MONTH, WEEK_OF_YEAR, etc.
+
+GET MILLIS
+
+ Gets the millisecond value of the current Calendar instance by calling
+ Calendar.getTimeInMillis(). The value is assigned to $result.
+
+GET field
+
+ Gets the `field' value specified of the current Calendar instance by
+ calling Calendar.get(field). The value is assigned to $result.
+
+GET MIN field
+
+ Gets the minimum value of the specified `field' of the current
+ Calendar instance by calling Calendar.getMinimum(field). The value is
+ assigned to $result.
+
+GET GREATESTMIN field
+
+ Gets the greatest minimum value of the specified `field' of the
+ current Calendar instance by calling
+ Calendar.getGreatestMinimum(field). The value is assigned to $result.
+
+GET ACTUALMIN field
+
+ Gets the actual minimum value of the specified `field' of the current
+ Calendar instance by calling Calendar.getActualMinimum(field). The
+ value is assigned to $result.
+
+GET MAX field
+
+ Gets the maximum value of the specified `field' of the current
+ Calendar instance by calling Calendar.getMaximum(field). The value is
+ assigned to $result.
+
+GET LEASTMAX field
+
+ Gets the least maximum value of the specified `field' of the current
+ Calendar instance by calling Calendar.getLeastMaximum(field). The
+ value is assigned to $result.
+
+GET ACTUALMAX field
+
+ Gets the actual maximum value of the specified `field' of the current
+ Calendar instance by calling Calendar.getActualMaximum(field). The
+ value is assigned to $result.
+
+GET FIRSTDAYOFWEEK
+
+ Gets the first day of week value of the current Calendar instance by
+ calling Calendar.getFirstDayOfWeek(). The value is assigned to
+ $result.
+
+GET MINIMALDAYSINFIRSTWEEK
+
+ Gets the minimal days in first week value of the current Calendar
+ instance by calling Calendar.getMinimalDaysInFirstWeek(). The value is
+ assigned to $result.
+
+ADD field amount
+
+ Adds `amount' to the specified `field' of the current Calendar
+ instance by calling Calendar.add(field, amount).
+
+ROLL field amount
+
+ Rolls `amount' of the specified `field' of the current Calendar
+ instance by calling Calendar.roll(field, amount).
+
+SET MILLIS value
+
+ Sets the millisecond value of the current Calendar instance to `value'
+ by calling Calendar.setTimeInMillis(value).
+
+SET field value
+
+ Sets the `field' value of the current Calendar instance to `value' by
+ calling Calendar.set(field, value).
+
+SET DATE era year month dayOfMonth
+
+ Sets the date of the current Calendar instance to the date specified
+ by `era', `year', `month' and `dayOfMonth' by calling
+ Calendar.set(ERA, era) and Calendar.set(year, month,
+ dayOfMonth). Please note that `month' follows the Calendar convention
+ and is 0-based. (e.g., JANUARY is 0)
+
+SET DATE year month dayOfMonth
+
+ Sets the date of the current Calendar instance to the date specified
+ by `year', `month' and `dayOfMonth' by calling
+ Calendar.set(year, month, dayOfMont). Please note that `month'
+ follows the Calendar convention and is 0-based. (e.g., JANUARY is 0)
+
+SET DATETIME year month dayOfMonth hourOfDay minute second
+
+ Sets the date and time of the current Calendar instance to the date
+ and time specified by `year', `month', `dayOfMonth', `hourOfDay',
+ `minute', and `second' by calling Calendar.set(year, month,
+ dayOfMonth, hourOfDay, minute, second). Please note that `hourOfDay'
+ is the 24-hour clock.
+
+SET TIMEOFDAY hourOfDay minute second millisecond
+
+ Sets the date and time of the current Calendar instance to the date
+ and time specified by `year', `month', `dayOfMonth', `hourOfDay',
+ `minute', and `second' by calling Calendar.set(HOUR_OF_DAY,
+ hourOfDay), Calendar.set(MINUTE, minute), and Calendar.set(SECOND,
+ second).
+
+SET FIRSTDAYOFWEEK value
+
+ Sets the first day of week value of the current Calendar instance to
+ `value' by calling Calendar.setFirstDayOfWeek(value).
+
+SET MINIMALDAYSINFIRSTWEEK value
+
+ Sets the minimal days in the first week value of the current Calendar
+ instance to `value' by calling Calendar.setMinimalDaysInFirstWeek(value).
+
+SET LENIENT
+
+ Sets the lenient mode in the current Calendar instance by calling
+ Calendar.setLenient(true).
+
+SET NON-LENIENT
+
+ Sets the non-lenient mode in the current Calendar instance by calling
+ Calendar.setLenient(false).
+
+CHECK MILLIS value
+
+ Checks if the specified `value' is the same as the millisecond value
+ of the current Calendar instance given by calling
+ Calendar.getTimeInMillis(). If the values are different, an exception
+ is thrown.
+
+CHECK DATE era year month dayOfMonth
+
+ Checks if the date specified by `era', `year', `month' and
+ `dayOfMonth' is the same date of the current Calendar instance. The
+ calendar date is given by calling Calendar.get(ERA),
+ Calendar.get(YEAR), Calendar.get(MONTH), and
+ Calendar.get(DAY_OF_MONTH). If the dates are different, an exception
+ is thrown.
+
+CHECK DATE year month dayOfMonth
+
+ Checks if the date specified by `year', `month' and `dayOfMonth' is
+ the same date of the current Calendar instance. The calendar date is
+ given by calling Calendar.get(YEAR), Calendar.get(MONTH), and
+ Calendar.get(DAY_OF_MONTH). If the dates are different, an exception
+ is thrown.
+
+CHECK DATETIME year month dayOfMonth hourOfDay minute second
+
+ Checks if the date and time specified by `year', `month',
+ `dayOfMonth', `hourOfDay', `minute', and `second' are the same ones of
+ the current Calendar instance. The calendar date and time are given by
+ calling Calendar.get(YEAR), Calendar.get(MONTH),
+ Calendar.get(DAY_OF_MONTH), Calendar.get(HOUR_OF_DAY),
+ Calendar.get(MINUTE) and Calendar.get(SECOND). If the dates or times
+ are different, an exception is thrown.
+
+CHECK DATETIME year month dayOfMonth hourOfDay minute second millisecond
+
+ Checks if the date and time specified by `year', `month',
+ `dayOfMonth', `hourOfDay', `minute', `second' and `millisecond' are
+ the same ones of the current Calendar instance. The calendar date and
+ time are given by calling Calendar.get(YEAR), Calendar.get(MONTH),
+ Calendar.get(DAY_OF_MONTH), Calendar.get(HOUR_OF_DAY),
+ Calendar.get(MINUTE), Calendar.get(SECOND) and
+ Calendar.get(MILLISECOND). If the dates or times are different, an
+ exception is thrown.
+
+CHECK TIMEOFDAY hourOfDay minute second millisecond
+
+ Checks if the time of day specified by `hourOfDay', `minute', `second'
+ and `millisecond' are the same ones of the current Calendar
+ instance. The calendar date and time are given by calling
+ Calendar.get(HOUR_OF_DAY), Calendar.get(MINUTE), Calendar.get(SECOND)
+ and Calendar.get(MILLISECOND). If the times are different, an
+ exception is thrown.
+
+CHECK field value
+
+ Checks if the value of the given `field' of the current Calendar
+ instance is equal to the given `value'. If it doesn't, an exception is
+ thrown.
+
+CHECK MIN field value
+
+ Checks if the minimum value of the specified `field' of the current
+ Calendar instance is equal to the specified `value'. If not, an
+ exception is thrown.
+
+CHECK GREATESTMIN field value
+
+ Checks if the greatest minimum value of the specified `field' of the
+ current Calendar instance is equal to the specified `value'. If not,
+ an exception is thrown.
+
+CHECK ACTUALMIN field value
+
+ Checks if the actual minimum value of the specified `field' of the
+ current Calendar instance is equal to the specified `value'. If not,
+ an exception is thrown.
+
+CHECK MAX field value
+
+ Checks if the maximum value of the specified `field' of the current
+ Calendar instance is equal to the specified `value'. If not, an
+ exception is thrown.
+
+CHECK LEASTMAX field value
+
+ Checks if the least maximum value of the specified `field' of the
+ current Calendar instance is equal to the specified `value'. If not,
+ an exception is thrown.
+
+CHECK ACTUALMAX field value
+
+ Checks if the actual maximum value of the specified `field' of the
+ current Calendar instance is equal to the specified `value'. If not,
+ an exception is thrown.
+
+EXCEPTION exceptionname
+
+ Checks if the previous command threw the specified exception by
+ `exceptionname'. For example, the following tests invalid date
+ detection in non-lenient.
+
+ set non-lenient
+ set date 2005 Feb 29 # 2005 isn't a leap year.
+ get millis
+ exception IllegalArgumentException
+
+PRINT variable
+
+ Prints the value of `variable'.
+
+PRINT INSTANCE [calendarname]
+
+ Prints the Calendar.toString() value of the current Calendar instance
+ or the instance given by `calendarname'.
+
+PRINT field
+
+ Prints the value of the specified `field' of the current Calendar
+ instance. The value is obtained by calling Calendar.get(field).
+
+PRINT MILLIS
+
+ Prints the millisecond value of the current Calendar instance. The
+ value is obtained by calling Calendar.getTimeInMillis().
+
+PRINT MIN field
+
+ Prints the minimum value of the specified field by `field' of the
+ current Calendar instance. The value is obtained by calling
+ Calendar.getMinimum(field).
+
+PRINT GREATESTMIN field
+
+ Prints the greatest minimum value of the specified field by `field' of
+ the current Calendar instance. The value is obtained by calling
+ Calendar.getGreatestMinimum(field).
+
+PRINT ACTUALMIN field
+
+ Prints the actual minimum value of the specified field by `field' of
+ the current Calendar instance by calling
+ Calendar.getActualMinimum(field).
+
+PRINT MAX field
+
+ Prints the maximum value of the specified field by `field' of the
+ current Calendar instance. The value is obtained by calling
+ Calendar.getMaximum(field).
+
+PRINT LEASTMAX field
+
+ Prints the least maximum value of the specified field by `field' of
+ the current Calendar instance. The value is obtained by calling
+ Calendar.getLeastMaximum(field).
+
+PRINT ACTUALMAX field
+
+ Prints the actual maximum value of the specified field by `field' of
+ the current Calendar instance. The value is obtained by calling
+ Calendar.getActualMaximum(field).
+
+PRINT DATE
+
+ Prints the date of the current Calendar instance in format
+ "[ERA] yyyy-MM-dd". The date is obtained by calling Calendar.get(ERA),
+ Calendar.get(YEAR), Calendar.get(MONTH), and
+ Calendar.get(DAY_OF_MONTH).
+
+PRINT DATETIME
+
+ Prints the date and time of the current Calendar instance in an ISO
+ 8601-style format "[ERA] yyyy-MM-ddTHH:mm:ss.SSS{Z|{+|-}hhmm}". The
+ date and time are obtained by calling Calendar.get(ERA),
+ Calendar.get(YEAR), Calendar.get(MONTH), Calendar.get(DAY_OF_MONTH),
+ Calendar.get(HOUR_OF_DAY), Calendar.get(MINUTE), Calendar.get(SECOND),
+ Calendar.get(MILLISECOND), Calendar.get(ZONE_OFFSET), and
+ Calendar.get(DST_OFFSET).
+
+PRINT TIMEZONE
+
+ Prints the toString() value of the current TimeZone.
+
+PRINT LOCALE
+
+ Prints the toString() value of the current Locale.
+
+Usage
+-----
+
+The usage of the test script system at this directory is:
+
+ $ javac -d classes --add-exports java.base/sun.util=ALL-UNNAMED --add-exports java.base/sun.util.calendar=ALL-UNNAMED *.java
+ $ java -cp classes CalendarTestEngine scriptfiles...
+
+A script file has suffix ".cts" by convention. If multiple script files
+are specified. Those files are sequentially executed as if those are a
+single test script. For example, if we have the following script files:
+
+ file1.cts:
+ locale ja JP JP
+ timezone Asia/Tokyo
+ file2.cts:
+ new instance jcal
+ new gregorian gcal
+ test example
+ use jcal
+ print datetime
+ get millis
+ print $result
+ use gcal
+ set millis $result
+ print datetime
+
+running CalendarTestEngine with those files will produce:
+
+ $ java -cp classes CalendarTestEngine file1.cts file2.cts
+ Starting file1.cts...
+ Completed file1.cts
+ Starting file2.cts...
+ Test #1: example
+ file2.cts:5: Heisei 0017-03-18T20:00:25.402+0900
+ file2.cts:7: $result=1111143625402
+ file2.cts:10: 2005-03-18T20:00:25.402+0900
+ Completed file2.cts
+
+[end of README]
diff --git a/test/java/util/Calendar/CalendarTestScripts/Result.java b/test/java/util/Calendar/CalendarTestScripts/Result.java
new file mode 100644
index 0000000000..9ea8b13bab
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/Result.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007, 2018, 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.
+ */
+
+public class Result extends Variable {
+ private Exception e;
+ private int lineno;
+
+ public Result() {
+ super("$result", 0);
+ put("$result", this);
+ }
+
+ public void setLineno(int lineno) {
+ this.lineno = lineno;
+ }
+
+ public int getLineno() {
+ return lineno;
+ }
+
+ public void setException(Exception e) {
+ if (this.e != null) {
+ throw new RuntimeException("existing exception: " + e, e);
+ }
+ this.e = e;
+ }
+
+ public Exception getException() {
+ Exception e = this.e;
+ this.e = null;
+ return e;
+ }
+}
diff --git a/test/java/util/Calendar/CalendarTestScripts/Symbol.java b/test/java/util/Calendar/CalendarTestScripts/Symbol.java
new file mode 100644
index 0000000000..7368a6da8d
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/Symbol.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2007, 2018, 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.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import static java.util.Calendar.*;
+import static java.util.GregorianCalendar.*;
+
+public class Symbol {
+
+ private static Map<String, Symbol> symbols;
+
+ String name;
+ Type type;
+ int value;
+ boolean isArithmetic;
+
+ private Symbol(Type type, Integer value) {
+ this(type, value, false);
+ }
+
+ private Symbol(Type type) {
+ this(type, null, false);
+ }
+
+ private Symbol(Type type, boolean isArithmetic) {
+ this(type, null, isArithmetic);
+ }
+
+ private Symbol(Type type, Integer value, boolean isArithmetic) {
+ this.name = type.toString().toLowerCase(Locale.ROOT);
+ this.type = type;
+ if (value != null)
+ this.value = value;
+ this.isArithmetic = isArithmetic;
+ }
+
+ public int value() {
+ return value;
+ }
+
+ public String toString() {
+ return type.name();
+ }
+
+ public boolean isArithmetic() {
+ return isArithmetic;
+ }
+
+ public static Symbol get(String s) {
+ return symbols.get(s);
+ }
+
+ public static enum Type {
+ // Directives
+ TEST,
+ // Commands
+ LOCALE, TIMEZONE, NEW, USE, ASSIGN, EVAL,
+ CLEAR, SET, GET, ADD, ROLL, CHECK, PRINT, EXCEPTION,
+ IF,
+ // Operands
+ INSTANCE, GREGORIAN, ALL, MILLIS, DATE, DATETIME, TIMEOFDAY,
+ LENIENT, NONLENIENT,
+ MINIMUM, GREATESTMINIMUM, ACTUALMINIMUM,
+ MAXIMUM, LEASTMAXIMUM, ACTUALMAXIMUM,
+ FIRSTDAYOFWEEK, MINIMALDAYSINFIRSTWEEK,
+ // Arithmetic operators
+ PLUS, MINUS, MULTIPLY, DIVIDE, MOD,
+ // Relational operators
+ GT, GE, EQ, NEQ, LE, LT,
+ // Calendar field indices
+ FIELD,
+ // Day of week
+ DAYOFWEEK,
+ // Month
+ MONTH,
+ // AM/PM
+ AMPM,
+ // Era values
+ ERA;
+ }
+
+ private static final void put(String key, Symbol sym) {
+ Symbol s = symbols.put(key, sym);
+ if (s != null) {
+ throw new RuntimeException("duplicated key: " + key);
+ }
+ }
+
+ static {
+ symbols = new HashMap<String, Symbol>();
+ Symbol sym;
+ // Directives
+ put("test", new Symbol(Type.TEST));
+
+ // Commands
+ put("locale", new Symbol(Type.LOCALE));
+ sym = new Symbol(Type.TIMEZONE);
+ put("tz", sym);
+ put("timezone", sym);
+ put("new", new Symbol(Type.NEW));
+ put("use", new Symbol(Type.USE));
+ put("assign", new Symbol(Type.ASSIGN));
+ put("eval", new Symbol(Type.EVAL));
+ put("clear", new Symbol(Type.CLEAR));
+ put("set", new Symbol(Type.SET));
+ put("get", new Symbol(Type.GET));
+ put("add", new Symbol(Type.ADD));
+ put("roll", new Symbol(Type.ROLL));
+ put("check", new Symbol(Type.CHECK));
+ put("print", new Symbol(Type.PRINT));
+ put("exception", new Symbol(Type.EXCEPTION));
+ put("throw", get("exception"));
+ put("if", new Symbol(Type.IF));
+
+ // Operands
+ put("instance", new Symbol(Type.INSTANCE));
+ put("gregorian", new Symbol(Type.GREGORIAN));
+ put("all", new Symbol(Type.ALL));
+ put("millis", new Symbol(Type.MILLIS));
+ put("date", new Symbol(Type.DATE));
+ put("datetime", new Symbol(Type.DATETIME));
+ put("timeofday", new Symbol(Type.TIMEOFDAY));
+ put("lenient", new Symbol(Type.LENIENT));
+ sym = new Symbol(Type.NONLENIENT);
+ put("non-lenient", sym);
+ put("nonlenient", sym);
+ put("firstdayofweek", new Symbol(Type.FIRSTDAYOFWEEK));
+ put("minimaldaysinfirstweek", new Symbol(Type.MINIMALDAYSINFIRSTWEEK));
+
+ sym = new Symbol(Type.MINIMUM);
+ put("minimum", sym);
+ put("min", sym);
+ sym = new Symbol(Type.GREATESTMINIMUM);
+ put("greatestminimum", sym);
+ put("greatestmin", sym);
+ sym = new Symbol(Type.ACTUALMINIMUM);
+ put("actualminimum", sym);
+ put("actualmin", sym);
+ sym = new Symbol(Type.MAXIMUM);
+ put("maximum", sym);
+ put("max", sym);
+ sym = new Symbol(Type.LEASTMAXIMUM);
+ put("leastmaximum", sym);
+ put("leastmax", sym);
+ sym = new Symbol(Type.ACTUALMAXIMUM);
+ put("actualmaximum", sym);
+ put("actualmax", sym);
+
+ // Arithmetic operators
+ put("+", new Symbol(Type.PLUS, true));
+ put("-", new Symbol(Type.MINUS, true));
+ put("*", new Symbol(Type.MULTIPLY, true));
+ put("/", new Symbol(Type.DIVIDE, true));
+ put("%", new Symbol(Type.MOD, true));
+
+ // Relational operators
+ put(">", new Symbol(Type.GT, false));
+ put(">=", new Symbol(Type.GE, false));
+ put("==", new Symbol(Type.EQ, false));
+ put("!=", new Symbol(Type.NEQ, false));
+ put("<=", new Symbol(Type.LE, false));
+ put("<", new Symbol(Type.LT, false));
+
+ // Calendar Fields
+ put("era", new Symbol(Type.FIELD, ERA));
+ put("year", new Symbol(Type.FIELD, YEAR));
+ put("month", new Symbol(Type.FIELD, MONTH));
+ sym = new Symbol(Type.FIELD, WEEK_OF_YEAR);
+ put("week_of_year", sym);
+ put("weekofyear", sym);
+ put("woy", sym);
+ sym = new Symbol(Type.FIELD, WEEK_OF_MONTH);
+ put("week_of_month", sym);
+ put("weekofmonth", sym);
+ put("wom", sym);
+ sym = new Symbol(Type.FIELD, DAY_OF_MONTH);
+ put("day_of_month", sym);
+ put("dayofmonth", sym);
+ put("dom", sym);
+ sym = new Symbol(Type.FIELD, DAY_OF_YEAR);
+ put("day_of_year", sym);
+ put("dayofyear", sym);
+ put("doy", sym);
+
+ sym = new Symbol(Type.FIELD, DAY_OF_WEEK);
+ put("day_of_week", sym);
+ put("dayofweek", sym);
+ put("dow", sym);
+ sym = new Symbol(Type.FIELD, DAY_OF_WEEK_IN_MONTH);
+ put("day_of_week_in_month", sym);
+ put("dayofweekinmonth", sym);
+ put("dowim", sym);
+ sym = new Symbol(Type.FIELD, AM_PM);
+ put("am_pm", sym);
+ put("ampm", sym);
+ put("hour", new Symbol(Type.FIELD, HOUR));
+ sym = new Symbol(Type.FIELD, HOUR_OF_DAY);
+ put("hour_of_day", sym);
+ put("hourofday", sym);
+ put("hod", sym);
+ put("minute", new Symbol(Type.FIELD, MINUTE));
+ put("second", new Symbol(Type.FIELD, SECOND));
+ put("millisecond", new Symbol(Type.FIELD, MILLISECOND));
+ sym = new Symbol(Type.FIELD, ZONE_OFFSET);
+ put("zone_offset", sym);
+ put("zoneoffset", sym);
+ put("zo", sym);
+ sym = new Symbol(Type.FIELD, DST_OFFSET);
+ put("dst_offset", sym);
+ put("dstoffset", sym);
+ put("do", sym);
+
+ // Day of week
+ sym = new Symbol(Type.DAYOFWEEK, SUNDAY);
+ put("sunday", sym);
+ put("sun", sym);
+ sym = new Symbol(Type.DAYOFWEEK, MONDAY);
+ put("monday", sym);
+ put("mon", sym);
+ sym = new Symbol(Type.DAYOFWEEK, TUESDAY);
+ put("tuesday", sym);
+ put("tue", sym);
+ sym = new Symbol(Type.DAYOFWEEK, WEDNESDAY);
+ put("wednesday", sym);
+ put("wed", sym);
+ sym = new Symbol(Type.DAYOFWEEK, THURSDAY);
+ put("thursday", sym);
+ put("thu", sym);
+ sym = new Symbol(Type.DAYOFWEEK, FRIDAY);
+ put("friday", sym);
+ put("fri", sym);
+ sym = new Symbol(Type.DAYOFWEEK, SATURDAY);
+ put("saturday", sym);
+ put("sat", sym);
+
+
+ // Month
+ sym = new Symbol(Type.MONTH, JANUARY);
+ put("january", sym);
+ put("jan", sym);
+ sym = new Symbol(Type.MONTH, FEBRUARY);
+ put("february", sym);
+ put("feb", sym);
+ sym = new Symbol(Type.MONTH, MARCH);
+ put("march", sym);
+ put("mar", sym);
+ sym = new Symbol(Type.MONTH, APRIL);
+ put("april", sym);
+ put("apr", sym);
+ sym = new Symbol(Type.MONTH, MAY);
+ put("may", sym);
+ sym = new Symbol(Type.MONTH, JUNE);
+ put("june", sym);
+ put("jun", sym);
+ sym = new Symbol(Type.MONTH, JULY);
+ put("july", sym);
+ put("jul", sym);
+ sym = new Symbol(Type.MONTH, AUGUST);
+ put("august", sym);
+ put("aug", sym);
+ sym = new Symbol(Type.MONTH, SEPTEMBER);
+ put("september", sym);
+ put("sep", sym);
+ sym = new Symbol(Type.MONTH, OCTOBER);
+ put("octobwe", sym);
+ put("oct", sym);
+ sym = new Symbol(Type.MONTH, NOVEMBER);
+ put("november", sym);
+ put("nov", sym);
+ sym = new Symbol(Type.MONTH, DECEMBER);
+ put("december", sym);
+ put("dec", sym);
+ sym = new Symbol(Type.MONTH, UNDECIMBER);
+ put("undecimber", sym);
+
+ // AM/PM
+ put("am", new Symbol(Type.AMPM, AM));
+ put("pm", new Symbol(Type.AMPM, PM));
+
+ // Eras
+
+ // Julian eras
+ sym = new Symbol(Type.ERA, BC);
+ put("bc", sym);
+ put("bce", sym);
+ sym = new Symbol(Type.ERA, AD);
+ put("ad", sym);
+ put("ce", sym);
+
+ // Buddhist era
+ put("be", new Symbol(Type.ERA, 1));
+
+ // Japanese imperial eras
+ sym = new Symbol(Type.ERA, 0);
+ put("before_meiji", sym);
+ put("beforemeiji", sym);
+ put("meiji", new Symbol(Type.ERA, 1));
+ put("taisho", new Symbol(Type.ERA, 2));
+ put("showa", new Symbol(Type.ERA, 3));
+ put("heisei", new Symbol(Type.ERA, 4));
+ put("newera", new Symbol(Type.ERA, 5));
+
+ }
+}
diff --git a/test/java/util/Calendar/CalendarTestScripts/Variable.java b/test/java/util/Calendar/CalendarTestScripts/Variable.java
new file mode 100644
index 0000000000..510b2bccbb
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/Variable.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2007, 2018, 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.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+public class Variable {
+ private static Map<String,Variable> vars = new HashMap<String,Variable>();
+
+ private String name;
+ private long value;
+
+ Variable(String name, long value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int intValue() {
+ if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
+ throw new RuntimeException("Overflow/Underflow: " + value);
+ }
+ return (int) value;
+ }
+
+ public long longValue() {
+ return value;
+ }
+
+ public void setValue(int v) { value = v; }
+ public void setValue(long v) { value = v; }
+
+ // static methods
+
+ public static Variable newVar(String name, long value) {
+ if (name.charAt(0) != '$') {
+ throw new RuntimeException("wrong var name: " + name);
+ }
+ String s = name.toLowerCase(Locale.ROOT);
+ Variable v = new Variable(name, value);
+ put(name, v);
+ return v;
+ }
+
+ static void put(String s, Variable var) {
+ vars.put(s, var);
+ }
+
+ public static Variable get(String name) {
+ return vars.get(name);
+ }
+}
diff --git a/test/java/util/Calendar/CalendarTestScripts/japanese/japanese.cts b/test/java/util/Calendar/CalendarTestScripts/japanese/japanese.cts
new file mode 100644
index 0000000000..bf4c8cba13
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/japanese/japanese.cts
@@ -0,0 +1,331 @@
+#
+#
+#
+
+locale ja JP JP
+new instance jcal
+new gregorian gcal
+
+test Default dates
+ # Default for all unset fields
+ # 1970-01-01T00:00:00.000 local time (Gregorian)
+ # which is equivalent to Showa 45.
+ use gcal
+ clear all
+ get millis
+ # get the default milliseconds from the Epoch. It's time zone
+ # dependent.
+ assign $result $defmillis
+ use jcal
+ clear all
+ get millis
+ eval $result == $defmillis
+ check era Showa
+ check datetime 45 Jan 1 0 0 0
+ check millisecond 0
+
+ # If each era is set, then January 1 of each Gan-nen is the
+ # default.
+ clear all
+ set era BeforeMeiji
+ check era BeforeMeiji
+ check datetime 1 Jan 1 0 0 0
+ check millisecond 0
+
+ clear all
+ set era Meiji
+ check era Meiji
+ check datetime 1 Jan 1 0 0 0
+ check millisecond 0
+
+ clear all
+ set era Taisho
+ check era Meiji
+ check datetime 45 Jan 1 0 0 0
+ check millisecond 0
+
+ clear all
+ set era Showa
+ check era Taisho
+ check datetime 15 Jan 1 0 0 0
+ check millisecond 0
+
+ clear all
+ set era Heisei
+ check era Showa
+ check datetime 64 Jan 1 0 0 0
+ check millisecond 0
+
+ clear all
+ set era NewEra
+ check era Heisei
+ check datetime 31 Jan 1 0 0 0
+ check millisecond 0
+
+#
+# Field resolution tests
+#
+ clear all
+ get firstdayofweek
+ # The test cases below assume that the first day of week is
+ # Sunday. So we should make sure it is.
+ eval $result == Sun
+ assign $result $fdow
+
+test Field resolution: YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
+ set era Showa
+ set year 64
+ set week_of_month 1
+ check day_of_week $fdow
+ check date 64 Jan 1
+
+ clear all
+ set era Showa
+ set year 64
+ set week_of_month 1
+ set day_of_week Thu
+ check era Showa
+ check day_of_week Thu
+ check date 64 Jan 5
+
+ clear all
+ # Heise 1 January and Showa 64 January are the same month. Its
+ # first week should be the same week. (January is the default
+ # month.)
+ set era Heisei
+ set year 1
+ set week_of_month 1
+ check day_of_week $fdow
+ check era Showa
+ check date 64 Jan 1
+
+ # Test aggregation
+ clear all
+ set date Heisei 17 Mar 16
+ set week_of_month 1
+ set day_of_week Tue
+ check date Heisei 17 Mar 1
+
+ clear all
+ set week_of_month 1
+ set date Heisei 17 Mar 16
+ set day_of_week Tue
+ check date Heisei 17 Mar 1
+
+ clear all
+ set day_of_week Tue
+ set date Heisei 17 Mar 16
+ set week_of_month 1
+ check date Heisei 17 Mar 1
+
+ clear all
+ set day_of_week Tue
+ set date Heisei 17 Mar 16
+ set week_of_year 10
+ set week_of_month 1
+ check date Heisei 17 Mar 1
+
+ clear all
+ set day_of_week Tue
+ set date Heisei 17 Mar 16
+ set day_of_year 300
+ set week_of_month 1
+ check date Heisei 17 Mar 1
+
+test Field resolution: YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
+ clear all
+ set era Meiji
+ set year 45
+ set month Jul
+ set day_of_week_in_month 5
+ set day_of_week Mon
+ check date Meiji 45 Jul 29
+
+ clear all
+ set era Meiji
+ set year 45
+ set month Jul
+ set day_of_week_in_month 4
+ check date Meiji 45 Jul 28
+
+ clear all
+ set era Meiji
+ set year 45
+ set month Jul
+ set day_of_week_in_month 5
+ set day_of_week Tue
+ check date Taisho 1 Jul 30
+
+ clear all
+ set era Taisho
+ set year 1
+ set month Jul
+ set day_of_week_in_month 1
+ set day_of_week Tue
+ check date Meiji 45 Jul 2
+
+ # Test aggregation
+ clear all
+ set date Heisei 17 Mar 16
+ set day_of_week_in_month 1
+ set day_of_week Wed
+ check date Heisei 17 Mar 2
+
+ clear all
+ set day_of_week_in_month 1
+ set date Heisei 17 Mar 16
+ set day_of_week Wed
+ check date Heisei 17 Mar 2
+
+ clear all
+ set day_of_week Wed
+ set date Heisei 17 Mar 16
+ set day_of_week_in_month 1
+ check date Heisei 17 Mar 2
+
+ clear all
+ set day_of_week Wed
+ set date Heisei 17 Mar 16
+ set week_of_month 4
+ set day_of_week_in_month 1
+ check date Heisei 17 Mar 2
+
+ clear all
+ set day_of_week Wed
+ set date Heisei 17 Mar 16
+ set day_of_year 365
+ set day_of_week_in_month 1
+ check date Heisei 17 Mar 2
+
+ clear all
+ set day_of_week Wed
+ set date Heisei 17 Mar 16
+ set week_of_year 50
+ set day_of_week_in_month 1
+ check date Heisei 17 Mar 2
+
+test Field resolution: YEAR + DAY_OF_YEAR
+ clear all
+ set era Showa
+ set year 64
+ set day_of_year 7
+ check date Showa 64 Jan 7
+
+ clear all
+ set era Showa
+ set year 64
+ set day_of_year 10
+ check date Heisei 1 Jan 10
+
+ clear all
+ set era Showa
+ set year 64
+ check date Showa 64 Jan 1
+ check day_of_year 1
+
+ clear all
+ set era Heisei
+ set year 1
+ set day_of_year 10
+ check date Heisei 1 Jan 17
+
+ clear all
+ set era Heisei
+ set year 1
+ set day_of_year 1
+ check date Heisei 1 Jan 8
+
+ clear all
+ set era Heisei
+ set year 1
+ set day_of_year -1
+ check date Showa 64 Jan 6
+
+ clear all
+ set date Heisei 17 Mar 16
+ set day_of_year 31
+ check date Heisei 17 Jan 31
+
+ clear all
+ set date Heisei 17 Mar 16
+ set week_of_year 50
+ set day_of_week Wed
+ set day_of_year 31
+ check date Heisei 17 Jan 31
+
+ clear all
+ set date Heisei 17 Mar 16
+ set week_of_month 5
+ set day_of_week Wed
+ set day_of_year 31
+ check date Heisei 17 Jan 31
+
+test Field resolution: YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
+ clear all
+ set era Showa
+ set year 64
+ set week_of_year 1
+ check day_of_week $fdow
+ check date 64 Jan 1
+
+ clear all
+ set era Showa
+ set year 64
+ set week_of_year 1
+ set day_of_week Wed
+ check date Showa 64 Jan 4
+
+ clear all
+ set era Heisei
+ set year 1
+ set week_of_year 1
+ check day_of_week $fdow
+ check date 1 Jan 8
+
+ clear all
+ set date Heisei 17 Mar 16
+ set week_of_year 2
+ set day_of_week Thu
+ check date Heisei 17 Jan 6
+
+ clear all
+ set week_of_year 2
+ set date Heisei 17 Mar 16
+ set day_of_week Thu
+ check date Heisei 17 Jan 6
+
+ clear all
+ set day_of_week Thu
+ set date Heisei 17 Mar 16
+ set week_of_year 2
+ check date Heisei 17 Jan 6
+
+test zone offsets
+ # Tests here depend on the GMT offset.
+ timezone GMT+09:00
+ new instance cal0900
+ use cal0900
+ clear all
+ set date Heisei 17 Mar 12
+ get millis
+ assign $result $H17Mar12
+ clear all
+ set date Heisei 17 Mar 12
+ set zone_offset 0
+ get millis
+ eval $result - 32400000 # -9 hours
+ eval $result == $H17Mar12
+
+ clear all
+ set date Heisei 17 Mar 12
+ set zone_offset 28800000 # 8 hours
+ set dst_offset 3600000 # 1 hour
+ get millis
+ eval $result == $H17Mar12
+
+ clear all
+ set date Heisei 17 Mar 12
+ set zone_offset 18000000 # 5 hours
+ set dst_offset 14400000 # 4 hours
+ get millis
+ eval $result == $H17Mar12
diff --git a/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_add.cts b/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_add.cts
new file mode 100644
index 0000000000..63e5debc84
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_add.cts
@@ -0,0 +1,521 @@
+#
+# %i%
+#
+
+# The test cases in this file assume the first day of week is Sunday
+# and the minimal days in the first week is 1.
+
+locale ja JP JP
+new instance jcal
+
+timezone Asia/Tokyo
+new instance tokyocal
+
+set non-lenient
+
+test add ERA
+ use jcal
+ clear all
+ set date NewEra 17 Mar 8
+ add era 10
+ # as of NewEra 17 March 8
+ check era NewEra
+ add era -100
+ check era BeforeMeiji
+
+test add HOUR_OF_DAY
+ use jcal
+ clear all
+ set era Heisei
+ set datetime 1 Jan 8 23 59 59
+ add hour_of_day 1
+ check datetime 1 Jan 9 0 59 59
+ check ampm AM
+ check hour 0
+ add hour_of_day -1
+ check datetime 1 Jan 8 23 59 59
+ add hour_of_day 24
+ check datetime 1 Jan 9 23 59 59
+ add hour_of_day -24
+ check datetime 1 Jan 8 23 59 59
+
+test add HOUR
+ use jcal
+ clear all
+ set era Showa
+ set datetime 64 Jan 7 11 59 59
+ check era Showa
+ check hour 11
+ check ampm AM
+ add hour 1
+ check hour 0
+ check ampm PM
+ check datetime 64 Jan 7 12 59 59
+ add hour -1
+ check datetime 64 Jan 7 11 59 59
+ add hour 240
+ check era Heisei
+ check datetime 1 Jan 17 11 59 59
+ add hour -240
+ check era Showa
+ check datetime 64 Jan 7 11 59 59
+
+ clear all
+ set era Showa
+ set datetime 64 Jan 7 23 59 59
+ check era Showa
+ check hour 11
+ check ampm PM
+ add hour 1
+ check hour 0
+ check ampm AM
+ check era Heisei
+ check datetime 1 Jan 8 0 59 59
+ add hour -1
+ check datetime 64 Jan 7 23 59 59
+ add hour 240
+ check era Heisei
+ check datetime 1 Jan 17 23 59 59
+ add hour -240
+ check era Showa
+ check datetime 64 Jan 7 23 59 59
+
+ clear all
+ set era Heisei
+ set datetime 1 Jan 8 23 59 59
+ check date Heisei 1 Jan 8
+ check hour 11
+ check ampm PM
+ add hour 1
+ check hour 0
+ check ampm AM
+ check era Heisei
+ check datetime 1 Jan 9 0 59 59
+ add hour -1
+ check datetime 1 Jan 8 23 59 59
+ add hour 240
+ check datetime 1 Jan 18 23 59 59
+ add hour -240
+ check datetime 1 Jan 8 23 59 59
+
+test add YEAR
+ use jcal
+ clear all
+ # check if pinDayOfMonth works correctly.
+ # Heisei 12 (Y2K) is a leap year.
+ set date Heisei 12 Feb 29
+ add year 5
+ check date Heisei 17 Feb 28
+ add year -5
+ check date Heisei 12 Feb 28 # not 29!
+
+ clear all
+ set date BeforeMeiji 1867 Jan 1
+ add year 1
+ check date Meiji 1 Jan 1
+ add year -1
+ check date BeforeMeiji 1867 Jan 1
+
+ clear all
+ set date Meiji 45 Jul 29
+ add year 1
+ check date Taisho 2 Jul 29
+ add year -1
+ check date Meiji 45 Jul 29
+
+ clear all
+ set date Meiji 44 Jul 30
+ add year 1
+ check date Taisho 1 Jul 30
+ add year -1
+ check date Meiji 44 Jul 30
+
+ clear all
+ set date Taisho 15 Aug 1
+ add year 1
+ check date Showa 2 Aug 1
+ add year -1
+ check date Taisho 15 Aug 1
+
+ clear all
+ set date Taisho 14 Dec 31
+ add year 1
+ check date Showa 1 Dec 31
+ add year -1
+ check date Taisho 14 Dec 31
+
+ clear all
+ set date Showa 63 Feb 1
+ add year 1
+ check date Heisei 1 Feb 1
+ add year -1
+ check date Showa 63 Feb 1
+
+ set date Showa 63 Dec 30
+ add year 1
+ check date Heisei 1 Dec 30
+ add year -1
+ check date Showa 63 Dec 30
+
+ set date Showa 64 Jan 7
+ add year 1
+ check date Heisei 2 Jan 7
+ add year -1
+ check date Showa 64 Jan 7
+
+ set date Heisei 2 Jan 7
+ add year -1
+ check date Showa 64 Jan 7
+ add year 1
+ check date Heisei 2 Jan 7
+
+test add MONTH
+ clear all
+ # Check pinDayOfMonth works correctly.
+ # Heisei 12 is a leap year.
+ set date Heisei 12 Jan 31
+ add month 1
+ check date Heisei 12 Feb 29
+ add month -1
+ check date Heisei 12 Jan 29
+
+ # Another leap year
+ set date Showa 63 Jan 31
+ add month 1
+ check date Showa 63 Feb 29
+ add month -1
+ check date Showa 63 Jan 29
+
+ # Non leap year
+ set date Heisei 15 Jan 31
+ add month 1
+ check date Heisei 15 Feb 28
+ add month -1
+ check date Heisei 15 Jan 28
+
+ set date Heisei 15 Mar 31
+ add month 1
+ check date Heisei 15 Apr 30
+ add month -1
+ check date Heisei 15 Mar 30
+
+ set date Heisei 15 May 31
+ add month 1
+ check date Heisei 15 Jun 30
+ add month -1
+ check date Heisei 15 May 30
+
+ set date Heisei 15 Aug 31
+ add month 1
+ check date Heisei 15 Sep 30
+ add month -1
+ check date Heisei 15 Aug 30
+
+ set date Heisei 15 Oct 31
+ add month 1
+ check date Heisei 15 Nov 30
+ add month -1
+ check date Heisei 15 Oct 30
+
+ set date Heisei 15 Dec 31
+ add month -1
+ check date Heisei 15 Nov 30
+ add month 1
+ check date Heisei 15 Dec 30
+
+ set date Heisei 15 Dec 31
+ add month 2
+ check date Heisei 16 Feb 29
+ add month -1
+ check date Heisei 16 Jan 29
+
+ # end of pinDayOfMonth tests
+
+ set date BeforeMeiji 1867 Dec 1
+ add month 1
+ check date Meiji 1 Jan 1
+ add month -1
+ check date BeforeMeiji 1867 Dec 1
+ add month 14
+ check date Meiji 2 Feb 1
+ add month -14
+ check date BeforeMeiji 1867 Dec 1
+
+ set date Meiji 1 Dec 1
+ add month 1
+ check date Meiji 2 Jan 1
+ add month -1
+ check date Meiji 1 Dec 1
+ add month 13
+ check date Meiji 3 Jan 1
+ add month -13
+ check date Meiji 1 Dec 1
+
+ set date Meiji 45 Jun 30
+ add month 1
+ check date Taisho 1 Jul 30
+ add month -1
+ check date Meiji 45 Jun 30
+
+ set date Meiji 45 Jun 30
+ add month 14
+ check date Taisho 2 Aug 30
+ add month -14
+ check date Meiji 45 Jun 30
+
+ # Taisho Gan-nen (year 1) has only 6 months.
+ set date Taisho 1 Jul 30
+ add month -1
+ check date Meiji 45 Jun 30
+ add month 1
+ check date Taisho 1 Jul 30
+ add month -18
+ check date Meiji 44 Jan 30
+ add month 18
+ check date Taisho 1 Jul 30
+
+ set date Taisho 15 Jan 20
+ add month 11
+ check date Taisho 15 Dec 20
+
+ set date Taisho 15 Jan 25
+ add month 11
+ check date Showa 1 Dec 25
+
+ set date Showa 1 Dec 25
+ add month 1
+ check date Showa 2 Jan 25
+ add month -1
+ check date Showa 1 Dec 25
+ add month 17
+ check date Showa 3 May 25
+ add month -17
+ check date Showa 1 Dec 25
+
+ set date Showa 64 Jan 7
+ add month 1
+ check date Heisei 1 Feb 7
+
+ set date Heisei 1 Feb 1
+ add month -1
+ # Heisei starts from Jan 8.
+ check date Showa 64 Jan 1
+ add month 1
+ check date Heisei 1 Feb 1
+
+ set date Heisei 1 Feb 8
+ add month -1
+ check date Heisei 1 Jan 8
+
+ set date Heisei 1 Dec 1
+ add month 1
+ check date Heisei 2 Jan 1
+ add month -1
+ check date Heisei 1 Dec 1
+
+ set date Heisei 1 Dec 8
+ add month 1
+ check date Heisei 2 Jan 8
+ add month -1
+ check date Heisei 1 Dec 8
+
+ # time zone dependent tests
+ use tokyocal
+ clear all
+
+ set date BeforeMeiji 1 Jan 1
+ get min year
+ assign $result $minyear
+ # actual min date: -292275055.05.17T01:47:04.192+0900
+
+ set date BeforeMeiji $minyear Dec 17
+ set timeofday 1 47 4 192
+ add month -7
+ check date BeforeMeiji $minyear May 17
+ check timeofday 1 47 4 192
+ add month 7
+ check date BeforeMeiji $minyear Dec 17
+ check timeofday 1 47 4 192
+ set date BeforeMeiji $minyear Dec 17
+ set timeofday 1 47 4 191
+ add month -7
+ check date BeforeMeiji $minyear May 18
+ check timeofday 1 47 4 191
+
+ set date NewEra 17 Jan 1
+ get max year
+ assign $result $max
+ set date NewEra $max Jul 17
+ add month 1
+ check date NewEra $max Aug 17
+# set date Heisei $max Jul 28
+# set timeofday 23 59 59 999
+# add month 1
+# check date Heisei $max Aug 16
+# check timeofday 23 59 59 999
+
+test add WEEK_OF_YEAR
+ use jcal
+ clear all
+ # 1867 Dec 23 is Monday.
+ set date BeforeMeiji 1867 Dec 23
+ add week_of_year 2
+ check day_of_week Mon
+ check date Meiji 1 Jan 6
+ add week_of_year -2
+ check day_of_week Mon
+ check date BeforeMeiji 1867 Dec 23
+
+ # 1867 Dec 23 is Wednesday.
+ set date Meiji 1 Dec 23
+ add week_of_year 2
+ check day_of_week Wed
+ check date Meiji 2 Jan 6
+ add week_of_year -2
+ check day_of_week Wed
+ check date Meiji 1 Dec 23
+
+ # Meiji 45 July 23 is Tuesday.
+ set date Meiji 45 Jul 23
+ add week_of_year 1
+ check day_of_week Tue
+ check date Taisho 1 Jul 30
+ add week_of_year -1
+ check day_of_week Tue
+ check date Meiji 45 Jul 23
+
+ # Taisho 15 December 23 is Thursday.
+ set date Taisho 15 Dec 23
+ add week_of_year 1
+ check day_of_week Thu
+ check date Showa 1 Dec 30
+ add week_of_year -1
+ check day_of_week Thu
+ check date Taisho 15 Dec 23
+
+ # Showa Gan-nen December 30 is Thursday. Showa Gan-nen has
+ # only one week. Rolling any number of weeks brings to the
+ # same date.
+ set date Showa 1 Dec 30
+ add week_of_year 1
+ check day_of_week Thu
+ check date Showa 2 Jan 6
+ add week_of_year -1
+ check day_of_week Thu
+ check date Showa 1 Dec 30
+
+ # Showa 64 January 7 is Saturday. The year has only one week.
+ set date Showa 64 Jan 7
+ add week_of_year 1
+ check day_of_week Sat
+ check date Heisei 1 Jan 14
+ add week_of_year -1
+ check day_of_week Sat
+ check date Showa 64 Jan 7
+
+ use tokyocal
+ clear all
+
+ set date BeforeMeiji $minyear Dec 25
+ check day_of_week Sat
+ eval $minyear + 1
+ assign $result $minyear_plus_1
+ add week_of_year 1
+ check day_of_week Sat
+ check date BeforeMeiji $minyear_plus_1 Jan 1
+ add week_of_year -1
+ check day_of_week Sat
+ check date BeforeMeiji $minyear Dec 25
+
+test WEEK_OF_MONTH
+ use jcal
+ clear all
+
+test DAY_OF_MONTH
+ use jcal
+ clear all
+
+test DAY_OF_YEAR
+ use jcal
+ clear all
+
+ # 1867 is a regular Gregorian year.
+ set date BeforeMeiji 1867 Dec 31
+ add day_of_year 1
+ check date Meiji 1 Jan 1
+ add day_of_year -1
+ check date BeforeMeiji 1867 Dec 31
+ add day_of_year 26
+ check date Meiji 1 Jan 26
+ add day_of_year -26
+ check date BeforeMeiji 1867 Dec 31
+
+ # Meiji 1 starts from Jan 1. It's a regular year as well.
+ set date Meiji 1 Dec 31
+ add day_of_year 1
+ check date Meiji 2 Jan 1
+ add day_of_year -1
+ check date Meiji 1 Dec 31
+ add day_of_year 26
+ check date Meiji 2 Jan 26
+ add day_of_year -26
+ check date Meiji 1 Dec 31
+
+ # The last year of Meiji (45) has an irregularity. Meiji 45
+ # July 30 is actually Taisho 1 July 30.
+ set date Meiji 45 Jul 29
+ add day_of_year 1
+ check date Taisho 1 Jul 30
+ add day_of_year -1
+ check date Meiji 45 Jul 29
+
+ # The first day of Taisho, July 30.
+ set date Taisho 1 Jul 30
+ add day_of_year -1
+ check date Meiji 45 Jul 29
+ add day_of_year 1
+ check date Taisho 1 Jul 30
+
+ set date Taisho 15 Dec 24
+ add day_of_year 1
+ check date Showa 1 Dec 25
+ add day_of_year -1
+ check date Taisho 15 Dec 24
+
+ set date Showa 1 Dec 31
+ add day_of_year 1
+ check date Showa 2 Jan 1
+ add day_of_year -1
+ check date Showa 1 Dec 31
+ add day_of_year 25
+ check date Showa 2 Jan 25
+ add day_of_year -25
+ check date Showa 1 Dec 31
+
+ set date Showa 64 Jan 7
+ add day_of_year 1
+ check date Heisei 1 Jan 8
+ add day_of_year -1
+ check date Showa 64 Jan 7
+
+ set date Heisei 1 Dec 31
+ add day_of_year 5
+ check date Heisei 2 Jan 5
+ add day_of_year -5
+ check date Heisei 1 Dec 31
+
+ use tokyocal
+ clear all
+
+ set date BeforeMeiji $minyear Dec 31
+ set timeofday 1 47 4 192
+ add day_of_year 1
+ check date BeforeMeiji $minyear_plus_1 Jan 1
+ check timeofday 1 47 4 192
+ add day_of_year -1
+ check date BeforeMeiji $minyear Dec 31
+ check timeofday 1 47 4 192
+
+test DAY_OF_WEEK_IN_MONTH
+ use jcal
+ clear all
diff --git a/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_exceptions.cts b/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_exceptions.cts
new file mode 100644
index 0000000000..976bfff561
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_exceptions.cts
@@ -0,0 +1,204 @@
+#
+#
+#
+
+locale ja JP JP
+
+# Use jcal in non-lenient mode for all test cases.
+set non-lenient
+new instance jcal
+
+use jcal
+clear all
+
+test Invalid BeforeMeiji dates
+ set date BeforeMeiji 1868 Jan 1
+ get millis
+ exception IllegalArgumentException
+ set date BeforeMeiji 1868 Jan 32
+ get millis
+ exception IllegalArgumentException
+ set date BeforeMeiji 2005 Mar 9
+ get millis
+ exception IllegalArgumentException
+
+test Invalid Meiji dates
+ set date Meiji -1 Jan 1
+ get millis
+ exception IllegalArgumentException
+ set date Meiji 1 Feb 30
+ get millis
+ exception IllegalArgumentException
+ set date Meiji 45 Jul 30
+ get millis
+ exception IllegalArgumentException
+ set date Meiji 46 Jan 1
+ get millis
+ exception IllegalArgumentException
+
+test Invalid Taisho dates
+ set date Taisho -1 Jan 1
+ get millis
+ exception IllegalArgumentException
+ set date Taisho 1 Jan 1
+ get millis
+ exception IllegalArgumentException
+ set date Taisho 1 Apr 1
+ get millis
+ exception IllegalArgumentException
+ set date Taisho 15 Dec 30
+ get millis
+ exception IllegalArgumentException
+ set date Taisho 15 Feb 29
+ get millis
+ exception IllegalArgumentException
+
+test Invalid Showa dates
+ set date Showa -11 Jan 1
+ get millis
+ exception IllegalArgumentException
+ set date Showa 1 Jan 1
+ get millis
+ exception IllegalArgumentException
+ set date Showa 1 Jun 1
+ get millis
+ exception IllegalArgumentException
+ set date Showa 1 Jul 29
+ get millis
+ exception IllegalArgumentException
+ set date Showa 64 Jan 8
+ get millis
+ exception IllegalArgumentException
+ set date Showa 64 Dec 8
+ get millis
+ exception IllegalArgumentException
+ set date Showa 65 Jan 1
+ get millis
+ exception IllegalArgumentException
+
+test Invalid Heisei dates
+ clear all
+ set date Heisei -1 Jan 1
+ get millis
+ exception IllegalArgumentException
+ set date Heisei 1 Jan 1
+ get millis
+ exception IllegalArgumentException
+ set date Heisei 1 Jan 7
+ get millis
+ exception IllegalArgumentException
+ set date Heisei 1 Jan 8
+ get max year
+ eval $result + 1
+ set date Heisei $result Jan 1
+ get millis
+ exception IllegalArgumentException
+
+test Invalid ERA
+ get max era
+ eval $result + 1
+ set era $result # max era + 1
+ get era
+ exception IllegalArgumentException
+ set era 100
+ get era
+ exception IllegalArgumentException
+ set era -100
+ get era
+ exception IllegalArgumentException
+
+test Invalid HOUR_OF_DAY
+ clear all
+ set date Heisei 17 Mar 14
+ set hour_of_day 25
+ get millis
+ exception IllegalArgumentException
+ set hour_of_day -9
+ get millis
+ exception IllegalArgumentException
+
+test Invalid AMPM
+ clear all
+ set date Heisei 17 Mar 14
+ set ampm -1
+ set hour 1
+ get millis
+ exception IllegalArgumentException
+ set ampm 5
+ set hour 1
+ get millis
+ exception IllegalArgumentException
+
+test Invalid HOUR
+ clear all
+ set date Heisei 17 Mar 14
+ set ampm AM
+ set hour 13
+ get millis
+ exception IllegalArgumentException
+ set ampm PM
+ set hour -1
+ get millis
+ exception IllegalArgumentException
+
+test Invalid MINUTE
+ clear all
+ set date Heisei 17 Mar 14
+ set minute 61
+ get millis
+ exception IllegalArgumentException
+ set minute -2
+ get millis
+ exception IllegalArgumentException
+
+test Invalid SECOND
+ clear all
+ set date Heisei 17 Mar 14
+ set second 61
+ get millis
+ exception IllegalArgumentException
+ set second -2
+ get millis
+ exception IllegalArgumentException
+
+test Invalid MILLISECOND
+ clear all
+ set date Heisei 17 Mar 14
+ set millisecond 1000
+ get millis
+ exception IllegalArgumentException
+ set millisecond -2
+ get millis
+ exception IllegalArgumentException
+
+test Invalid ZONE_OFFSET
+ clear all
+ set date Heisei 17 Mar 14
+ set zone_offset -360000000
+ get millis
+ exception IllegalArgumentException
+ set zone_offset -360000000
+ get year
+ exception IllegalArgumentException
+ set zone_offset 360000000
+ get millis
+ exception IllegalArgumentException
+ set zone_offset 360000000
+ get year
+ exception IllegalArgumentException
+
+test Invalid DST_OFFSET
+ clear all
+ set date Heisei 17 Mar 14
+ set dst_offset -360000000
+ get millis
+ exception IllegalArgumentException
+ set dst_offset -360000000
+ get year
+ exception IllegalArgumentException
+ set dst_offset 360000000
+ get millis
+ exception IllegalArgumentException
+ set dst_offset 360000000
+ get year
+ exception IllegalArgumentException
diff --git a/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_minmax.cts b/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_minmax.cts
new file mode 100644
index 0000000000..1faea67908
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_minmax.cts
@@ -0,0 +1,336 @@
+#
+#
+#
+
+locale ja JP JP
+new instance jcal
+new gregorian gcal
+
+# Use GMT+09:00 for max day of year test which depends on time zone
+# offsets.
+
+timezone GMT+09:00
+new instance tokyocal
+
+test Make sure that the maximum year value doesn't depent on era
+ use jcal
+ # Note: the max year value is as of NewEra
+ assign 292276976 $max
+ clear all
+ set date NewEra 1 May 1
+ get millis
+ check max year $max
+ assign $max $maxyear
+
+ clear all
+ set date Heisei 20 May 5
+ get millis
+ check max year $maxyear
+
+ clear all
+ set date Showa 35 May 5
+ get millis
+ check max year $maxyear
+
+ clear all
+ set date BeforeMeiji 1 Jun 1
+ get millis
+ check max year $max
+
+test Max of ERA
+ use jcal
+ # Assumption: NewEra is the current era
+ check maximum era NewEra
+ check leastmax era NewEra
+
+test Actual max MONTH
+ use jcal
+ clear all
+ set date BeforeMeiji 1867 Jan 31
+ check actualmax month Dec
+ # Make sure that the same value is returned after
+ # normalization.
+ get millis
+ check actualmax month Dec
+
+ clear all
+ set date Meiji 45 Mar 31
+ check actualmax month Jul
+ get millis
+ check actualmax month Jul
+
+ clear all
+ set date Taisho 15 June 1
+ check actualmax month Dec
+ get millis
+ check actualmax month Dec
+
+ clear all
+ set date Showa 64 Jan 4
+ check actualmax month Jan
+ get millis
+ check actualmax month Jan
+
+ clear all
+ set date Heisei 31 Jan 4
+ check actualmax month Apr
+ get millis
+ check actualmax month Apr
+
+ clear all
+ set date NewEra 2 Jan 1
+ set year $maxyear
+ check actualmax month Aug
+ get millis
+ check actualmax month Aug
+
+ clear all
+ set date 17 Mar 1
+ check actualmax month Dec
+ get millis
+ check actualmax month Dec
+
+test Actual max DAY_OF_YEAR
+ use jcal
+ clear all
+ set date Meiji 1 Dec 31
+ # Meiji Gan-nen is a leap year.
+ check actualmax day_of_year 366
+ check day_of_year 366
+
+ clear all
+ set date Meiji 45 Jan 1
+ # Meiji 45 or Taishi Gan-nen is also a leap year.
+ check actualmax day_of_year 211 # 31+29+31+30+31+30+29
+ set date Meiji 45 Jul 29
+ check day_of_year 211
+ set date Taisho 1 Jul 31
+ get millis
+ check actualmax day_of_year 155 # 366 - 211
+ set date Taisho 1 Dec 31
+ check day_of_year 155
+
+ clear all
+ set date Taisho 15 Sep 23
+ check actualmax day_of_year 358 # 365 - 7
+ set date Taisho 15 Dec 24
+ check day_of_year 358
+ set date Showa 1 Dec 25
+ check actualmax day_of_year 7
+ set date Showa 1 Dec 31
+ check day_of_year 7
+
+ clear all
+ set date Showa 64 Jan 3
+ check actualmax day_of_year 7
+ set date Showa 64 Jan 7
+ check day_of_year 7
+ set date Heisei 1 Aug 9
+ check actualmax day_of_year 358 # 365 - 7
+ set date Heisei 1 Dec 31
+ check day_of_year 358
+
+ # time zone dependent
+ use tokyocal
+ clear all
+ set date NewEra $maxyear Jan 1
+ # the last date of NewEra is N292276976.08.17T16:12:55.807+0900
+ check actualmax day_of_year 229 # 31+28+31+30+31+30+31+17
+
+test Actual max WEEK_OF_YEAR
+ use jcal
+ clear all
+ set date Meiji 1 Jan 1
+ # Meiji gan-nen is a leap year.
+ check actualmax week_of_year 52
+
+ clear all
+ set date Meiji 45 Jan 1
+ check actualmax week_of_year 30
+ set date Taisho 1 July 31
+ check actualmax week_of_year 22
+
+ clear all
+ set date Taisho 15 Sep 23
+ check actualmax week_of_year 51
+ set date Showa 1 Dec 25
+ check actualmax week_of_year 1
+
+ clear all
+ set date Showa 64 Jan 3
+ check actualmax week_of_year 1
+ set date Heisei 1 Aug 9
+ check actualmax week_of_year 51
+
+ clear all
+ set date Heisei 31 Apr 28
+ check actualmax week_of_year 17
+ set date NewEra 1 Aug 9
+ check actualmax week_of_year 35
+
+ use tokyocal
+ set date NewEra $maxyear Jan 1
+ # the last date of NewEra is N292276976.08.17T16:12:55.807+0900 (Sunday)
+ # The year is equivalent to 2003 (Gregorian).
+ check actualmax week_of_year 34
+
+test Actual max WEEK_OF_MONTH
+ use jcal
+ clear all
+ set date Meiji 45 Jul 1
+ check actualmax week_of_month 5
+ set date Taisho 1 Jul 31
+ check actualmax week_of_month 5
+
+ clear all
+ set date Taisho 15 Dec 1
+ check actualmax week_of_month 5
+ set date Showa 1 Dec 25
+ check actualmax week_of_month 5
+
+ clear all
+ set date Showa 64 Jan 1
+ check actualmax week_of_month 5
+ set date Heisei 1 Jan 8
+ check actualmax week_of_month 5
+
+ clear all
+ set date Heisei 31 Apr 30
+ check actualmax week_of_month 5
+ set date NewEra 1 May 1
+ check actualmax week_of_month 5
+
+ use tokyocal
+ set date NewEra $maxyear Jan 1
+ # the last date of NewEra is N292276976.08.17T16:12:55.807+0900 (Sunday)
+ # The year is equivalent to 2003 (Gregorian).
+ check actualmax week_of_month 4
+
+test Actual max DAY_OF_WEEK_IN_MONTH
+ use jcal
+ clear all
+ set date Meiji 45 Jul 1
+ check actualmax week_of_month 5
+ set date Taisho 1 Jul 31
+ check actualmax week_of_month 5
+
+ clear all
+ set date Taisho 15 Dec 1
+ check actualmax week_of_month 5
+ set date Showa 1 Dec 25
+ check actualmax week_of_month 5
+
+ clear all
+ set date Showa 64 Jan 1
+ check actualmax week_of_month 5
+ set date Heisei 1 Jan 8
+ check actualmax week_of_month 5
+
+ clear all
+ set date Heisei 31 Apr 30
+ check actualmax week_of_month 5
+ set date NewEra 1 May 1
+ check actualmax week_of_month 5
+
+ use tokyocal
+ clear all
+ set date NewEra $maxyear Jan 1
+ # the last date of NewEra is N292276976.08.17T16:12:55.807+0900 (Sunday)
+ # The year is equivalent to 2003 (Gregorian).
+ check actualmax week_of_month 4
+
+test Actual max YEAR
+ use jcal
+ clear all
+ set date BeforeMeiji 1 Jan 1
+ check actualmax year 1867
+
+ set date Meiji 1 Jan 1
+ check actualmax year 45
+
+ set date Meiji 1 Jul 30
+ check actualmax year 44
+
+ set date Taisho 1 Jul 30
+ check actualmax year 15
+
+ set date Taisho 1 Dec 25
+ check actualmax year 14
+
+ set date Showa 2 Jan 1
+ check actualmax year 64
+
+ set date Showa 1 Dec 25
+ check actualmax year 63
+
+ set date Heisei 1 Jan 7
+ check actualmax year 64
+
+ set date Heisei 1 Aug 18
+ check actualmax year 30
+
+ set date NewEra 1 Apr 30
+ check actualmax year 31
+
+ # Date/time beyond the last date in the max year.
+ set date NewEra 1 Aug 18
+ check actualmax year 292276975
+
+test Least max YEAR
+ set date Heisei 17 Mar 1
+ # Taisho is the shortest era, 14 years.
+ # (See above actual max YEAR case.)
+ check leastmax year 14
+
+test Acutual min YEAR
+ # Get minimum values for comparison
+ clear all
+ set era BeforeMeiji
+ get min year
+ assign $result $minyear
+ set date $minyear Dec 31
+ eval $minyear + 1
+ assign $result $minyear_plus_one
+
+ # BeforeMeiji 1 Dec 31 should exist in the minimum year which
+ # should be the same value as the getMinimum() value.
+ set date BeforeMeiji 1 Dec 31
+ check actualmin year $minyear
+
+ # Jan 1 shouldn't exist in the same year. So the actual minimum is
+ # $minyear + 1.
+ set date 1 Jan 1
+ check actualmin year $minyear_plus_one
+
+ # 1 should be returned if it's on a date of the last
+ # year which also exists in the first year of each era.
+ clear all
+ set date Meiji 45 Jan 1
+ check actualmin year 1
+
+ clear all
+ set date Taisho 14 Jul 30
+ check actualmin year 1
+
+ clear all
+ set date Showa 60 Dec 25
+ check actualmin year 1
+
+ clear all
+ set date Heisei 17 Jan 8
+ check actualmin year 1
+
+ # 2 should be returned if it's on a date of the last year which
+ # doesn't exist in the first year of each era. (Meiji is an
+ # exception.)
+ clear all
+ set date Taisho 14 Jul 29
+ check actualmin year 2
+
+ clear all
+ set date Showa 60 Dec 23
+ check actualmin year 2
+
+ clear all
+ set date Heisei 17 Jan 7
+ check actualmin year 2
diff --git a/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_normalization.cts b/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_normalization.cts
new file mode 100644
index 0000000000..eb174ea0a0
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_normalization.cts
@@ -0,0 +1,97 @@
+#
+#
+#
+
+locale ja JP JP
+tz Asia/Tokyo
+new instance jcal
+new gregorian gcal
+
+test Normalize year 0 and -1 (Showa)
+ use jcal
+ clear all
+ set date Showa 1 Jan 1
+ check date Taisho 15 Jan 1
+
+ clear all
+ set date Showa 0 Jan 1
+ check era Taisho
+ check date 14 Jan 1
+
+ clear all
+ set date Showa -1 Jan 1
+ check era Taisho
+ check date 13 Jan 1
+
+test Normalize year max and max+1 (Showa)
+ clear all
+ set date Showa 64 Aug 9
+ check date Heisei 1 Aug 9
+
+ clear all
+ set date Showa 65 Aug 9
+ check date Heisei 2 Aug 9
+
+test Normalize year 0 and -1 (Heisei)
+ use jcal
+ clear all
+ set date Heisei 1 Jan 1
+ check date Showa 64 Jan 1
+
+ clear all
+ set date Heisei 0 Jan 1
+ check date Showa 63 Jan 1
+
+ clear all
+ set date Heisei -1 Jan 1
+ check date Showa 62 Jan 1
+
+test Normalize year max and max+1 (Taisho)
+ clear all
+ set date Taisho 15 Dec 25
+ check date Showa 1 Dec 25
+
+ clear all
+ set date Taisho 16 Dec 25
+ check date Showa 2 Dec 25
+
+test Normalize day of month 0 and -1 (Heisei)
+ use jcal
+ clear all
+ set date Heisei 1 Jan 1
+ check date Showa 64 Jan 1
+
+ clear all
+ set date Heisei 1 Jan 0
+ check date Showa 63 Dec 31
+
+ clear all
+ set date Heisei 1 Jan -1
+ check date Showa 63 Dec 30
+
+test Normalize hour of day -1:00 (Heisei)
+ clear all
+ set era Heisei
+ set datetime 1 Jan 1 0 0 0
+ check era Showa
+ check datetime 64 Jan 1 0 0 0
+
+ clear all
+ set era Heisei
+ set datetime 1 Jan 1 -1 0 0
+ check era Showa
+ check datetime 63 Dec 31 23 0 0
+
+test Normalize hour of day 25:00 (Taisho)
+ clear all
+ set era Taisho
+ set datetime 15 Dec 25 25 0 0
+ check era Showa
+ check datetime 1 Dec 26 1 0 0
+
+test Normalize hour of day 25:00 (Showa)
+ clear all
+ set era Showa
+ set datetime 64 Jan 7 25 0 0
+ check era Heisei
+ check datetime 1 Jan 8 1 0 0
diff --git a/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_roll.cts b/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_roll.cts
new file mode 100644
index 0000000000..fe82f6aa5e
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/japanese/japanese_roll.cts
@@ -0,0 +1,556 @@
+#
+#
+#
+
+# The test cases in this file assume that the first day of week is Sunday
+# and the minimal days in the first week is 1.
+
+locale ja JP JP
+new instance jcal
+
+timezone Asia/Tokyo
+new instance tokyocal
+
+test roll HOUR_OF_DAY
+ use jcal
+ clear all
+ set era Heisei
+ set datetime 1 Jan 8 23 59 59
+ roll hour_of_day 1
+ check datetime 1 Jan 8 0 59 59
+ check ampm AM
+ check hour 0
+ roll hour_of_day -1
+ check datetime 1 Jan 8 23 59 59
+ roll hour_of_day 240
+ check datetime 1 Jan 8 23 59 59
+ roll hour_of_day -240
+ check datetime 1 Jan 8 23 59 59
+
+test roll HOUR
+ use jcal
+ clear all
+ set era Showa
+ set datetime 64 Jan 7 11 59 59
+ get ampm
+ check era Showa
+ check hour 11
+ check ampm AM
+ roll hour 1
+ check hour 0
+ check ampm AM
+ check datetime 64 Jan 7 0 59 59
+ roll hour -1
+ check datetime 64 Jan 7 11 59 59
+ roll hour 240
+ check datetime 64 Jan 7 11 59 59
+ roll hour -240
+ check datetime 64 Jan 7 11 59 59
+
+ clear all
+ set era Showa
+ set datetime 64 Jan 7 23 59 59
+ get ampm
+ check era Showa
+ check hour 11
+ check ampm PM
+ roll hour 1
+ check hour 0
+ check ampm PM
+ check datetime 64 Jan 7 12 59 59
+ roll hour -1
+ check datetime 64 Jan 7 23 59 59
+ roll hour 240
+ check datetime 64 Jan 7 23 59 59
+ roll hour -240
+ check datetime 64 Jan 7 23 59 59
+
+ clear all
+ set era Heisei
+ set datetime 1 Jan 8 23 59 59
+ get ampm
+ check hour 11
+ check ampm PM
+ roll hour 1
+ check hour 0
+ check ampm PM
+ check datetime 1 Jan 8 12 59 59
+ roll hour -1
+ check datetime 1 Jan 8 23 59 59
+ roll hour 240
+ check datetime 1 Jan 8 23 59 59
+ roll hour -240
+ check datetime 1 Jan 8 23 59 59
+
+test roll YEAR
+ clear all
+ set date BeforeMeiji 1867 Jan 1
+ get actualmin year
+ # roll to the min year value of Gregorian (not Julian)
+ roll year 1
+ check date BeforeMeiji $result Jan 1
+ roll year -1
+ check date BeforeMeiji 1867 Jan 1
+
+ clear all
+ set date Meiji 45 Jul 29
+ roll year 1
+ check date Meiji 1 Jul 29
+ roll year -1
+ check date Meiji 45 Jul 29
+
+ clear all
+ set date Meiji 44 Jul 30
+ roll year 1
+ check date Meiji 1 Jul 30
+ roll year -1
+ check date Meiji 44 Jul 30
+
+ clear all
+ set date Taisho 15 Aug 1
+ roll year 1
+ check date Taisho 1 Aug 1
+ roll year -1
+ check date Taisho 15 Aug 1
+
+ clear all
+ set date Taisho 14 Dec 31
+ roll year 1
+ check date Taisho 1 Dec 31
+ roll year -1
+ check date Taisho 14 Dec 31
+
+ clear all
+ set date Showa 63 Feb 1
+ # Neither 64 Feb 1 nor 1 Feb 1 exists in Showa.
+ roll year 1
+ check date Showa 2 Feb 1
+ roll year -1
+ check date Showa 63 Feb 1
+
+ set date Showa 63 Dec 30
+ roll year 1
+ # Showa 1 Dec 30 exists.
+ check date Showa 1 Dec 30
+ roll year -1
+ check date Showa 63 Dec 30
+
+ set date Showa 64 Jan 7
+ roll year 1
+ check date Showa 2 Jan 7
+ roll year -1
+ check date Showa 64 Jan 7
+
+ set date Heisei 31 Apr 30
+ roll year 1
+ check date Heisei 1 Apr 30
+ roll year -1
+ check date Heisei 31 Apr 30
+
+ set date NewEra 2 Apr 30
+ get max year
+ assign $result $hmax
+ roll year -1
+ check date NewEra $hmax Apr 30
+ roll year 1
+ check date NewEra 2 Apr 30
+
+test roll MONTH
+ set date BeforeMeiji 1867 Dec 1
+ roll month 1
+ check date BeforeMeiji 1867 Jan 1
+ roll month -1
+ check date BeforeMeiji 1867 Dec 1
+ roll month 14
+ check date BeforeMeiji 1867 Feb 1
+ roll month -14
+ check date BeforeMeiji 1867 Dec 1
+
+ set date Meiji 1 Dec 1
+ roll month 1
+ check date Meiji 1 Jan 1
+ roll month -1
+ check date Meiji 1 Dec 1
+ roll month 13
+ check date Meiji 1 Jan 1
+ roll month -13
+ check date Meiji 1 Dec 1
+
+ set date Meiji 45 Jun 30
+ roll month 1
+ # Meiji 45 Jun 30 is actually Taisho 1 Jun 30. By the rule of
+ # roll() that year can't be changed, the day of month value
+ # has to be changed ("pin date to month").
+ check date Meiji 45 Jul 29
+ roll month -1
+ # doesn't roll back to Jun 30, but to Jun 29.
+ check date Meiji 45 Jun 29
+
+ set date Meiji 45 Jun 30
+ # Meiji 45 (year) has only 7 months. rolling 14 months must
+ # bring the given date to the same date.
+ roll month 14
+ check date Meiji 45 Jun 30
+ roll month -14
+ check date Meiji 45 Jun 30
+
+ # Taisho Gan-nen (year 1) has only 6 months.
+ set date Taisho 1 Jul 30
+ roll month -1
+ check date Taisho 1 Dec 30
+ roll month 1
+ check date Taisho 1 Jul 30
+ roll month -18
+ check date Taisho 1 Jul 30
+ roll month 18
+ check date Taisho 1 Jul 30
+
+ set date Taisho 15 Jan 20
+ roll month 11
+ check date Taisho 15 Dec 20
+
+ set date Taisho 15 Jan 25
+ roll month 11
+ # Taisho 15 Dec 25 is actually Showa 1 Dec 25. Day of month is
+ # adjusted to the last day of month. ("pin date to month")
+ check date Taisho 15 Dec 24
+
+ set date Showa 1 Dec 25
+ roll month 1
+ check date Showa 1 Dec 25
+ roll month -1
+ check date Showa 1 Dec 25
+ roll month 17
+ check date Showa 1 Dec 25
+ roll month -17
+ check date Showa 1 Dec 25
+
+ set date Showa 64 Jan 7
+ roll month 1
+ check date Showa 64 Jan 7
+
+ set date Heisei 1 Feb 1
+ roll month -1
+ # Heisei starts from Jan 8.
+ check date Heisei 1 Jan 8
+ roll month 1
+ check date Heisei 1 Feb 8
+
+ set date Heisei 1 Feb 8
+ roll month -1
+ check date Heisei 1 Jan 8
+
+ set date Heisei 1 Dec 1
+ roll month 1
+ check date Heisei 1 Jan 8
+ roll month -1
+ check date Heisei 1 Dec 8
+
+ set date Heisei 1 Dec 8
+ roll month 1
+ check date Heisei 1 Jan 8
+ roll month -1
+ check date Heisei 1 Dec 8
+
+ # time zone dependent tests
+ use tokyocal
+ clear all
+
+ set date BeforeMeiji 1 Jan 1
+ get min year
+ assign $result $minyear
+ # actual min date: -292275055.05.17T01:47:04.192+0900
+ set date BeforeMeiji $minyear Dec 31
+ roll month 1
+ check date BeforeMeiji $minyear May 31
+
+ set date BeforeMeiji $minyear Dec 1
+ set timeofday 1 47 4 192
+ roll month 1
+ check date BeforeMeiji $minyear May 17
+ check timeofday 1 47 4 192
+
+ set date BeforeMeiji $minyear Dec 1
+ set timeofday 1 47 4 191
+ roll month 1
+ check date BeforeMeiji $minyear May 18
+ check timeofday 1 47 4 191
+
+ set date NewEra 17 Jan 1
+ get max year
+ assign $result $max
+ set date NewEra $max Jul 28
+ roll month 1
+ check date NewEra $max Aug 17
+ set date NewEra $max Jul 28
+ set timeofday 23 59 59 999
+ roll month 1
+ check date NewEra $max Aug 16
+ check timeofday 23 59 59 999
+
+test roll WEEK_OF_YEAR
+ use jcal
+ clear all
+ # 1867 Dec 23 is Monday.
+ set date BeforeMeiji 1867 Dec 23
+ roll week_of_year 1
+ check day_of_week Mon
+ check date BeforeMeiji 1867 Jan 7
+ roll week_of_year -1
+ check day_of_week Mon
+ check date BeforeMeiji 1867 Dec 23
+ roll week_of_year 26
+ check day_of_week Mon
+ check date BeforeMeiji 1867 Jul 1
+ roll week_of_year -26
+ check day_of_week Mon
+ check date BeforeMeiji 1867 Dec 23
+
+ # 1867 Dec 23 is Wednesday.
+ set date Meiji 1 Dec 23
+ roll week_of_year 1
+ check day_of_week Wed
+ check date Meiji 1 Jan 1
+ roll week_of_year -1
+ check day_of_week Wed
+ check date Meiji 1 Dec 23
+ roll week_of_year 26
+ check day_of_week Wed
+ check date Meiji 1 Jun 24
+ roll week_of_year -26
+ check day_of_week Wed
+ check date Meiji 1 Dec 23
+
+ # Meiji 45 July 22 is Monday.
+ set date Meiji 45 Jul 22
+ # the next week if the first week of Taisho 1
+ roll week_of_year 1
+ check day_of_week Mon
+ check date Meiji 45 Jan 1
+ roll week_of_year -1
+ check day_of_week Mon
+ check date Meiji 45 Jul 22
+ roll week_of_year 26
+ check day_of_week Mon
+ check date Meiji 45 Jun 24
+
+ # Taisho Gan-nen (year 1) July 30 is Tuesday.
+ set date Taisho 1 Jul 30
+ roll week_of_year -1
+ # Taisho Gen-nen December 31 is the first week of the next year.
+ check day_of_week Tue
+ check date Taisho 1 Dec 24
+ roll week_of_year 1
+ check day_of_week Tue
+ check date Taisho 1 Jul 30
+ roll week_of_year 26
+ check day_of_week Tue
+ check date Taisho 1 Aug 27
+ roll week_of_year -26
+ check day_of_week Tue
+ check date Taisho 1 Jul 30
+
+ # Taisho 15 January 7 is Thursday.
+ set date Taisho 15 Jan 7
+ roll week_of_year -1
+ check day_of_week Thu
+ check date Taisho 15 Dec 16
+ roll week_of_year 1
+ check day_of_week Thu
+ check date Taisho 15 Jan 7
+
+ roll week_of_year 51
+ check day_of_week Thu
+ check date Taisho 15 Jan 14
+
+ # Showa Gan-nen December 30 is Thursday. Showa Gan-nen has
+ # only one week. Rolling any number of weeks brings to the
+ # same date.
+ set date Showa 1 Dec 30
+ roll week_of_year 1
+ check day_of_week Thu
+ check date Showa 1 Dec 30
+ roll week_of_year -1
+ check day_of_week Thu
+ check date Showa 1 Dec 30
+ roll week_of_year 26
+ check day_of_week Thu
+ check date Showa 1 Dec 30
+ roll week_of_year -26
+ check day_of_week Thu
+ check date Showa 1 Dec 30
+
+ # Showa 64 January 7 is Saturday. The year has only one week.
+ set date Showa 64 Jan 7
+ roll week_of_year 1
+ check day_of_week Sat
+ check date Showa 64 Jan 7
+ roll week_of_year -1
+ check day_of_week Sat
+ check date Showa 64 Jan 7
+ roll week_of_year 26
+ check day_of_week Sat
+ check date Showa 64 Jan 7
+ roll week_of_year -26
+ check day_of_week Sat
+ check date Showa 64 Jan 7
+
+ # Heisei Gan-nen January 14 is Saturday.
+ set date Heisei 1 Jan 14
+ roll week_of_year -1
+ check day_of_week Sat
+ check date Heisei 1 Dec 30
+ roll week_of_year 1
+ check day_of_week Sat
+ check date Heisei 1 Jan 14
+ roll week_of_year -26
+ check day_of_week Sat
+ check date Heisei 1 Jul 8
+ roll week_of_year 26
+ check day_of_week Sat
+ check date Heisei 1 Jan 14
+
+ # Heisei Gan-nen December 1 is Friday.
+ set date Heisei 1 Dec 1
+ roll week_of_year 5
+ check day_of_week Fri
+ check date Heisei 1 Jan 13
+ roll week_of_year -5
+ check day_of_week Fri
+ check date Heisei 1 Dec 1
+ roll week_of_year 55
+ check day_of_week Fri
+ check date Heisei 1 Dec 29
+
+ use tokyocal
+ clear all
+
+ set date BeforeMeiji $minyear Dec 25
+ check day_of_week Sat
+ roll week_of_year 1
+ check day_of_week Sat
+ check date BeforeMeiji $minyear May 22
+ roll week_of_year -1
+ check day_of_week Sat
+ check date BeforeMeiji $minyear Dec 25
+
+test WEEK_OF_MONTH
+ # Needs to wait for 6191841 fix. (WEEK_OF_MONTH needs to change
+ # ERA and YEAR in a transition month.)
+
+test DAY_OF_MONTH
+ # Needs to wait for 6191841 fix. (DAY_OF_MONTH needs to change
+ # ERA and YEAR in a transition month.)
+
+test DAY_OF_YEAR
+ use jcal
+ clear all
+
+ # 1867 is a regular Gregorian year.
+ set date BeforeMeiji 1867 Dec 31
+ roll day_of_year 1
+ check date BeforeMeiji 1867 Jan 1
+ roll day_of_year -1
+ check date BeforeMeiji 1867 Dec 31
+ roll day_of_year 26
+ check date BeforeMeiji 1867 Jan 26
+ roll day_of_year -26
+ check date BeforeMeiji 1867 Dec 31
+
+ # Meiji 1 starts from Jan 1. It's a regular year as well.
+ set date Meiji 1 Dec 31
+ roll day_of_year 1
+ check date Meiji 1 Jan 1
+ roll day_of_year -1
+ check date Meiji 1 Dec 31
+ roll day_of_year 26
+ check date Meiji 1 Jan 26
+ roll day_of_year -26
+ check date Meiji 1 Dec 31
+
+ # The last year of Meiji (45) has an irregularity. Meiji 45
+ # July 30 is actually Taisho 1 July 30.
+ set date Meiji 45 Jul 29
+ roll day_of_year 1
+ check date Meiji 45 Jan 1
+ roll day_of_year -1
+ check date Meiji 45 Jul 29
+ roll day_of_year 26
+ check date Meiji 45 Jan 26
+ roll day_of_year -26
+ check date Meiji 45 Jul 29
+
+ # The first day of Taisho, July 30.
+ set date Taisho 1 Jul 30
+ roll day_of_year -1
+ check date Taisho 1 Dec 31
+ roll day_of_year 1
+ check date Taisho 1 Jul 30
+ roll day_of_year 26
+ check date Taisho 1 Aug 25
+ roll day_of_year -26
+ check date Taisho 1 Jul 30
+
+ set date Taisho 15 Jan 1
+ roll day_of_year -1
+ check date Taisho 15 Dec 24
+ roll day_of_year 1
+ check date Taisho 15 Jan 1
+
+ set date Showa 1 Dec 31
+ roll day_of_year 1
+ check date Showa 1 Dec 25
+ roll day_of_year -1
+ check date Showa 1 Dec 31
+ roll day_of_year 26
+ # 26 % 7 = 5
+ check date Showa 1 Dec 29
+ roll day_of_year -26
+ check date Showa 1 Dec 31
+
+ set date Showa 64 Jan 7
+ roll day_of_year 1
+ check date Showa 64 Jan 1
+ roll day_of_year -1
+ check date Showa 64 Jan 7
+ roll day_of_year 26
+ # 26 % 7 = 5
+ check date Showa 64 Jan 5
+ roll day_of_year -26
+ check date Showa 64 Jan 7
+
+ set date Heisei 1 Jan 8
+ roll day_of_year -1
+ check date Heisei 1 Dec 31
+ roll day_of_year 1
+ check date Heisei 1 Jan 8
+ roll day_of_year -26
+ check date Heisei 1 Dec 6
+ roll day_of_year 26
+ check date Heisei 1 Jan 8
+
+ set date Heisei 1 Dec 31
+ roll day_of_year 5
+ check date Heisei 1 Jan 12
+ roll day_of_year -5
+ check date Heisei 1 Dec 31
+ roll day_of_year 55
+ check date Heisei 1 Mar 3
+ roll day_of_year -55
+ check date Heisei 1 Dec 31
+
+ use tokyocal
+ clear all
+
+ set date BeforeMeiji $minyear Dec 31
+ set timeofday 1 47 4 192
+ roll day_of_year 1
+ check date BeforeMeiji $minyear May 17
+ check timeofday 1 47 4 192
+ roll day_of_year -1
+ check date BeforeMeiji $minyear Dec 31
+ check timeofday 1 47 4 192
+
+test DAY_OF_WEEK_IN_MONTH
+ use jcal
+ clear all
diff --git a/test/java/util/Calendar/CalendarTestScripts/params/lenient.cts b/test/java/util/Calendar/CalendarTestScripts/params/lenient.cts
new file mode 100644
index 0000000000..a8ab80d53d
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/params/lenient.cts
@@ -0,0 +1,5 @@
+#
+#
+#
+
+set lenient
diff --git a/test/java/util/Calendar/CalendarTestScripts/params/non-lenient.cts b/test/java/util/Calendar/CalendarTestScripts/params/non-lenient.cts
new file mode 100644
index 0000000000..da0742d869
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/params/non-lenient.cts
@@ -0,0 +1,5 @@
+#
+#
+#
+
+set non-lenient
diff --git a/test/java/util/Calendar/CalendarTestScripts/timezones/tz_japan.cts b/test/java/util/Calendar/CalendarTestScripts/timezones/tz_japan.cts
new file mode 100644
index 0000000000..33baa96228
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/timezones/tz_japan.cts
@@ -0,0 +1,5 @@
+#
+#
+#
+
+timezone Asia/Tokyo
diff --git a/test/java/util/Calendar/CalendarTestScripts/timezones/tz_novosibirsk.cts b/test/java/util/Calendar/CalendarTestScripts/timezones/tz_novosibirsk.cts
new file mode 100644
index 0000000000..4602d74fb0
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/timezones/tz_novosibirsk.cts
@@ -0,0 +1,5 @@
+#
+#
+#
+
+timezone Asia/Novosibirsk
diff --git a/test/java/util/Calendar/CalendarTestScripts/timezones/tz_pst.cts b/test/java/util/Calendar/CalendarTestScripts/timezones/tz_pst.cts
new file mode 100644
index 0000000000..ffaaa30e26
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/timezones/tz_pst.cts
@@ -0,0 +1,5 @@
+#
+#
+#
+
+timezone America/Los_Angeles
diff --git a/test/java/util/Calendar/CalendarTestScripts/timezones/tz_sydney.cts b/test/java/util/Calendar/CalendarTestScripts/timezones/tz_sydney.cts
new file mode 100644
index 0000000000..b3be00dbe6
--- /dev/null
+++ b/test/java/util/Calendar/CalendarTestScripts/timezones/tz_sydney.cts
@@ -0,0 +1,5 @@
+#
+#
+#
+
+timezone Australia/Sydney