1 /*
2  * hunt-time: A time library for D programming language.
3  *
4  * Copyright (C) 2015-2018 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.time.chrono.ThaiBuddhistChronology;
13 
14 
15 // import hunt.time.temporal.ChronoField;
16 
17 // //import hunt.io.ObjectInputStream;
18 // import hunt.stream.Common;
19 // import hunt.time.Clock;
20 // import hunt.time.Exceptions;
21 // import hunt.time.Instant;
22 // import hunt.time.LocalDate;
23 // import hunt.time.ZoneId;
24 // import hunt.time.format.ResolverStyle;
25 // import hunt.time.temporal.ChronoField;
26 // import hunt.time.temporal.TemporalAccessor;
27 // import hunt.time.temporal.TemporalField;
28 // import hunt.time.temporal.ValueRange;
29 // import hunt.time.util;
30 // //import hunt.concurrent.ConcurrentMap;;
31 
32 // import hunt.collection.List;
33 // // import hunt.time.util.Locale;
34 // import hunt.collection.Map;
35 
36 // /**
37 //  * The Thai Buddhist calendar system.
38 //  * !(p)
39 //  * This chronology defines the rules of the Thai Buddhist calendar system.
40 //  * This calendar system is primarily used _in Thailand.
41 //  * Dates are aligned such that {@code 2484-01-01 (Buddhist)} is {@code 1941-01-01 (ISO)}.
42 //  * !(p)
43 //  * The fields are defined as follows:
44 //  * !(ul)
45 //  * !(li)era - There are two eras, the current 'Buddhist' (ERA_BE) and the previous era (ERA_BEFORE_BE).
46 //  * !(li)year-of-era - The year-of-era for the current era increases uniformly from the epoch at year one.
47 //  *  For the previous era the year increases from one as time goes backwards.
48 //  *  The value for the current era is equal to the ISO proleptic-year plus 543.
49 //  * !(li)proleptic-year - The proleptic year is the same as the year-of-era for the
50 //  *  current era. For the previous era, years have zero, then negative values.
51 //  *  The value is equal to the ISO proleptic-year plus 543.
52 //  * !(li)month-of-year - The ThaiBuddhist month-of-year exactly matches ISO.
53 //  * !(li)day-of-month - The ThaiBuddhist day-of-month exactly matches ISO.
54 //  * !(li)day-of-year - The ThaiBuddhist day-of-year exactly matches ISO.
55 //  * !(li)leap-year - The ThaiBuddhist leap-year pattern exactly matches ISO, such that the two calendars
56 //  *  are never _out of step.
57 //  * </ul>
58 //  *
59 //  * @implSpec
60 //  * This class is immutable and thread-safe.
61 //  *
62 //  * @since 1.8
63 //  */
64 // public final class ThaiBuddhistChronology : AbstractChronology , Serializable {
65 
66 //     mixin MakeServiceLoader!AbstractChronology;
67 
68 //     /**
69 //      * Singleton instance of the Buddhist chronology.
70 //      */
71 //     public static final ThaiBuddhistChronology INSTANCE = new ThaiBuddhistChronology();
72 
73 //     /**
74 //      * Serialization version.
75 //      */
76 //     private static final long serialVersionUID = 2775954514031616474L;
77 //     /**
78 //      * Containing the offset to add to the ISO year.
79 //      */
80 //     static final int YEARS_DIFFERENCE = 543;
81 //     /**
82 //      * Narrow names for eras.
83 //      */
84 //     private static final HashMap!(string, string[]) ERA_NARROW_NAMES = new HashMap!()();
85 //     /**
86 //      * Short names for eras.
87 //      */
88 //     private static final HashMap!(string, string[]) ERA_SHORT_NAMES = new HashMap!()();
89 //     /**
90 //      * Full names for eras.
91 //      */
92 //     private static final HashMap!(string, string[]) ERA_FULL_NAMES = new HashMap!()();
93 //     /**
94 //      * Fallback language for the era names.
95 //      */
96 //     private static final string FALLBACK_LANGUAGE = "en";
97 //     /**
98 //      * Language that has the era names.
99 //      */
100 //     private static final string TARGET_LANGUAGE = "th";
101 //     /**
102 //      * Name data.
103 //      */
104 //     static this(){
105 //         ERA_NARROW_NAMES.put(FALLBACK_LANGUAGE, ["BB", "BE"]);
106 //         ERA_NARROW_NAMES.put(TARGET_LANGUAGE, ["BB", "BE"]);
107 //         ERA_SHORT_NAMES.put(FALLBACK_LANGUAGE, ["B.B.", "B.E."]);
108 //         ERA_SHORT_NAMES.put(TARGET_LANGUAGE,
109 //                 ["\u0e1e.\u0e28.",
110 //                 "\u0e1b\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e04\u0e23\u0e34\u0e2a\u0e15\u0e4c\u0e01\u0e32\u0e25\u0e17\u0e35\u0e48"]);
111 //         ERA_FULL_NAMES.put(FALLBACK_LANGUAGE, ["Before Buddhist", "Budhhist Era"]);
112 //         ERA_FULL_NAMES.put(TARGET_LANGUAGE,
113 //                 ["\u0e1e\u0e38\u0e17\u0e18\u0e28\u0e31\u0e01\u0e23\u0e32\u0e0a",
114 //                 "\u0e1b\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e04\u0e23\u0e34\u0e2a\u0e15\u0e4c\u0e01\u0e32\u0e25\u0e17\u0e35\u0e48"]);
115 //     }
116 
117 //     /**
118 //      * Restricted constructor.
119 //      */
120 //     private this() {
121 //     }
122 
123 //     //-----------------------------------------------------------------------
124 //     /**
125 //      * Gets the ID of the chronology - 'ThaiBuddhist'.
126 //      * !(p)
127 //      * The ID uniquely identifies the {@code Chronology}.
128 //      * It can be used to lookup the {@code Chronology} using {@link Chronology#of(string)}.
129 //      *
130 //      * @return the chronology ID - 'ThaiBuddhist'
131 //      * @see #getCalendarType()
132 //      */
133 //     override
134 //     public string getId() {
135 //         return "ThaiBuddhist";
136 //     }
137 
138 //     /**
139 //      * Gets the calendar type of the underlying calendar system - 'buddhist'.
140 //      * !(p)
141 //      * The calendar type is an identifier defined by the
142 //      * !(em)Unicode Locale Data Markup Language (LDML)</em> specification.
143 //      * It can be used to lookup the {@code Chronology} using {@link Chronology#of(string)}.
144 //      * It can also be used as part of a locale, accessible via
145 //      * {@link Locale#getUnicodeLocaleType(string)} with the key 'ca'.
146 //      *
147 //      * @return the calendar system type - 'buddhist'
148 //      * @see #getId()
149 //      */
150 //     override
151 //     public string getCalendarType() {
152 //         return "buddhist";
153 //     }
154 
155 //     //-----------------------------------------------------------------------
156 //     /**
157 //      * Obtains a local date _in Thai Buddhist calendar system from the
158 //      * era, year-of-era, month-of-year and day-of-month fields.
159 //      *
160 //      * @param era  the Thai Buddhist era, not null
161 //      * @param yearOfEra  the year-of-era
162 //      * @param month  the month-of-year
163 //      * @param dayOfMonth  the day-of-month
164 //      * @return the Thai Buddhist local date, not null
165 //      * @throws DateTimeException if unable to create the date
166 //      * @throws ClassCastException if the {@code era} is not a {@code ThaiBuddhistEra}
167 //      */
168 //     override
169 //     public ThaiBuddhistDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
170 //         return date(prolepticYear(era, yearOfEra), month, dayOfMonth);
171 //     }
172 
173 //     /**
174 //      * Obtains a local date _in Thai Buddhist calendar system from the
175 //      * proleptic-year, month-of-year and day-of-month fields.
176 //      *
177 //      * @param prolepticYear  the proleptic-year
178 //      * @param month  the month-of-year
179 //      * @param dayOfMonth  the day-of-month
180 //      * @return the Thai Buddhist local date, not null
181 //      * @throws DateTimeException if unable to create the date
182 //      */
183 //     override
184 //     public ThaiBuddhistDate date(int prolepticYear, int month, int dayOfMonth) {
185 //         return new ThaiBuddhistDate(LocalDate.of(prolepticYear - YEARS_DIFFERENCE, month, dayOfMonth));
186 //     }
187 
188 //     /**
189 //      * Obtains a local date _in Thai Buddhist calendar system from the
190 //      * era, year-of-era and day-of-year fields.
191 //      *
192 //      * @param era  the Thai Buddhist era, not null
193 //      * @param yearOfEra  the year-of-era
194 //      * @param dayOfYear  the day-of-year
195 //      * @return the Thai Buddhist local date, not null
196 //      * @throws DateTimeException if unable to create the date
197 //      * @throws ClassCastException if the {@code era} is not a {@code ThaiBuddhistEra}
198 //      */
199 //     override
200 //     public ThaiBuddhistDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
201 //         return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
202 //     }
203 
204 //     /**
205 //      * Obtains a local date _in Thai Buddhist calendar system from the
206 //      * proleptic-year and day-of-year fields.
207 //      *
208 //      * @param prolepticYear  the proleptic-year
209 //      * @param dayOfYear  the day-of-year
210 //      * @return the Thai Buddhist local date, not null
211 //      * @throws DateTimeException if unable to create the date
212 //      */
213 //     override
214 //     public ThaiBuddhistDate dateYearDay(int prolepticYear, int dayOfYear) {
215 //         return new ThaiBuddhistDate(LocalDate.ofYearDay(prolepticYear - YEARS_DIFFERENCE, dayOfYear));
216 //     }
217 
218 //     /**
219 //      * Obtains a local date _in the Thai Buddhist calendar system from the epoch-day.
220 //      *
221 //      * @param epochDay  the epoch day
222 //      * @return the Thai Buddhist local date, not null
223 //      * @throws DateTimeException if unable to create the date
224 //      */
225 //     override  // override with covariant return type
226 //     public ThaiBuddhistDate dateEpochDay(long epochDay) {
227 //         return new ThaiBuddhistDate(LocalDate.ofEpochDay(epochDay));
228 //     }
229 
230 //     override
231 //     public ThaiBuddhistDate dateNow() {
232 //         return dateNow(Clock.systemDefaultZone());
233 //     }
234 
235 //     override
236 //     public ThaiBuddhistDate dateNow(ZoneId zone) {
237 //         return dateNow(Clock.system(zone));
238 //     }
239 
240 //     override
241 //     public ThaiBuddhistDate dateNow(Clock clock) {
242 //         return date(LocalDate.now(clock));
243 //     }
244 
245 //     override
246 //     public ThaiBuddhistDate date(TemporalAccessor temporal) {
247 //         if (cast(ThaiBuddhistDate)(temporal) !is null) {
248 //             return cast(ThaiBuddhistDate) temporal;
249 //         }
250 //         return new ThaiBuddhistDate(LocalDate.from(temporal));
251 //     }
252 
253 //     override
254 //     /*@SuppressWarnings("unchecked")*/
255 //     public ChronoLocalDateTime!(ThaiBuddhistDate) localDateTime(TemporalAccessor temporal) {
256 //         return cast(ChronoLocalDateTime!(ThaiBuddhistDate))super.localDateTime(temporal);
257 //     }
258 
259 //     override
260 //     /*@SuppressWarnings("unchecked")*/
261 //     public ChronoZonedDateTime!(ThaiBuddhistDate) zonedDateTime(TemporalAccessor temporal) {
262 //         return cast(ChronoZonedDateTime!(ThaiBuddhistDate))super.zonedDateTime(temporal);
263 //     }
264 
265 //     override
266 //     /*@SuppressWarnings("unchecked")*/
267 //     public ChronoZonedDateTime!(ThaiBuddhistDate) zonedDateTime(Instant instant, ZoneId zone) {
268 //         return cast(ChronoZonedDateTime!(ThaiBuddhistDate))super.zonedDateTime(instant, zone);
269 //     }
270 
271 //     //-----------------------------------------------------------------------
272 //     /**
273 //      * Checks if the specified year is a leap year.
274 //      * !(p)
275 //      * Thai Buddhist leap years occur exactly _in line with ISO leap years.
276 //      * This method does not validate the year passed _in, and only has a
277 //      * well-defined result for years _in the supported range.
278 //      *
279 //      * @param prolepticYear  the proleptic-year to check, not validated for range
280 //      * @return true if the year is a leap year
281 //      */
282 //     override
283 //     public bool isLeapYear(long prolepticYear) {
284 //         return IsoChronology.INSTANCE.isLeapYear(prolepticYear - YEARS_DIFFERENCE);
285 //     }
286 
287 //     override
288 //     public int prolepticYear(Era era, int yearOfEra) {
289 //         if ((cast(ThaiBuddhistEra)(era) !is null) == false) {
290 //             throw new ClassCastException("Era must be BuddhistEra");
291 //         }
292 //         return (era == ThaiBuddhistEra.BE ? yearOfEra : 1 - yearOfEra);
293 //     }
294 
295 //     override
296 //     public ThaiBuddhistEra eraOf(int eraValue) {
297 //         return ThaiBuddhistEra.of(eraValue);
298 //     }
299 
300 //     override
301 //     public List!(Era) eras() {
302 //         return List.of(ThaiBuddhistEra.values());
303 //     }
304 
305 //     //-----------------------------------------------------------------------
306 //     override
307 //     public ValueRange range(ChronoField field) {
308 //         switch (field) {
309 //             case PROLEPTIC_MONTH: {
310 //                 ValueRange range = PROLEPTIC_MONTH.range();
311 //                 return ValueRange.of(range.getMinimum() + YEARS_DIFFERENCE * 12L, range.getMaximum() + YEARS_DIFFERENCE * 12L);
312 //             }
313 //             case YEAR_OF_ERA: {
314 //                 ValueRange range = YEAR.range();
315 //                 return ValueRange.of(1, -(range.getMinimum() + YEARS_DIFFERENCE) + 1, range.getMaximum() + YEARS_DIFFERENCE);
316 //             }
317 //             case YEAR: {
318 //                 ValueRange range = YEAR.range();
319 //                 return ValueRange.of(range.getMinimum() + YEARS_DIFFERENCE, range.getMaximum() + YEARS_DIFFERENCE);
320 //             }
321 //         }
322 //         return field.range();
323 //     }
324 
325 //     //-----------------------------------------------------------------------
326 //     override  // override for return type
327 //     public ThaiBuddhistDate resolveDate(Map!(TemporalField, Long) fieldValues, ResolverStyle resolverStyle) {
328 //         return cast(ThaiBuddhistDate) super.resolveDate(fieldValues, resolverStyle);
329 //     }
330 
331 //     //-----------------------------------------------------------------------
332 //     /**
333 //      * Writes the Chronology using a
334 //      * <a href="{@docRoot}/serialized-form.html#hunt.time.chrono.Ser">dedicated serialized form</a>.
335 //      * @serialData
336 //      * !(pre)
337 //      *  _out.writeByte(1);     // identifies a Chronology
338 //      *  _out.writeUTF(getId());
339 //      * </pre>
340 //      *
341 //      * @return the instance of {@code Ser}, not null
342 //      */
343 //     override
344 //     Object writeReplace() {
345 //         return super.writeReplace();
346 //     }
347 
348 //     /**
349 //      * Defend against malicious streams.
350 //      *
351 //      * @param s the stream to read
352 //      * @throws InvalidObjectException always
353 //      */
354 //     private void readObject(ObjectInputStream s) /*throws InvalidObjectException*/ {
355 //         throw new InvalidObjectException("Deserialization via serialization delegate");
356 //     }
357 // }