View Javadoc
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 }