1 /* 2 * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.util; 27 28 import java.io.IOException; 29 import java.io.ObjectInputStream; 30 import java.util.GregorianCalendar; 31 import java.util.Locale; 32 import java.util.Map; 33 import java.util.TimeZone; 34 import sun.util.locale.provider.CalendarDataUtility; 35 36 public class BuddhistCalendar extends GregorianCalendar { 37 38 ////////////////// 39 // Class Variables 40 ////////////////// 41 42 private static final long serialVersionUID = -8527488697350388578L; 43 44 private static final int BUDDHIST_YEAR_OFFSET = 543; 45 46 /////////////// 47 // Constructors 48 /////////////// 49 50 /** 51 * Constructs a default BuddhistCalendar using the current time 52 * in the default time zone with the default locale. 53 */ 54 public BuddhistCalendar() { 55 super(); 56 } 57 58 /** 59 * Constructs a BuddhistCalendar based on the current time 60 * in the given time zone with the default locale. 61 * @param zone the given time zone. 62 */ 63 public BuddhistCalendar(TimeZone zone) { 64 super(zone); 65 } 66 67 /** 68 * Constructs a BuddhistCalendar based on the current time 69 * in the default time zone with the given locale. 70 * @param aLocale the given locale. 71 */ 72 public BuddhistCalendar(Locale aLocale) { 73 super(aLocale); 74 } 75 76 /** 77 * Constructs a BuddhistCalendar based on the current time 78 * in the given time zone with the given locale. 79 * @param zone the given time zone. 80 * @param aLocale the given locale. 81 */ 82 public BuddhistCalendar(TimeZone zone, Locale aLocale) { 83 super(zone, aLocale); 84 } 85 86 ///////////////// 87 // Public methods 88 ///////////////// 89 90 /** 91 * Returns {@code "buddhist"} as the calendar type of this Calendar. 92 */ 93 @Override 94 public String getCalendarType() { 95 return "buddhist"; 96 } 97 98 /** 99 * Compares this BuddhistCalendar to an object reference. 100 * @param obj the object reference with which to compare 101 * @return true if this object is equal to <code>obj</code>; false otherwise 102 */ 103 @Override 104 public boolean equals(Object obj) { 105 return obj instanceof BuddhistCalendar 106 && super.equals(obj); 107 } 108 109 /** 110 * Override hashCode. 111 * Generates the hash code for the BuddhistCalendar object 112 */ 113 @Override 114 public int hashCode() { 115 return super.hashCode() ^ BUDDHIST_YEAR_OFFSET; 116 } 117 118 /** 119 * Gets the value for a given time field. 120 * @param field the given time field. 121 * @return the value for the given time field. 122 */ 123 @Override 124 public int get(int field) 125 { 126 if (field == YEAR) { 127 return super.get(field) + yearOffset; 128 } 129 return super.get(field); 130 } 131 132 /** 133 * Sets the time field with the given value. 134 * @param field the given time field. 135 * @param value the value to be set for the given time field. 136 */ 137 @Override 138 public void set(int field, int value) 139 { 140 if (field == YEAR) { 141 super.set(field, value - yearOffset); 142 } else { 143 super.set(field, value); 144 } 145 } 146 147 /** 148 * Adds the specified (signed) amount of time to the given time field. 149 * @param field the time field. 150 * @param amount the amount of date or time to be added to the field. 151 */ 152 @Override 153 public void add(int field, int amount) 154 { 155 int savedYearOffset = yearOffset; 156 // To let the superclass calculate date-time values correctly, 157 // temporarily make this GregorianCalendar. 158 yearOffset = 0; 159 try { 160 super.add(field, amount); 161 } finally { 162 yearOffset = savedYearOffset; 163 } 164 } 165 166 /** 167 * Add to field a signed amount without changing larger fields. 168 * A negative roll amount means to subtract from field without changing 169 * larger fields. 170 * @param field the time field. 171 * @param amount the signed amount to add to <code>field</code>. 172 */ 173 @Override 174 public void roll(int field, int amount) 175 { 176 int savedYearOffset = yearOffset; 177 // To let the superclass calculate date-time values correctly, 178 // temporarily make this GregorianCalendar. 179 yearOffset = 0; 180 try { 181 super.roll(field, amount); 182 } finally { 183 yearOffset = savedYearOffset; 184 } 185 } 186 187 @Override 188 public String getDisplayName(int field, int style, Locale locale) { 189 if (field != ERA) { 190 return super.getDisplayName(field, style, locale); 191 } 192 193 return CalendarDataUtility.retrieveFieldValueName("buddhist", field, get(field), style, locale); 194 } 195 196 @Override 197 public Map<String,Integer> getDisplayNames(int field, int style, Locale locale) { 198 if (field != ERA) { 199 return super.getDisplayNames(field, style, locale); 200 } 201 return CalendarDataUtility.retrieveFieldValueNames("buddhist", field, style, locale); 202 } 203 204 /** 205 * Returns the maximum value that this field could have, given the 206 * current date. For example, with the date "Feb 3, 2540" and the 207 * <code>DAY_OF_MONTH</code> field, the actual maximum is 28; for 208 * "Feb 3, 2539" it is 29. 209 * 210 * @param field the field to determine the maximum of 211 * @return the maximum of the given field for the current date of this Calendar 212 */ 213 @Override 214 public int getActualMaximum(int field) { 215 int savedYearOffset = yearOffset; 216 // To let the superclass calculate date-time values correctly, 217 // temporarily make this GregorianCalendar. 218 yearOffset = 0; 219 try { 220 return super.getActualMaximum(field); 221 } finally { 222 yearOffset = savedYearOffset; 223 } 224 } 225 226 @Override 227 @SuppressWarnings("empty-statement") 228 public String toString() { 229 // The super class produces a String with the Gregorian year 230 // value (or '?') 231 String s = super.toString(); 232 // If the YEAR field is UNSET, then return the Gregorian string. 233 if (!isSet(YEAR)) { 234 return s; 235 } 236 237 final String yearField = "YEAR="; 238 int p = s.indexOf(yearField); 239 // If the string doesn't include the year value for some 240 // reason, then return the Gregorian string. 241 if (p == -1) { 242 return s; 243 } 244 p += yearField.length(); 245 StringBuilder sb = new StringBuilder(s.substring(0, p)); 246 // Skip the year number 247 while (Character.isDigit(s.charAt(p++))) 248 ; 249 int year = internalGet(YEAR) + BUDDHIST_YEAR_OFFSET; 250 sb.append(year).append(s.substring(p - 1)); 251 return sb.toString(); 252 } 253 254 private transient int yearOffset = BUDDHIST_YEAR_OFFSET; 255 256 private void readObject(ObjectInputStream stream) 257 throws IOException, ClassNotFoundException { 258 stream.defaultReadObject(); 259 yearOffset = BUDDHIST_YEAR_OFFSET; 260 } 261 }