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.MinguoChronology;
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.collection.List;
30 // // import hunt.time.util.Locale;
31 // import hunt.collection.Map;
32 // import hunt.time.chrono.AbstractChronology;
33 // import hunt.time.util.ServiceLoader;
34 // import hunt.time.chrono.MinguoDate;
35 // import hunt.time.chrono.Era;
36 // import hunt.time.chrono.ChronoLocalDateTime;
37 // import hunt.time.chrono.MinguoDate;
38 // import hunt.time.chrono.ChronoZonedDateTime;
39 // import hunt.time.chrono.MinguoEra;
40 // // import hunt.lang;
41 // /**
42 //  * The Minguo calendar system.
43 //  * !(p)
44 //  * This chronology defines the rules of the Minguo calendar system.
45 //  * This calendar system is primarily used _in the Republic of China, often known as Taiwan.
46 //  * Dates are aligned such that {@code 0001-01-01 (Minguo)} is {@code 1912-01-01 (ISO)}.
47 //  * !(p)
48 //  * The fields are defined as follows:
49 //  * !(ul)
50 //  * !(li)era - There are two eras, the current 'Republic' (ERA_ROC) and the previous era (ERA_BEFORE_ROC).
51 //  * !(li)year-of-era - The year-of-era for the current era increases uniformly from the epoch at year one.
52 //  *  For the previous era the year increases from one as time goes backwards.
53 //  *  The value for the current era is equal to the ISO proleptic-year minus 1911.
54 //  * !(li)proleptic-year - The proleptic year is the same as the year-of-era for the
55 //  *  current era. For the previous era, years have zero, then negative values.
56 //  *  The value is equal to the ISO proleptic-year minus 1911.
57 //  * !(li)month-of-year - The Minguo month-of-year exactly matches ISO.
58 //  * !(li)day-of-month - The Minguo day-of-month exactly matches ISO.
59 //  * !(li)day-of-year - The Minguo day-of-year exactly matches ISO.
60 //  * !(li)leap-year - The Minguo leap-year pattern exactly matches ISO, such that the two calendars
61 //  *  are never _out of step.
62 //  * </ul>
63 //  *
64 //  * @implSpec
65 //  * This class is immutable and thread-safe.
66 //  *
67 //  * @since 1.8
68 //  */
69 // public final class MinguoChronology : AbstractChronology , Serializable {
70 
71 //     mixin MakeServiceLoader!AbstractChronology;
72 
73 //     /**
74 //      * Singleton instance for the Minguo chronology.
75 //      */
76 //     public __gshared MinguoChronology INSTANCE;
77 
78 //     shared static this()
79 //     {
80 //         INSTANCE = new MinguoChronology();
81 //     }
82 
83 //     /**
84 //      * Serialization version.
85 //      */
86 //     private enum long serialVersionUID = 1039765215346859963L;
87 //     /**
88 //      * The difference _in years between ISO and Minguo.
89 //      */
90 //     enum int YEARS_DIFFERENCE = 1911;
91 
92 //     /**
93 //      * Restricted constructor.
94 //      */
95 //     private this() {
96 //     }
97 
98 //     //-----------------------------------------------------------------------
99 //     /**
100 //      * Gets the ID of the chronology - 'Minguo'.
101 //      * !(p)
102 //      * The ID uniquely identifies the {@code Chronology}.
103 //      * It can be used to lookup the {@code Chronology} using {@link Chronology#of(string)}.
104 //      *
105 //      * @return the chronology ID - 'Minguo'
106 //      * @see #getCalendarType()
107 //      */
108 //     // override
109 //     public string getId() {
110 //         return "Minguo";
111 //     }
112 
113 //     /**
114 //      * Gets the calendar type of the underlying calendar system - 'roc'.
115 //      * !(p)
116 //      * The calendar type is an identifier defined by the
117 //      * !(em)Unicode Locale Data Markup Language (LDML)</em> specification.
118 //      * It can be used to lookup the {@code Chronology} using {@link Chronology#of(string)}.
119 //      * It can also be used as part of a locale, accessible via
120 //      * {@link Locale#getUnicodeLocaleType(string)} with the key 'ca'.
121 //      *
122 //      * @return the calendar system type - 'roc'
123 //      * @see #getId()
124 //      */
125 //     // override
126 //     public string getCalendarType() {
127 //         return "roc";
128 //     }
129 
130 //     //-----------------------------------------------------------------------
131 //     /**
132 //      * Obtains a local date _in Minguo calendar system from the
133 //      * era, year-of-era, month-of-year and day-of-month fields.
134 //      *
135 //      * @param era  the Minguo era, not null
136 //      * @param yearOfEra  the year-of-era
137 //      * @param month  the month-of-year
138 //      * @param dayOfMonth  the day-of-month
139 //      * @return the Minguo local date, not null
140 //      * @throws DateTimeException if unable to create the date
141 //      * @throws ClassCastException if the {@code era} is not a {@code MinguoEra}
142 //      */
143 //     // override
144 //     public MinguoDate date(Era era, int yearOfEra, int month, int dayOfMonth) {
145 //         return date(prolepticYear(era, yearOfEra), month, dayOfMonth);
146 //     }
147 
148 //     /**
149 //      * Obtains a local date _in Minguo calendar system from the
150 //      * proleptic-year, month-of-year and day-of-month fields.
151 //      *
152 //      * @param prolepticYear  the proleptic-year
153 //      * @param month  the month-of-year
154 //      * @param dayOfMonth  the day-of-month
155 //      * @return the Minguo local date, not null
156 //      * @throws DateTimeException if unable to create the date
157 //      */
158 //     // override
159 //     public MinguoDate date(int prolepticYear, int month, int dayOfMonth) {
160 //         return new MinguoDate(LocalDate.of(prolepticYear + YEARS_DIFFERENCE, month, dayOfMonth));
161 //     }
162 
163 //     /**
164 //      * Obtains a local date _in Minguo calendar system from the
165 //      * era, year-of-era and day-of-year fields.
166 //      *
167 //      * @param era  the Minguo era, not null
168 //      * @param yearOfEra  the year-of-era
169 //      * @param dayOfYear  the day-of-year
170 //      * @return the Minguo local date, not null
171 //      * @throws DateTimeException if unable to create the date
172 //      * @throws ClassCastException if the {@code era} is not a {@code MinguoEra}
173 //      */
174 //     // override
175 //     public MinguoDate dateYearDay(Era era, int yearOfEra, int dayOfYear) {
176 //         return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear);
177 //     }
178 
179 //     /**
180 //      * Obtains a local date _in Minguo calendar system from the
181 //      * proleptic-year and day-of-year fields.
182 //      *
183 //      * @param prolepticYear  the proleptic-year
184 //      * @param dayOfYear  the day-of-year
185 //      * @return the Minguo local date, not null
186 //      * @throws DateTimeException if unable to create the date
187 //      */
188 //     // override
189 //     public MinguoDate dateYearDay(int prolepticYear, int dayOfYear) {
190 //         return new MinguoDate(LocalDate.ofYearDay(prolepticYear + YEARS_DIFFERENCE, dayOfYear));
191 //     }
192 
193 //     /**
194 //      * Obtains a local date _in the Minguo calendar system from the epoch-day.
195 //      *
196 //      * @param epochDay  the epoch day
197 //      * @return the Minguo local date, not null
198 //      * @throws DateTimeException if unable to create the date
199 //      */
200 //     // override  // override with covariant return type
201 //     public MinguoDate dateEpochDay(long epochDay) {
202 //         return new MinguoDate(LocalDate.ofEpochDay(epochDay));
203 //     }
204 
205 //     // override
206 //     public MinguoDate dateNow() {
207 //         return dateNow(Clock.systemDefaultZone());
208 //     }
209 
210 //     // override
211 //     public MinguoDate dateNow(ZoneId zone) {
212 //         return dateNow(Clock.system(zone));
213 //     }
214 
215 //     // override
216 //     public MinguoDate dateNow(Clock clock) {
217 //         return date(LocalDate.now(clock));
218 //     }
219 
220 //     // override
221 //     public MinguoDate date(TemporalAccessor temporal) {
222 //         if (cast(MinguoDate)(temporal) !is null) {
223 //             return cast(MinguoDate) temporal;
224 //         }
225 //         return new MinguoDate(LocalDate.from(temporal));
226 //     }
227 
228 //     // override
229 //     /*@SuppressWarnings("unchecked")*/
230 //     public ChronoLocalDateTime!(MinguoDate) localDateTime(TemporalAccessor temporal) {
231 //         return cast(ChronoLocalDateTime!(MinguoDate))super.localDateTime(temporal);
232 //     }
233 
234 //     // override
235 //     /*@SuppressWarnings("unchecked")*/
236 //     public ChronoZonedDateTime!(MinguoDate) zonedDateTime(TemporalAccessor temporal) {
237 //         return cast(ChronoZonedDateTime!(MinguoDate))super.zonedDateTime(temporal);
238 //     }
239 
240 //     // override
241 //     /*@SuppressWarnings("unchecked")*/
242 //     public ChronoZonedDateTime!(MinguoDate) zonedDateTime(Instant instant, ZoneId zone) {
243 //         return cast(ChronoZonedDateTime!(MinguoDate))super.zonedDateTime(instant, zone);
244 //     }
245 
246 //     //-----------------------------------------------------------------------
247 //     /**
248 //      * Checks if the specified year is a leap year.
249 //      * !(p)
250 //      * Minguo leap years occur exactly _in line with ISO leap years.
251 //      * This method does not validate the year passed _in, and only has a
252 //      * well-defined result for years _in the supported range.
253 //      *
254 //      * @param prolepticYear  the proleptic-year to check, not validated for range
255 //      * @return true if the year is a leap year
256 //      */
257 //     // override
258 //     public bool isLeapYear(long prolepticYear) {
259 //         return IsoChronology.INSTANCE.isLeapYear(prolepticYear + YEARS_DIFFERENCE);
260 //     }
261 
262 //     // override
263 //     public int prolepticYear(Era era, int yearOfEra) {
264 //         if ((cast(MinguoEra)(era) !is null) == false) {
265 //             throw new ClassCastException("Era must be MinguoEra");
266 //         }
267 //         return (era == MinguoEra.ROC ? yearOfEra : 1 - yearOfEra);
268 //     }
269 
270 //     // override
271 //     public MinguoEra eraOf(int eraValue) {
272 //         return MinguoEra.of(eraValue);
273 //     }
274 
275 //     // override
276 //     public List!(Era) eras() {
277 //         return List.of(MinguoEra.values());
278 //     }
279 
280 //     //-----------------------------------------------------------------------
281 //     // override
282 //     public ValueRange range(ChronoField field) {
283 //         switch (field) {
284 //             case PROLEPTIC_MONTH: {
285 //                 ValueRange range = PROLEPTIC_MONTH.range();
286 //                 return ValueRange.of(range.getMinimum() - YEARS_DIFFERENCE * 12L, range.getMaximum() - YEARS_DIFFERENCE * 12L);
287 //             }
288 //             case YEAR_OF_ERA: {
289 //                 ValueRange range = YEAR.range();
290 //                 return ValueRange.of(1, range.getMaximum() - YEARS_DIFFERENCE, -range.getMinimum() + 1 + YEARS_DIFFERENCE);
291 //             }
292 //             case YEAR: {
293 //                 ValueRange range = YEAR.range();
294 //                 return ValueRange.of(range.getMinimum() - YEARS_DIFFERENCE, range.getMaximum() - YEARS_DIFFERENCE);
295 //             }
296 //         }
297 //         return field.range();
298 //     }
299 
300 //     //-----------------------------------------------------------------------
301 //     override  // override for return type
302 //     public MinguoDate resolveDate(Map!(TemporalField, Long) fieldValues, ResolverStyle resolverStyle) {
303 //         return cast(MinguoDate) super.resolveDate(fieldValues, resolverStyle);
304 //     }
305 
306 //     //-----------------------------------------------------------------------
307 //     /**
308 //      * Writes the Chronology using a
309 //      * <a href="{@docRoot}/serialized-form.html#hunt.time.chrono.Ser">dedicated serialized form</a>.
310 //      * @serialData
311 //      * !(pre)
312 //      *  _out.writeByte(1);     // identifies a Chronology
313 //      *  _out.writeUTF(getId());
314 //      * </pre>
315 //      *
316 //      * @return the instance of {@code Ser}, not null
317 //      */
318 //     override
319 //     Object writeReplace() {
320 //         return super.writeReplace();
321 //     }
322 
323 //     /**
324 //      * Defend against malicious streams.
325 //      *
326 //      * @param s the stream to read
327 //      * @throws InvalidObjectException always
328 //      */
329 //      ///@gxc
330 //     // private void readObject(ObjectInputStream s) /*throws InvalidObjectException*/ {
331 //     //     throw new InvalidObjectException("Deserialization via serialization delegate");
332 //     // }
333 // }