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 @java.io.Serial 43 private static final long serialVersionUID = -8527488697350388578L; 44 45 private static final int BUDDHIST_YEAR_OFFSET = 543; 46 47 /////////////// 48 // Constructors 49 /////////////// 50 51 /** 52 * Constructs a default BuddhistCalendar using the current time 53 * in the default time zone with the default locale. 54 */ 55 public BuddhistCalendar() { 56 super(); 57 } 58 59 /** 60 * Constructs a BuddhistCalendar based on the current time 61 * in the given time zone with the default locale. 62 * @param zone the given time zone. 63 */ 64 public BuddhistCalendar(TimeZone zone) { 65 super(zone); 66 } 67 68 /** 69 * Constructs a BuddhistCalendar based on the current time 70 * in the default time zone with the given locale. 71 * @param aLocale the given locale. 72 */ 73 public BuddhistCalendar(Locale aLocale) { 74 super(aLocale); 75 } 76 77 /** 78 * Constructs a BuddhistCalendar based on the current time 79 * in the given time zone with the given locale. 80 * @param zone the given time zone. 81 * @param aLocale the given locale. 82 */ 83 public BuddhistCalendar(TimeZone zone, Locale aLocale) { 84 super(zone, aLocale); 85 } 86 87 ///////////////// 88 // Public methods 89 ///////////////// 90 91 /** 92 * Returns {@code "buddhist"} as the calendar type of this Calendar. 93 */ 94 @Override 95 public String getCalendarType() { 96 return "buddhist"; 97 } 98 99 /** 100 * Compares this BuddhistCalendar to an object reference. 101 * @param obj the object reference with which to compare 102 * @return true if this object is equal to <code>obj</code>; false otherwise 103 */ 104 @Override 105 public boolean equals(Object obj) { 106 return obj instanceof BuddhistCalendar 107 && super.equals(obj); 108 } 109 110 /** 111 * Override hashCode. 112 * Generates the hash code for the BuddhistCalendar object 113 */ 114 @Override 115 public int hashCode() { 116 return super.hashCode() ^ BUDDHIST_YEAR_OFFSET; 117 } 118 119 /** 120 * Gets the value for a given time field. 121 * @param field the given time field. 122 * @return the value for the given time field. 123 */ 124 @Override 125 public int get(int field) 126 { 127 if (field == YEAR) { 128 return super.get(field) + yearOffset; 129 } 130 return super.get(field); 131 } 132 133 /** 134 * Sets the time field with the given value. 135 * @param field the given time field. 136 * @param value the value to be set for the given time field. 137 */ 138 @Override 139 public void set(int field, int value) 140 { 141 if (field == YEAR) { 142 super.set(field, value - yearOffset); 143 } else { 144 super.set(field, value); 145 } 146 } 147 148 /** 149 * Adds the specified (signed) amount of time to the given time field. 150 * @param field the time field. 151 * @param amount the amount of date or time to be added to the field. 152 */ 153 @Override 154 public void add(int field, int amount) 155 { 156 int savedYearOffset = yearOffset; 157 // To let the superclass calculate date-time values correctly, 158 // temporarily make this GregorianCalendar. 159 yearOffset = 0; 160 try { 161 super.add(field, amount); 162 } finally { 163 yearOffset = savedYearOffset; 164 } 165 } 166 167 /** 168 * Add to field a signed amount without changing larger fields. 169 * A negative roll amount means to subtract from field without changing 170 * larger fields. 171 * @param field the time field. 172 * @param amount the signed amount to add to <code>field</code>. 173 */ 174 @Override 175 public void roll(int field, int amount) 176 { 177 int savedYearOffset = yearOffset; 178 // To let the superclass calculate date-time values correctly, 179 // temporarily make this GregorianCalendar. 180 yearOffset = 0; 181 try { 182 super.roll(field, amount); 183 } finally { 184 yearOffset = savedYearOffset; 185 } 186 } 187 188 @Override 189 public String getDisplayName(int field, int style, Locale locale) { 190 if (field != ERA) { 191 return super.getDisplayName(field, style, locale); 192 } 193 194 return CalendarDataUtility.retrieveFieldValueName("buddhist", field, get(field), style, locale); 195 } 196 197 @Override 198 public Map<String,Integer> getDisplayNames(int field, int style, Locale locale) { 199 if (field != ERA) { 200 return super.getDisplayNames(field, style, locale); 201 } 202 return CalendarDataUtility.retrieveFieldValueNames("buddhist", field, style, locale); 203 } 204 205 /** 206 * Returns the maximum value that this field could have, given the 207 * current date. For example, with the date "Feb 3, 2540" and the 208 * <code>DAY_OF_MONTH</code> field, the actual maximum is 28; for 209 * "Feb 3, 2539" it is 29. 210 * 211 * @param field the field to determine the maximum of 212 * @return the maximum of the given field for the current date of this Calendar 213 */ 214 @Override 215 public int getActualMaximum(int field) { 216 int savedYearOffset = yearOffset; 217 // To let the superclass calculate date-time values correctly, 218 // temporarily make this GregorianCalendar. 219 yearOffset = 0; 220 try { 221 return super.getActualMaximum(field); 222 } finally { 223 yearOffset = savedYearOffset; 224 } 225 } 226 227 @Override 228 @SuppressWarnings("empty-statement") 229 public String toString() { 230 // The super class produces a String with the Gregorian year 231 // value (or '?') 232 String s = super.toString(); 233 // If the YEAR field is UNSET, then return the Gregorian string. 234 if (!isSet(YEAR)) { 235 return s; 236 } 237 238 final String yearField = "YEAR="; 239 int p = s.indexOf(yearField); 240 // If the string doesn't include the year value for some 241 // reason, then return the Gregorian string. 242 if (p == -1) { 243 return s; 244 } 245 p += yearField.length(); 246 StringBuilder sb = new StringBuilder(s.length() + 10); 247 sb.append(s, 0, p); 248 // Skip the year number 249 while (Character.isDigit(s.charAt(p++))) 250 ; 251 int year = internalGet(YEAR) + BUDDHIST_YEAR_OFFSET; 252 sb.append(year).append(s, p - 1, s.length()); 253 return sb.toString(); 254 } 255 256 private transient int yearOffset = BUDDHIST_YEAR_OFFSET; 257 258 @java.io.Serial 259 private void readObject(ObjectInputStream stream) 260 throws IOException, ClassNotFoundException { 261 stream.defaultReadObject(); 262 yearOffset = BUDDHIST_YEAR_OFFSET; 263 } 264 }