39 * and/or other materials provided with the distribution.
40 *
41 * * Neither the name of JSR-310 nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
47 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
48 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
49 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
50 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
52 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
53 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
54 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
55 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 */
57 package java.time.chrono;
58
59 import static java.time.temporal.ChronoField.YEAR;
60
61 import java.io.Serializable;
62 import java.time.Clock;
63 import java.time.DateTimeException;
64 import java.time.Instant;
65 import java.time.LocalDate;
66 import java.time.ZoneId;
67 import java.time.temporal.ChronoField;
68 import java.time.temporal.TemporalAccessor;
69 import java.time.temporal.ValueRange;
70 import java.util.Arrays;
71 import java.util.HashMap;
72 import java.util.List;
73 import java.util.Locale;
74
75 /**
76 * The Thai Buddhist calendar system.
77 * <p>
78 * This chronology defines the rules of the Thai Buddhist calendar system.
89 * current era. For the previous era, years have zero, then negative values.
90 * The value is equal to the ISO proleptic-year plus 543.
91 * <li>month-of-year - The ThaiBuddhist month-of-year exactly matches ISO.
92 * <li>day-of-month - The ThaiBuddhist day-of-month exactly matches ISO.
93 * <li>day-of-year - The ThaiBuddhist day-of-year exactly matches ISO.
94 * <li>leap-year - The ThaiBuddhist leap-year pattern exactly matches ISO, such that the two calendars
95 * are never out of step.
96 * </ul><p>
97 *
98 * <h3>Specification for implementors</h3>
99 * This class is immutable and thread-safe.
100 *
101 * @since 1.8
102 */
103 public final class ThaiBuddhistChronology extends Chronology implements Serializable {
104
105 /**
106 * Singleton instance of the Buddhist chronology.
107 */
108 public static final ThaiBuddhistChronology INSTANCE = new ThaiBuddhistChronology();
109 /**
110 * The singleton instance for the era before the current one - Before Buddhist -
111 * which has the value 0.
112 */
113 public static final Era ERA_BEFORE_BE = ThaiBuddhistEra.BEFORE_BE;
114 /**
115 * The singleton instance for the current era - Buddhist - which has the value 1.
116 */
117 public static final Era ERA_BE = ThaiBuddhistEra.BE;
118
119 /**
120 * Serialization version.
121 */
122 private static final long serialVersionUID = 2775954514031616474L;
123 /**
124 * Containing the offset to add to the ISO year.
125 */
126 static final int YEARS_DIFFERENCE = 543;
127 /**
128 * Narrow names for eras.
129 */
130 private static final HashMap<String, String[]> ERA_NARROW_NAMES = new HashMap<>();
131 /**
132 * Short names for eras.
133 */
134 private static final HashMap<String, String[]> ERA_SHORT_NAMES = new HashMap<>();
135 /**
136 * Full names for eras.
137 */
149 */
150 static {
151 ERA_NARROW_NAMES.put(FALLBACK_LANGUAGE, new String[]{"BB", "BE"});
152 ERA_NARROW_NAMES.put(TARGET_LANGUAGE, new String[]{"BB", "BE"});
153 ERA_SHORT_NAMES.put(FALLBACK_LANGUAGE, new String[]{"B.B.", "B.E."});
154 ERA_SHORT_NAMES.put(TARGET_LANGUAGE,
155 new String[]{"\u0e1e.\u0e28.",
156 "\u0e1b\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e04\u0e23\u0e34\u0e2a\u0e15\u0e4c\u0e01\u0e32\u0e25\u0e17\u0e35\u0e48"});
157 ERA_FULL_NAMES.put(FALLBACK_LANGUAGE, new String[]{"Before Buddhist", "Budhhist Era"});
158 ERA_FULL_NAMES.put(TARGET_LANGUAGE,
159 new String[]{"\u0e1e\u0e38\u0e17\u0e18\u0e28\u0e31\u0e01\u0e23\u0e32\u0e0a",
160 "\u0e1b\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e04\u0e23\u0e34\u0e2a\u0e15\u0e4c\u0e01\u0e32\u0e25\u0e17\u0e35\u0e48"});
161 }
162
163 /**
164 * Restricted constructor.
165 */
166 private ThaiBuddhistChronology() {
167 }
168
169 /**
170 * Resolve singleton.
171 *
172 * @return the singleton instance, not null
173 */
174 private Object readResolve() {
175 return INSTANCE;
176 }
177
178 //-----------------------------------------------------------------------
179 /**
180 * Gets the ID of the chronology - 'ThaiBuddhist'.
181 * <p>
182 * The ID uniquely identifies the {@code Chronology}.
183 * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
184 *
185 * @return the chronology ID - 'ThaiBuddhist'
186 * @see #getCalendarType()
187 */
188 @Override
189 public String getId() {
190 return "ThaiBuddhist";
191 }
192
193 /**
194 * Gets the calendar type of the underlying calendar system - 'buddhist'.
195 * <p>
196 * The calendar type is an identifier defined by the
197 * <em>Unicode Locale Data Markup Language (LDML)</em> specification.
198 * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
199 * It can also be used as part of a locale, accessible via
200 * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'.
201 *
202 * @return the calendar system type - 'buddhist'
203 * @see #getId()
204 */
205 @Override
206 public String getCalendarType() {
207 return "buddhist";
208 }
209
210 //-----------------------------------------------------------------------
211 @Override
212 public ThaiBuddhistDate date(int prolepticYear, int month, int dayOfMonth) {
213 return new ThaiBuddhistDate(LocalDate.of(prolepticYear - YEARS_DIFFERENCE, month, dayOfMonth));
214 }
215
216 @Override
217 public ThaiBuddhistDate dateYearDay(int prolepticYear, int dayOfYear) {
218 return new ThaiBuddhistDate(LocalDate.ofYearDay(prolepticYear - YEARS_DIFFERENCE, dayOfYear));
219 }
220
221 @Override
222 public ThaiBuddhistDate date(TemporalAccessor temporal) {
223 if (temporal instanceof ThaiBuddhistDate) {
224 return (ThaiBuddhistDate) temporal;
225 }
226 return new ThaiBuddhistDate(LocalDate.from(temporal));
227 }
228 @Override
229 public ThaiBuddhistDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
230 return date(prolepticYear(era, yearOfEra), month, dayOfMonth);
231
232 }
233
234 @Override
235 public ThaiBuddhistDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
236 return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
237 }
238
239 @Override
240 public ThaiBuddhistDate dateNow() {
241 return dateNow(Clock.systemDefaultZone());
242 }
243
244 @Override
245 public ThaiBuddhistDate dateNow(ZoneId zone) {
246 return dateNow(Clock.system(zone));
247 }
248
249 @Override
250 public ThaiBuddhistDate dateNow(Clock clock) {
251 return date(LocalDate.now(clock));
252 }
253
254 @Override
255 public ChronoLocalDateTime<ThaiBuddhistDate> localDateTime(TemporalAccessor temporal) {
256 return (ChronoLocalDateTime<ThaiBuddhistDate>)super.localDateTime(temporal);
257 }
258
259 @Override
260 public ChronoZonedDateTime<ThaiBuddhistDate> zonedDateTime(TemporalAccessor temporal) {
261 return (ChronoZonedDateTime<ThaiBuddhistDate>)super.zonedDateTime(temporal);
262 }
263
264 @Override
265 public ChronoZonedDateTime<ThaiBuddhistDate> zonedDateTime(Instant instant, ZoneId zone) {
266 return (ChronoZonedDateTime<ThaiBuddhistDate>)super.zonedDateTime(instant, zone);
267 }
268
269 //-----------------------------------------------------------------------
270 /**
271 * Checks if the specified year is a leap year.
272 * <p>
273 * Thai Buddhist leap years occur exactly in line with ISO leap years.
274 * This method does not validate the year passed in, and only has a
275 * well-defined result for years in the supported range.
276 *
277 * @param prolepticYear the proleptic-year to check, not validated for range
278 * @return true if the year is a leap year
279 */
280 @Override
281 public boolean isLeapYear(long prolepticYear) {
282 return IsoChronology.INSTANCE.isLeapYear(prolepticYear - YEARS_DIFFERENCE);
283 }
284
285 @Override
286 public int prolepticYear(Era era, int yearOfEra) {
287 if (era instanceof ThaiBuddhistEra == false) {
288 throw new DateTimeException("Era must be BuddhistEra");
289 }
290 return (era == ThaiBuddhistEra.BE ? yearOfEra : 1 - yearOfEra);
291 }
292
293 @Override
294 public Era eraOf(int eraValue) {
295 return ThaiBuddhistEra.of(eraValue);
296 }
297
298 @Override
299 public List<Era> eras() {
300 return Arrays.<Era>asList(ThaiBuddhistEra.values());
301 }
302
303 //-----------------------------------------------------------------------
304 @Override
305 public ValueRange range(ChronoField field) {
306 switch (field) {
307 case YEAR_OF_ERA: {
308 ValueRange range = YEAR.range();
309 return ValueRange.of(1, -(range.getMinimum() + YEARS_DIFFERENCE) + 1, range.getMaximum() + YEARS_DIFFERENCE);
310 }
311 case YEAR: {
312 ValueRange range = YEAR.range();
313 return ValueRange.of(range.getMinimum() + YEARS_DIFFERENCE, range.getMaximum() + YEARS_DIFFERENCE);
314 }
315 }
316 return field.range();
317 }
318
319 }
|
39 * and/or other materials provided with the distribution.
40 *
41 * * Neither the name of JSR-310 nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
47 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
48 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
49 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
50 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
52 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
53 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
54 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
55 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 */
57 package java.time.chrono;
58
59 import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
60 import static java.time.temporal.ChronoField.YEAR;
61
62 import java.io.Serializable;
63 import java.time.Clock;
64 import java.time.DateTimeException;
65 import java.time.Instant;
66 import java.time.LocalDate;
67 import java.time.ZoneId;
68 import java.time.temporal.ChronoField;
69 import java.time.temporal.TemporalAccessor;
70 import java.time.temporal.ValueRange;
71 import java.util.Arrays;
72 import java.util.HashMap;
73 import java.util.List;
74 import java.util.Locale;
75
76 /**
77 * The Thai Buddhist calendar system.
78 * <p>
79 * This chronology defines the rules of the Thai Buddhist calendar system.
90 * current era. For the previous era, years have zero, then negative values.
91 * The value is equal to the ISO proleptic-year plus 543.
92 * <li>month-of-year - The ThaiBuddhist month-of-year exactly matches ISO.
93 * <li>day-of-month - The ThaiBuddhist day-of-month exactly matches ISO.
94 * <li>day-of-year - The ThaiBuddhist day-of-year exactly matches ISO.
95 * <li>leap-year - The ThaiBuddhist leap-year pattern exactly matches ISO, such that the two calendars
96 * are never out of step.
97 * </ul><p>
98 *
99 * <h3>Specification for implementors</h3>
100 * This class is immutable and thread-safe.
101 *
102 * @since 1.8
103 */
104 public final class ThaiBuddhistChronology extends Chronology implements Serializable {
105
106 /**
107 * Singleton instance of the Buddhist chronology.
108 */
109 public static final ThaiBuddhistChronology INSTANCE = new ThaiBuddhistChronology();
110
111 /**
112 * Serialization version.
113 */
114 private static final long serialVersionUID = 2775954514031616474L;
115 /**
116 * Containing the offset to add to the ISO year.
117 */
118 static final int YEARS_DIFFERENCE = 543;
119 /**
120 * Narrow names for eras.
121 */
122 private static final HashMap<String, String[]> ERA_NARROW_NAMES = new HashMap<>();
123 /**
124 * Short names for eras.
125 */
126 private static final HashMap<String, String[]> ERA_SHORT_NAMES = new HashMap<>();
127 /**
128 * Full names for eras.
129 */
141 */
142 static {
143 ERA_NARROW_NAMES.put(FALLBACK_LANGUAGE, new String[]{"BB", "BE"});
144 ERA_NARROW_NAMES.put(TARGET_LANGUAGE, new String[]{"BB", "BE"});
145 ERA_SHORT_NAMES.put(FALLBACK_LANGUAGE, new String[]{"B.B.", "B.E."});
146 ERA_SHORT_NAMES.put(TARGET_LANGUAGE,
147 new String[]{"\u0e1e.\u0e28.",
148 "\u0e1b\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e04\u0e23\u0e34\u0e2a\u0e15\u0e4c\u0e01\u0e32\u0e25\u0e17\u0e35\u0e48"});
149 ERA_FULL_NAMES.put(FALLBACK_LANGUAGE, new String[]{"Before Buddhist", "Budhhist Era"});
150 ERA_FULL_NAMES.put(TARGET_LANGUAGE,
151 new String[]{"\u0e1e\u0e38\u0e17\u0e18\u0e28\u0e31\u0e01\u0e23\u0e32\u0e0a",
152 "\u0e1b\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e04\u0e23\u0e34\u0e2a\u0e15\u0e4c\u0e01\u0e32\u0e25\u0e17\u0e35\u0e48"});
153 }
154
155 /**
156 * Restricted constructor.
157 */
158 private ThaiBuddhistChronology() {
159 }
160
161 //-----------------------------------------------------------------------
162 /**
163 * Gets the ID of the chronology - 'ThaiBuddhist'.
164 * <p>
165 * The ID uniquely identifies the {@code Chronology}.
166 * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
167 *
168 * @return the chronology ID - 'ThaiBuddhist'
169 * @see #getCalendarType()
170 */
171 @Override
172 public String getId() {
173 return "ThaiBuddhist";
174 }
175
176 /**
177 * Gets the calendar type of the underlying calendar system - 'buddhist'.
178 * <p>
179 * The calendar type is an identifier defined by the
180 * <em>Unicode Locale Data Markup Language (LDML)</em> specification.
181 * It can be used to lookup the {@code Chronology} using {@link #of(String)}.
182 * It can also be used as part of a locale, accessible via
183 * {@link Locale#getUnicodeLocaleType(String)} with the key 'ca'.
184 *
185 * @return the calendar system type - 'buddhist'
186 * @see #getId()
187 */
188 @Override
189 public String getCalendarType() {
190 return "buddhist";
191 }
192
193 //-----------------------------------------------------------------------
194 /**
195 * Obtains a local date in Thai Buddhist calendar system from the
196 * era, year-of-era, month-of-year and day-of-month fields.
197 *
198 * @param era the Thai Buddhist era, not null
199 * @param yearOfEra the year-of-era
200 * @param month the month-of-year
201 * @param dayOfMonth the day-of-month
202 * @return the Thai Buddhist local date, not null
203 * @throws DateTimeException if unable to create the date
204 * @throws ClassCastException if the {@code era} is not a {@code ThaiBuddhistEra}
205 */
206 @Override
207 public ThaiBuddhistDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
208 return date(prolepticYear(era, yearOfEra), month, dayOfMonth);
209 }
210
211 /**
212 * Obtains a local date in Thai Buddhist calendar system from the
213 * proleptic-year, month-of-year and day-of-month fields.
214 *
215 * @param prolepticYear the proleptic-year
216 * @param month the month-of-year
217 * @param dayOfMonth the day-of-month
218 * @return the Thai Buddhist local date, not null
219 * @throws DateTimeException if unable to create the date
220 */
221 @Override
222 public ThaiBuddhistDate date(int prolepticYear, int month, int dayOfMonth) {
223 return new ThaiBuddhistDate(LocalDate.of(prolepticYear - YEARS_DIFFERENCE, month, dayOfMonth));
224 }
225
226 /**
227 * Obtains a local date in Thai Buddhist calendar system from the
228 * era, year-of-era and day-of-year fields.
229 *
230 * @param era the Thai Buddhist era, not null
231 * @param yearOfEra the year-of-era
232 * @param dayOfYear the day-of-year
233 * @return the Thai Buddhist local date, not null
234 * @throws DateTimeException if unable to create the date
235 * @throws ClassCastException if the {@code era} is not a {@code ThaiBuddhistEra}
236 */
237 @Override
238 public ThaiBuddhistDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
239 return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
240 }
241
242 /**
243 * Obtains a local date in Thai Buddhist calendar system from the
244 * proleptic-year and day-of-year fields.
245 *
246 * @param prolepticYear the proleptic-year
247 * @param dayOfYear the day-of-year
248 * @return the Thai Buddhist local date, not null
249 * @throws DateTimeException if unable to create the date
250 */
251 @Override
252 public ThaiBuddhistDate dateYearDay(int prolepticYear, int dayOfYear) {
253 return new ThaiBuddhistDate(LocalDate.ofYearDay(prolepticYear - YEARS_DIFFERENCE, dayOfYear));
254 }
255
256 /**
257 * Obtains a local date in the Thai Buddhist calendar system from the epoch-day.
258 *
259 * @param epochDay the epoch day
260 * @return the Thai Buddhist local date, not null
261 * @throws DateTimeException if unable to create the date
262 */
263 @Override // override with covariant return type
264 public ThaiBuddhistDate dateEpochDay(long epochDay) {
265 return new ThaiBuddhistDate(LocalDate.ofEpochDay(epochDay));
266 }
267
268 @Override
269 public ThaiBuddhistDate dateNow() {
270 return dateNow(Clock.systemDefaultZone());
271 }
272
273 @Override
274 public ThaiBuddhistDate dateNow(ZoneId zone) {
275 return dateNow(Clock.system(zone));
276 }
277
278 @Override
279 public ThaiBuddhistDate dateNow(Clock clock) {
280 return date(LocalDate.now(clock));
281 }
282
283 @Override
284 public ThaiBuddhistDate date(TemporalAccessor temporal) {
285 if (temporal instanceof ThaiBuddhistDate) {
286 return (ThaiBuddhistDate) temporal;
287 }
288 return new ThaiBuddhistDate(LocalDate.from(temporal));
289 }
290
291 @Override
292 public ChronoLocalDateTime<ThaiBuddhistDate> localDateTime(TemporalAccessor temporal) {
293 return (ChronoLocalDateTime<ThaiBuddhistDate>)super.localDateTime(temporal);
294 }
295
296 @Override
297 public ChronoZonedDateTime<ThaiBuddhistDate> zonedDateTime(TemporalAccessor temporal) {
298 return (ChronoZonedDateTime<ThaiBuddhistDate>)super.zonedDateTime(temporal);
299 }
300
301 @Override
302 public ChronoZonedDateTime<ThaiBuddhistDate> zonedDateTime(Instant instant, ZoneId zone) {
303 return (ChronoZonedDateTime<ThaiBuddhistDate>)super.zonedDateTime(instant, zone);
304 }
305
306 //-----------------------------------------------------------------------
307 /**
308 * Checks if the specified year is a leap year.
309 * <p>
310 * Thai Buddhist leap years occur exactly in line with ISO leap years.
311 * This method does not validate the year passed in, and only has a
312 * well-defined result for years in the supported range.
313 *
314 * @param prolepticYear the proleptic-year to check, not validated for range
315 * @return true if the year is a leap year
316 */
317 @Override
318 public boolean isLeapYear(long prolepticYear) {
319 return IsoChronology.INSTANCE.isLeapYear(prolepticYear - YEARS_DIFFERENCE);
320 }
321
322 @Override
323 public int prolepticYear(Era era, int yearOfEra) {
324 if (era instanceof ThaiBuddhistEra == false) {
325 throw new ClassCastException("Era must be BuddhistEra");
326 }
327 return (era == ThaiBuddhistEra.BE ? yearOfEra : 1 - yearOfEra);
328 }
329
330 @Override
331 public Era eraOf(int eraValue) {
332 return ThaiBuddhistEra.of(eraValue);
333 }
334
335 @Override
336 public List<Era> eras() {
337 return Arrays.<Era>asList(ThaiBuddhistEra.values());
338 }
339
340 //-----------------------------------------------------------------------
341 @Override
342 public ValueRange range(ChronoField field) {
343 switch (field) {
344 case PROLEPTIC_MONTH: {
345 ValueRange range = PROLEPTIC_MONTH.range();
346 return ValueRange.of(range.getMinimum() + YEARS_DIFFERENCE * 12L, range.getMaximum() + YEARS_DIFFERENCE * 12L);
347 }
348 case YEAR_OF_ERA: {
349 ValueRange range = YEAR.range();
350 return ValueRange.of(1, -(range.getMinimum() + YEARS_DIFFERENCE) + 1, range.getMaximum() + YEARS_DIFFERENCE);
351 }
352 case YEAR: {
353 ValueRange range = YEAR.range();
354 return ValueRange.of(range.getMinimum() + YEARS_DIFFERENCE, range.getMaximum() + YEARS_DIFFERENCE);
355 }
356 }
357 return field.range();
358 }
359
360 }
|