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.JapaneseEra;
13 
14 // import hunt.time.chrono.JapaneseDate;
15 // import hunt.time.temporal.ChronoField;
16 
17 // import hunt.stream.DataInput;
18 // import hunt.stream.DataOutput;
19 // import hunt.Exceptions;
20 
21 // //import hunt.io.ObjectInputStream;
22 // // import hunt.io.ObjectStreamException;
23 // import hunt.stream.Common;
24 // import hunt.time.Exceptions;
25 // import hunt.time.LocalDate;
26 // import hunt.time.format.DateTimeFormatterBuilder;
27 // import hunt.time.format.TextStyle;
28 // import hunt.time.temporal.ChronoField;
29 // import hunt.time.temporal.TemporalField;
30 // import hunt.time.Exceptions;
31 // import hunt.time.temporal.ValueRange;
32 // //import hunt.concurrent.ConcurrentMap;;
33 // // import hunt.time.util.Locale;
34 // import hunt.time.chrono.Era;
35 
36 // // import sun.util.calendar.CalendarDate;
37 
38 // /**
39 //  * An era _in the Japanese Imperial calendar system.
40 //  * !(p)
41 //  * This class defines the valid eras for the Japanese chronology.
42 //  * Japan introduced the Gregorian calendar starting with Meiji 6.
43 //  * Only Meiji and later eras are supported;
44 //  * dates before Meiji 6, January 1 are not supported.
45 //  * The number of the valid eras may increase, as new eras may be
46 //  * defined by the Japanese government. Once an era is defined,
47 //  * subsequent versions of this class will add a singleton instance
48 //  * for it. The defined era is expected to have a consecutive integer
49 //  * associated with it.
50 //  *
51 //  * @implSpec
52 //  * This class is immutable and thread-safe.
53 //  *
54 //  * @since 1.8
55 //  */
56 // public final class JapaneseEra
57 //         : Era, Serializable {
58 
59 //     // The offset value to 0-based index from the era value.
60 //     // i.e., getValue() + ERA_OFFSET == 0-based index
61 //     static final int ERA_OFFSET = 2;
62 
63 //     static final sun.util.calendar.Era[] ERA_CONFIG;
64 
65 //     /**
66 //      * The singleton instance for the 'Meiji' era (1868-01-01 - 1912-07-29)
67 //      * which has the value -1.
68 //      */
69 //     public static final JapaneseEra MEIJI = new JapaneseEra(-1, LocalDate.of(1868, 1, 1));
70 //     /**
71 //      * The singleton instance for the 'Taisho' era (1912-07-30 - 1926-12-24)
72 //      * which has the value 0.
73 //      */
74 //     public static final JapaneseEra TAISHO = new JapaneseEra(0, LocalDate.of(1912, 7, 30));
75 //     /**
76 //      * The singleton instance for the 'Showa' era (1926-12-25 - 1989-01-07)
77 //      * which has the value 1.
78 //      */
79 //     public static final JapaneseEra SHOWA = new JapaneseEra(1, LocalDate.of(1926, 12, 25));
80 //     /**
81 //      * The singleton instance for the 'Heisei' era (1989-01-08 - 2019-04-30)
82 //      * which has the value 2.
83 //      */
84 //     public static final JapaneseEra HEISEI = new JapaneseEra(2, LocalDate.of(1989, 1, 8));
85 //     /**
86 //      * The singleton instance for the 'NewEra' era (2019-05-01 - current)
87 //      * which has the value 3.
88 //      */
89 //     private static final JapaneseEra NEWERA = new JapaneseEra(3, LocalDate.of(2019, 5, 1));
90 
91 //     // The number of predefined JapaneseEra constants.
92 //     // There may be a supplemental era defined by the property.
93 //     private static final int N_ERA_CONSTANTS = NEWERA.getValue() + ERA_OFFSET;
94 
95 //     /**
96 //      * Serialization version.
97 //      */
98 //     private static final long serialVersionUID = 1466499369062886794L;
99 
100 //     // array for the singleton JapaneseEra instances
101 //     private static final JapaneseEra[] KNOWN_ERAS;
102 
103 //     static this(){
104 //         ERA_CONFIG = JapaneseChronology.JCAL.getEras();
105 
106 //         KNOWN_ERAS = new JapaneseEra[ERA_CONFIG.length];
107 //         KNOWN_ERAS[0] = MEIJI;
108 //         KNOWN_ERAS[1] = TAISHO;
109 //         KNOWN_ERAS[2] = SHOWA;
110 //         KNOWN_ERAS[3] = HEISEI;
111 //         KNOWN_ERAS[4] = NEWERA;
112 //         for (int i = N_ERA_CONSTANTS; i < ERA_CONFIG.length; i++) {
113 //             CalendarDate date = ERA_CONFIG[i].getSinceDate();
114 //             LocalDate isoDate = LocalDate.of(date.getYear(), date.getMonth(), date.getDayOfMonth());
115 //             KNOWN_ERAS[i] = new JapaneseEra(i - ERA_OFFSET + 1, isoDate);
116 //         }
117 //     };
118 
119 //     /**
120 //      * The era value.
121 //      * @serial
122 //      */
123 //     private final /*transient*/ int eraValue;
124 
125 //     // the first day of the era
126 //     private final /*transient*/ LocalDate since;
127 
128 //     /**
129 //      * Creates an instance.
130 //      *
131 //      * @param eraValue  the era value, validated
132 //      * @param since  the date representing the first date of the era, validated not null
133 //      */
134 //     private this(int eraValue, LocalDate since) {
135 //         this.eraValue = eraValue;
136 //         this.since = since;
137 //     }
138 
139 //     //-----------------------------------------------------------------------
140 //     /**
141 //      * Returns the Sun private Era instance corresponding to this {@code JapaneseEra}.
142 //      *
143 //      * @return the Sun private Era instance for this {@code JapaneseEra}.
144 //      */
145 //     sun.util.calendar.Era getPrivateEra() {
146 //         return ERA_CONFIG[ordinal(eraValue)];
147 //     }
148 
149 //     //-----------------------------------------------------------------------
150 //     /**
151 //      * Obtains an instance of {@code JapaneseEra} from an {@code int} value.
152 //      * !(p)
153 //      * The {@link #SHOWA} era that contains 1970-01-01 (ISO calendar system) has the value 1.
154 //      * Later era is numbered 2 ({@link #HEISEI}). Earlier eras are numbered 0 ({@link #TAISHO}),
155 //      * -1 ({@link #MEIJI}), only Meiji and later eras are supported.
156 //      * !(p)
157 //      * In addition to the known era singletons, values for additional
158 //      * eras may be defined. Those values are the {@link Era#getValue()}
159 //      * of corresponding eras from the {@link #values()} method.
160 //      *
161 //      * @param japaneseEra  the era to represent
162 //      * @return the {@code JapaneseEra} singleton, not null
163 //      * @throws DateTimeException if the value is invalid
164 //      */
165 //     public static JapaneseEra of(int japaneseEra) {
166 //         int i = ordinal(japaneseEra);
167 //         if (i < 0 || i >= KNOWN_ERAS.length) {
168 //             throw new DateTimeException("Invalid era: " ~ japaneseEra);
169 //         }
170 //         return KNOWN_ERAS[i];
171 //     }
172 
173 //     /**
174 //      * Returns the {@code JapaneseEra} with the name.
175 //      * !(p)
176 //      * The string must match exactly the name of the era.
177 //      * (Extraneous whitespace characters are not permitted.)
178 //      * !(p)
179 //      * Valid era names are the names of eras returned from {@link #values()}.
180 //      *
181 //      * @param japaneseEra  the japaneseEra name; non-null
182 //      * @return the {@code JapaneseEra} singleton, never null
183 //      * @throws IllegalArgumentException if there is not JapaneseEra with the specified name
184 //      */
185 //     public static JapaneseEra valueOf(string japaneseEra) {
186 //         assert(japaneseEra, "japaneseEra");
187 //         foreach(JapaneseEra era ; KNOWN_ERAS) {
188 //             if (era.getName().equals(japaneseEra)) {
189 //                 return era;
190 //             }
191 //         }
192 //         throw new IllegalArgumentException("japaneseEra is invalid");
193 //     }
194 
195 //     /**
196 //      * Returns an array of JapaneseEras. The array may contain eras defined
197 //      * by the Japanese government beyond the known era singletons.
198 //      *
199 //      * !(p)
200 //      * This method may be used to iterate over the JapaneseEras as follows:
201 //      * !(pre)
202 //      * foreach(JapaneseEra c ; JapaneseEra.values())
203 //      *     System._out.println(c);
204 //      * </pre>
205 //      *
206 //      * @return an array of JapaneseEras
207 //      */
208 //     public static JapaneseEra[] values() {
209 //         return Arrays.copyOf(KNOWN_ERAS, KNOWN_ERAS.length);
210 //     }
211 
212 //     /**
213 //      * {@inheritDoc}
214 //      *
215 //      * @param style {@inheritDoc}
216 //      * @param locale {@inheritDoc}
217 //      */
218 //     override
219 //     public string getDisplayName(TextStyle style, Locale locale) {
220 //         // If this JapaneseEra is a supplemental one, obtain the name from
221 //         // the era definition.
222 //         if (getValue() > N_ERA_CONSTANTS - ERA_OFFSET) {
223 //             assert(locale, "locale");
224 //             return style.asNormal() == TextStyle.NARROW ? getAbbreviation() : getName();
225 //         }
226 
227 //         return new DateTimeFormatterBuilder()
228 //             .appendText(ERA, style)
229 //             .toFormatter(locale)
230 //             .withChronology(JapaneseChronology.INSTANCE)
231 //             .format(this == MEIJI ? MEIJI_6_ISODATE : since);
232 //     }
233 
234 //     //-----------------------------------------------------------------------
235 //     /**
236 //      * Obtains an instance of {@code JapaneseEra} from a date.
237 //      *
238 //      * @param date  the date, not null
239 //      * @return the Era singleton, never null
240 //      */
241 //     static JapaneseEra from(LocalDate date) {
242 //         if (date.isBefore(MEIJI_6_ISODATE)) {
243 //             throw new DateTimeException("JapaneseDate before Meiji 6 are not supported");
244 //         }
245 //         for (int i = KNOWN_ERAS.length - 1; i > 0; i--) {
246 //             JapaneseEra era = KNOWN_ERAS[i];
247 //             if (date.compareTo(era.since) >= 0) {
248 //                 return era;
249 //             }
250 //         }
251 //         return null;
252 //     }
253 
254 //     static JapaneseEra toJapaneseEra(sun.util.calendar.Era privateEra) {
255 //         for (int i = ERA_CONFIG.length - 1; i >= 0; i--) {
256 //             if (ERA_CONFIG[i].equals(privateEra)) {
257 //                 return KNOWN_ERAS[i];
258 //             }
259 //         }
260 //         return null;
261 //     }
262 
263 //     static sun.util.calendar.Era privateEraFrom(LocalDate isoDate) {
264 //         for (int i = KNOWN_ERAS.length - 1; i > 0; i--) {
265 //             JapaneseEra era = KNOWN_ERAS[i];
266 //             if (isoDate.compareTo(era.since) >= 0) {
267 //                 return ERA_CONFIG[i];
268 //             }
269 //         }
270 //         return null;
271 //     }
272 
273 //     /**
274 //      * Returns the index into the arrays from the Era value.
275 //      * the eraValue is a valid Era number, -1..2.
276 //      *
277 //      * @param eraValue  the era value to convert to the index
278 //      * @return the index of the current Era
279 //      */
280 //     private static int ordinal(int eraValue) {
281 //         return eraValue + ERA_OFFSET - 1;
282 //     }
283 
284 //     //-----------------------------------------------------------------------
285 //     /**
286 //      * Gets the numeric era {@code int} value.
287 //      * !(p)
288 //      * The {@link #SHOWA} era that contains 1970-01-01 (ISO calendar system) has the value 1.
289 //      * Later eras are numbered from 2 ({@link #HEISEI}).
290 //      * Earlier eras are numbered 0 ({@link #TAISHO}), -1 ({@link #MEIJI})).
291 //      *
292 //      * @return the era value
293 //      */
294 //     override
295 //     public int getValue() {
296 //         return eraValue;
297 //     }
298 
299 //     //-----------------------------------------------------------------------
300 //     /**
301 //      * Gets the range of valid values for the specified field.
302 //      * !(p)
303 //      * The range object expresses the minimum and maximum valid values for a field.
304 //      * This era is used to enhance the accuracy of the returned range.
305 //      * If it is not possible to return the range, because the field is not supported
306 //      * or for some other reason, an exception is thrown.
307 //      * !(p)
308 //      * If the field is a {@link ChronoField} then the query is implemented here.
309 //      * The {@code ERA} field returns the range.
310 //      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
311 //      * !(p)
312 //      * If the field is not a {@code ChronoField}, then the result of this method
313 //      * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
314 //      * passing {@code this} as the argument.
315 //      * Whether the range can be obtained is determined by the field.
316 //      * !(p)
317 //      * The range of valid Japanese eras can change over time due to the nature
318 //      * of the Japanese calendar system.
319 //      *
320 //      * @param field  the field to query the range for, not null
321 //      * @return the range of valid values for the field, not null
322 //      * @throws DateTimeException if the range for the field cannot be obtained
323 //      * @throws UnsupportedTemporalTypeException if the unit is not supported
324 //      */
325 //     override  // override as super would return range from 0 to 1
326 //     public ValueRange range(TemporalField field) {
327 //         if (field == ERA) {
328 //             return JapaneseChronology.INSTANCE.range(ERA);
329 //         }
330 //         return /* Era. */super.range(field);
331 //     }
332 
333 //     //-----------------------------------------------------------------------
334 //     string getAbbreviation() {
335 //         return ERA_CONFIG[ordinal(getValue())].getAbbreviation();
336 //     }
337 
338 //     string getName() {
339 //         return ERA_CONFIG[ordinal(getValue())].getName();
340 //     }
341 
342 //     override
343 //     public string toString() {
344 //         return getName();
345 //     }
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 
358 //     //-----------------------------------------------------------------------
359 //     /**
360 //      * Writes the object using a
361 //      * <a href="{@docRoot}/serialized-form.html#hunt.time.chrono.Ser">dedicated serialized form</a>.
362 //      * @serialData
363 //      * !(pre)
364 //      *  _out.writeByte(5);        // identifies a JapaneseEra
365 //      *  _out.writeInt(getValue());
366 //      * </pre>
367 //      *
368 //      * @return the instance of {@code Ser}, not null
369 //      */
370 //     private Object writeReplace() {
371 //         return new Ser(Ser.JAPANESE_ERA_TYPE, this);
372 //     }
373 
374 //     void writeExternal(DataOutput _out) /*throws IOException*/ {
375 //         _out.writeByte(this.getValue());
376 //     }
377 
378 //     static JapaneseEra readExternal(DataInput _in) /*throws IOException*/ {
379 //         byte eraValue = _in.readByte();
380 //         return JapaneseEra.of(eraValue);
381 //     }
382 
383 // }