diff --git a/src/share/classes/sun/util/BuddhistCalendar.java b/src/share/classes/sun/util/BuddhistCalendar.java index 8c7916aa430d06498ce51ff57e6aa1f57b3505fa..37df725fdc473594af23e024f50ab5627393d4a2 100644 --- a/src/share/classes/sun/util/BuddhistCalendar.java +++ b/src/share/classes/sun/util/BuddhistCalendar.java @@ -25,6 +25,8 @@ package sun.util; +import java.io.IOException; +import java.io.ObjectInputStream; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; @@ -42,7 +44,7 @@ public class BuddhistCalendar extends GregorianCalendar { private static final long serialVersionUID = -8527488697350388578L; - private static final int buddhistOffset = 543; + private static final int BUDDHIST_YEAR_OFFSET = 543; /////////////// // Constructors @@ -103,7 +105,7 @@ public class BuddhistCalendar extends GregorianCalendar { * Generates the hash code for the BuddhistCalendar object */ public int hashCode() { - return super.hashCode() ^ buddhistOffset; + return super.hashCode() ^ BUDDHIST_YEAR_OFFSET; } /** @@ -141,6 +143,8 @@ public class BuddhistCalendar extends GregorianCalendar { public void add(int field, int amount) { int savedYearOffset = yearOffset; + // To let the superclass calculate date-time values correctly, + // temporarily make this GregorianCalendar. yearOffset = 0; try { super.add(field, amount); @@ -159,6 +163,8 @@ public class BuddhistCalendar extends GregorianCalendar { public void roll(int field, int amount) { int savedYearOffset = yearOffset; + // To let the superclass calculate date-time values correctly, + // temporarily make this GregorianCalendar. yearOffset = 0; try { super.roll(field, amount); @@ -246,6 +252,8 @@ public class BuddhistCalendar extends GregorianCalendar { */ public int getActualMaximum(int field) { int savedYearOffset = yearOffset; + // To let the superclass calculate date-time values correctly, + // temporarily make this GregorianCalendar. yearOffset = 0; try { return super.getActualMaximum(field); @@ -275,11 +283,16 @@ public class BuddhistCalendar extends GregorianCalendar { // Skip the year number while (Character.isDigit(s.charAt(p++))) ; - int year = internalGet(YEAR) + buddhistOffset; + int year = internalGet(YEAR) + BUDDHIST_YEAR_OFFSET; sb.append(year).append(s.substring(p - 1)); return sb.toString(); } - private transient int yearOffset = buddhistOffset; + private transient int yearOffset = BUDDHIST_YEAR_OFFSET; + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + yearOffset = BUDDHIST_YEAR_OFFSET; + } } diff --git a/test/sun/util/calendar/Bug6653944.java b/test/sun/util/calendar/Bug6653944.java new file mode 100644 index 0000000000000000000000000000000000000000..59c8b734c977bc17bdc03f936443d383006bfc97 --- /dev/null +++ b/test/sun/util/calendar/Bug6653944.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + *@test + *@bug 6653944 + *@summary Deserialization tests for YEAR calculcations + */ + +import java.io.*; +import java.util.*; + +public class Bug6653944 { + private static int errorCount = 0; + + public static void main(String[] args) throws Exception { + Calendar buddhist = Calendar.getInstance(new Locale("th", "TH")); + int expectedYear = buddhist.get(Calendar.YEAR); + + Calendar deserialized = (Calendar) deserialize(serialize(buddhist)); + compare(deserialized, buddhist); + + int deserializedYear = deserialized.get(Calendar.YEAR); + compare(deserializedYear, expectedYear); + + // test add(YEAR, n). + buddhist.add(Calendar.YEAR, 12); + expectedYear = buddhist.get(Calendar.YEAR); + deserialized.add(Calendar.YEAR, 12); + deserializedYear = deserialized.get(Calendar.YEAR); + compare(deserialized, buddhist); + compare(deserializedYear, expectedYear); + + if (errorCount > 0) { + throw new RuntimeException("Bug6653944: failed"); + } + } + + private static void compare(int got, int expected) { + if (got != expected) { + System.err.println("got " + got + ", expected " + expected); + errorCount++; + } + } + + private static void compare(Calendar got, Calendar expected) { + if (!got.equals(expected)) { + System.err.println("got " + got + ", expected " + expected); + errorCount++; + } + } + + private static byte[] serialize(Serializable obj) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(obj); + oos.close(); + return baos.toByteArray(); + } + + private static Object deserialize(byte[] data) throws Exception { + ByteArrayInputStream bais = new ByteArrayInputStream(data); + ObjectInputStream ois = new ObjectInputStream(bais); + return ois.readObject(); + } +}