1 /* 2 * Copyright (c) 2000, 2011, 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 sun.util.locale.provider.CalendarDataUtility; 29 import java.io.IOException; 30 import java.io.ObjectInputStream; 31 import java.util.GregorianCalendar; 32 import java.util.Locale; 33 import java.util.Map; 34 import java.util.TimeZone; 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 public boolean equals(Object obj) { 104 return obj instanceof BuddhistCalendar 105 && super.equals(obj); 106 } 107 108 /** 109 * Override hashCode. 110 * Generates the hash code for the BuddhistCalendar object 111 */ 112 public int hashCode() { 113 return super.hashCode() ^ BUDDHIST_YEAR_OFFSET; 114 } 115 116 /** 117 * Gets the value for a given time field. 118 * @param field the given time field. 119 * @return the value for the given time field. 120 */ 121 public int get(int field) 122 { 123 if (field == YEAR) { 124 return super.get(field) + yearOffset; 125 } 126 return super.get(field); 127 } 128 129 /** 130 * Sets the time field with the given value. 131 * @param field the given time field. 132 * @param value the value to be set for the given time field. 133 */ 134 public void set(int field, int value) 135 { 136 if (field == YEAR) { 137 super.set(field, value - yearOffset); 138 } else { 139 super.set(field, value); 140 } 141 } 142 143 /** 144 * Adds the specified (signed) amount of time to the given time field. 145 * @param field the time field. 146 * @param amount the amount of date or time to be added to the field. 147 */ 148 public void add(int field, int amount) 149 { 150 int savedYearOffset = yearOffset; 151 // To let the superclass calculate date-time values correctly, 152 // temporarily make this GregorianCalendar. 153 yearOffset = 0; 154 try { 155 super.add(field, amount); 156 } finally { 157 yearOffset = savedYearOffset; 158 } 159 } 160 161 /** 162 * Add to field a signed amount without changing larger fields. 163 * A negative roll amount means to subtract from field without changing 164 * larger fields. 165 * @param field the time field. 166 * @param amount the signed amount to add to <code>field</code>. 167 */ 168 public void roll(int field, int amount) 169 { 170 int savedYearOffset = yearOffset; 171 // To let the superclass calculate date-time values correctly, 172 // temporarily make this GregorianCalendar. 173 yearOffset = 0; 174 try { 175 super.roll(field, amount); 176 } finally { 177 yearOffset = savedYearOffset; 178 } 179 } 180 181 public String getDisplayName(int field, int style, Locale locale) { 182 if (field != ERA) { 183 return super.getDisplayName(field, style, locale); 184 } 185 186 String name = CalendarDataUtility.retrieveFieldValueName("buddhist", field, get(field), style, locale); 187 return name; 188 } 189 190 public Map<String,Integer> getDisplayNames(int field, int style, Locale locale) { 191 if (field != ERA) { 192 return super.getDisplayNames(field, style, locale); 193 } 194 Map<String, Integer> names = CalendarDataUtility.retrieveFieldValueNames("buddhist", field, style, locale); 195 return names; 196 } 197 198 /** 199 * Returns the maximum value that this field could have, given the 200 * current date. For example, with the date "Feb 3, 2540" and the 201 * <code>DAY_OF_MONTH</code> field, the actual maximum is 28; for 202 * "Feb 3, 2539" it is 29. 203 * 204 * @param field the field to determine the maximum of 205 * @return the maximum of the given field for the current date of this Calendar 206 */ 207 public int getActualMaximum(int field) { 208 int savedYearOffset = yearOffset; 209 // To let the superclass calculate date-time values correctly, 210 // temporarily make this GregorianCalendar. 211 yearOffset = 0; 212 try { 213 return super.getActualMaximum(field); 214 } finally { 215 yearOffset = savedYearOffset; 216 } 217 } 218 219 public String toString() { 220 // The super class produces a String with the Gregorian year 221 // value (or '?') 222 String s = super.toString(); 223 // If the YEAR field is UNSET, then return the Gregorian string. 224 if (!isSet(YEAR)) { 225 return s; 226 } 227 228 final String yearField = "YEAR="; 229 int p = s.indexOf(yearField); 230 // If the string doesn't include the year value for some 231 // reason, then return the Gregorian string. 232 if (p == -1) { 233 return s; 234 } 235 p += yearField.length(); 236 StringBuilder sb = new StringBuilder(s.substring(0, p)); 237 // Skip the year number 238 while (Character.isDigit(s.charAt(p++))) 239 ; 240 int year = internalGet(YEAR) + BUDDHIST_YEAR_OFFSET; 241 sb.append(year).append(s.substring(p - 1)); 242 return sb.toString(); 243 } 244 245 private transient int yearOffset = BUDDHIST_YEAR_OFFSET; 246 247 private void readObject(ObjectInputStream stream) 248 throws IOException, ClassNotFoundException { 249 stream.defaultReadObject(); 250 yearOffset = BUDDHIST_YEAR_OFFSET; 251 } 252 }