1 /*
2 * Copyright (c) 2000, 2010, 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.Calendar;
31 import java.util.GregorianCalendar;
32 import java.util.HashMap;
33 import java.util.Locale;
34 import java.util.Map;
35 import java.util.ResourceBundle;
36 import java.util.TimeZone;
37 import sun.util.resources.LocaleData;
38
39 public class BuddhistCalendar extends GregorianCalendar {
40
41 //////////////////
42 // Class Variables
43 //////////////////
44
45 private static final long serialVersionUID = -8527488697350388578L;
46
47 private static final int BUDDHIST_YEAR_OFFSET = 543;
48
49 ///////////////
50 // Constructors
51 ///////////////
52
53 /**
54 * Constructs a default BuddhistCalendar using the current time
55 * in the default time zone with the default locale.
56 */
57 public BuddhistCalendar() {
74 */
75 public BuddhistCalendar(Locale aLocale) {
76 super(aLocale);
77 }
78
79 /**
80 * Constructs a BuddhistCalendar based on the current time
81 * in the given time zone with the given locale.
82 * @param zone the given time zone.
83 * @param aLocale the given locale.
84 */
85 public BuddhistCalendar(TimeZone zone, Locale aLocale) {
86 super(zone, aLocale);
87 }
88
89 /////////////////
90 // Public methods
91 /////////////////
92
93 /**
94 * Compares this BuddhistCalendar to an object reference.
95 * @param obj the object reference with which to compare
96 * @return true if this object is equal to <code>obj</code>; false otherwise
97 */
98 public boolean equals(Object obj) {
99 return obj instanceof BuddhistCalendar
100 && super.equals(obj);
101 }
102
103 /**
104 * Override hashCode.
105 * Generates the hash code for the BuddhistCalendar object
106 */
107 public int hashCode() {
108 return super.hashCode() ^ BUDDHIST_YEAR_OFFSET;
109 }
110
111 /**
112 * Gets the value for a given time field.
113 * @param field the given time field.
114 * @return the value for the given time field.
115 */
116 public int get(int field)
117 {
118 if (field == YEAR) {
119 return super.get(field) + yearOffset;
120 }
121 return super.get(field);
122 }
123
124 /**
125 * Sets the time field with the given value.
126 * @param field the given time field.
127 * @param value the value to be set for the given time field.
128 */
129 public void set(int field, int value)
130 {
131 if (field == YEAR) {
132 super.set(field, value - yearOffset);
133 } else {
134 super.set(field, value);
135 }
136 }
137
138 /**
139 * Adds the specified (signed) amount of time to the given time field.
140 * @param field the time field.
141 * @param amount the amount of date or time to be added to the field.
142 */
143 public void add(int field, int amount)
144 {
145 int savedYearOffset = yearOffset;
146 // To let the superclass calculate date-time values correctly,
147 // temporarily make this GregorianCalendar.
148 yearOffset = 0;
149 try {
150 super.add(field, amount);
151 } finally {
152 yearOffset = savedYearOffset;
153 }
154 }
155
156 /**
157 * Add to field a signed amount without changing larger fields.
158 * A negative roll amount means to subtract from field without changing
159 * larger fields.
160 * @param field the time field.
161 * @param amount the signed amount to add to <code>field</code>.
162 */
163 public void roll(int field, int amount)
164 {
165 int savedYearOffset = yearOffset;
166 // To let the superclass calculate date-time values correctly,
167 // temporarily make this GregorianCalendar.
168 yearOffset = 0;
169 try {
170 super.roll(field, amount);
171 } finally {
172 yearOffset = savedYearOffset;
173 }
174 }
175
176 public String getDisplayName(int field, int style, Locale locale) {
177 if (field != ERA) {
178 return super.getDisplayName(field, style, locale);
179 }
180
181 // Handle Thai BuddhistCalendar specific era names
182 if (field < 0 || field >= fields.length ||
183 style < SHORT || style > LONG) {
184 throw new IllegalArgumentException();
185 }
186 if (locale == null) {
187 throw new NullPointerException();
188 }
189 ResourceBundle rb = LocaleData.getDateFormatData(locale);
190 String[] eras = rb.getStringArray(getKey(style));
191 return eras[get(field)];
192 }
193
194 public Map<String,Integer> getDisplayNames(int field, int style, Locale locale) {
195 if (field != ERA) {
196 return super.getDisplayNames(field, style, locale);
197 }
198
199 // Handle Thai BuddhistCalendar specific era names
200 if (field < 0 || field >= fields.length ||
201 style < ALL_STYLES || style > LONG) {
202 throw new IllegalArgumentException();
203 }
204 if (locale == null) {
205 throw new NullPointerException();
206 }
207 // ALL_STYLES
208 if (style == ALL_STYLES) {
209 Map<String,Integer> shortNames = getDisplayNamesImpl(field, SHORT, locale);
210 Map<String,Integer> longNames = getDisplayNamesImpl(field, LONG, locale);
211 if (shortNames == null) {
212 return longNames;
213 }
214 if (longNames != null) {
215 shortNames.putAll(longNames);
216 }
217 return shortNames;
218 }
219
220 // SHORT or LONG
221 return getDisplayNamesImpl(field, style, locale);
222 }
223
224 private Map<String,Integer> getDisplayNamesImpl(int field, int style, Locale locale) {
225 ResourceBundle rb = LocaleData.getDateFormatData(locale);
226 String[] eras = rb.getStringArray(getKey(style));
227 Map<String,Integer> map = new HashMap<String,Integer>(4);
228 for (int i = 0; i < eras.length; i++) {
229 map.put(eras[i], i);
230 }
231 return map;
232 }
233
234 private String getKey(int style) {
235 StringBuilder key = new StringBuilder();
236 key.append(BuddhistCalendar.class.getName());
237 if (style == SHORT) {
238 key.append(".short");
239 }
240 key.append(".Eras");
241 return key.toString();
242 }
243
244 /**
245 * Returns the maximum value that this field could have, given the
246 * current date. For example, with the date "Feb 3, 2540" and the
247 * <code>DAY_OF_MONTH</code> field, the actual maximum is 28; for
248 * "Feb 3, 2539" it is 29.
249 *
250 * @param field the field to determine the maximum of
251 * @return the maximum of the given field for the current date of this Calendar
252 */
253 public int getActualMaximum(int field) {
254 int savedYearOffset = yearOffset;
255 // To let the superclass calculate date-time values correctly,
256 // temporarily make this GregorianCalendar.
257 yearOffset = 0;
258 try {
259 return super.getActualMaximum(field);
260 } finally {
261 yearOffset = savedYearOffset;
262 }
263 }
264
265 public String toString() {
266 // The super class produces a String with the Gregorian year
267 // value (or '?')
268 String s = super.toString();
269 // If the YEAR field is UNSET, then return the Gregorian string.
270 if (!isSet(YEAR)) {
271 return s;
272 }
273
274 final String yearField = "YEAR=";
275 int p = s.indexOf(yearField);
276 // If the string doesn't include the year value for some
277 // reason, then return the Gregorian string.
278 if (p == -1) {
279 return s;
280 }
281 p += yearField.length();
282 StringBuilder sb = new StringBuilder(s.substring(0, p));
283 // Skip the year number
284 while (Character.isDigit(s.charAt(p++)))
|
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() {
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++)))
|