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.JapaneseDate;
13 
14 // import hunt.time.temporal.ChronoField;
15 
16 // import hunt.stream.DataInput;
17 // import hunt.stream.DataOutput;
18 // import hunt.Exceptions;
19 
20 // //import hunt.io.ObjectInputStream;
21 // import hunt.stream.Common;
22 // import hunt.time.Clock;
23 // import hunt.time.Exceptions;
24 // import hunt.time.LocalDate;
25 // import hunt.time.LocalTime;
26 // import hunt.time.Period;
27 // import hunt.time.ZoneId;
28 // import hunt.time.temporal.ChronoField;
29 // import hunt.time.temporal.TemporalAccessor;
30 // import hunt.time.temporal.TemporalAdjuster;
31 // import hunt.time.temporal.TemporalAmount;
32 // import hunt.time.temporal.TemporalField;
33 // import hunt.time.temporal.TemporalQuery;
34 // import hunt.time.temporal.TemporalUnit;
35 // import hunt.time.Exceptions;
36 // import hunt.time.temporal.ValueRange;
37 // import hunt.time.util.Calendar;
38 // import hunt.time.chrono.ChronoLocalDateTimeImpl;
39 // import hunt.time.chrono.ChronoLocalDate;
40 // import hunt.time.chrono.JapaneseEra;
41 // import hunt.time.chrono.JapaneseChronology;
42 
43 // // import sun.util.calendar.CalendarDate;
44 // // import sun.util.calendar.LocalGregorianCalendar;
45 
46 // /**
47 //  * A date _in the Japanese Imperial calendar system.
48 //  * !(p)
49 //  * This date operates using the {@linkplain JapaneseChronology Japanese Imperial calendar}.
50 //  * This calendar system is primarily used _in Japan.
51 //  * !(p)
52 //  * The Japanese Imperial calendar system is the same as the ISO calendar system
53 //  * apart from the era-based year numbering. The proleptic-year is defined to be
54 //  * equal to the ISO proleptic-year.
55 //  * !(p)
56 //  * Japan introduced the Gregorian calendar starting with Meiji 6.
57 //  * Only Meiji and later eras are supported;
58 //  * dates before Meiji 6, January 1 are not supported.
59 //  * !(p)
60 //  * For example, the Japanese year "Heisei 24" corresponds to ISO year "2012".!(br)
61 //  * Calling {@code japaneseDate.get(YEAR_OF_ERA)} will return 24.!(br)
62 //  * Calling {@code japaneseDate.get(YEAR)} will return 2012.!(br)
63 //  * Calling {@code japaneseDate.get(ERA)} will return 2, corresponding to
64 //  * {@code JapaneseChronology.ERA_HEISEI}.!(br)
65 //  *
66 //  * !(p)
67 //  * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
68 //  * class; use of identity-sensitive operations (including reference equality
69 //  * ({@code ==}), identity hash code, or synchronization) on instances of
70 //  * {@code JapaneseDate} may have unpredictable results and should be avoided.
71 //  * The {@code equals} method should be used for comparisons.
72 //  *
73 //  * @implSpec
74 //  * This class is immutable and thread-safe.
75 //  *
76 //  * @since 1.8
77 //  */
78 // public final class JapaneseDate
79 //         : ChronoLocalDateImpl!(JapaneseDate)
80 //         , ChronoLocalDate, Serializable {
81 
82 //     /**
83 //      * Serialization version.
84 //      */
85 //     private enum long serialVersionUID = -305327627230580483L;
86 
87 //     /**
88 //      * The underlying ISO local date.
89 //      */
90 //     private  /*transient*/ LocalDate isoDate;
91 //     /**
92 //      * The JapaneseEra of this date.
93 //      */
94 //     private /*transient*/ JapaneseEra era;
95 //     /**
96 //      * The Japanese imperial calendar year of this date.
97 //      */
98 //     private /*transient*/ int yearOfEra;
99 
100 //     /**
101 //      * The first day supported by the JapaneseChronology is Meiji 6, January 1st.
102 //      */
103 //     __gshared LocalDate MEIJI_6_ISODATE;
104 
105 //     shared static this()
106 //     {
107 //         MEIJI_6_ISODATE = LocalDate.of(1873, 1, 1);
108 //     }
109 //     //-----------------------------------------------------------------------
110 //     /**
111 //      * Obtains the current {@code JapaneseDate} from the system clock _in the default time-zone.
112 //      * !(p)
113 //      * This will query the {@link Clock#systemDefaultZone() system clock} _in the default
114 //      * time-zone to obtain the current date.
115 //      * !(p)
116 //      * Using this method will prevent the ability to use an alternate clock for testing
117 //      * because the clock is hard-coded.
118 //      *
119 //      * @return the current date using the system clock and default time-zone, not null
120 //      */
121 //     public static JapaneseDate now() {
122 //         return now(Clock.systemDefaultZone());
123 //     }
124 
125 //     /**
126 //      * Obtains the current {@code JapaneseDate} from the system clock _in the specified time-zone.
127 //      * !(p)
128 //      * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date.
129 //      * Specifying the time-zone avoids dependence on the default time-zone.
130 //      * !(p)
131 //      * Using this method will prevent the ability to use an alternate clock for testing
132 //      * because the clock is hard-coded.
133 //      *
134 //      * @param zone  the zone ID to use, not null
135 //      * @return the current date using the system clock, not null
136 //      */
137 //     public static JapaneseDate now(ZoneId zone) {
138 //         return now(Clock.system(zone));
139 //     }
140 
141 //     /**
142 //      * Obtains the current {@code JapaneseDate} from the specified clock.
143 //      * !(p)
144 //      * This will query the specified clock to obtain the current date - today.
145 //      * Using this method allows the use of an alternate clock for testing.
146 //      * The alternate clock may be introduced using {@linkplain Clock dependency injection}.
147 //      *
148 //      * @param clock  the clock to use, not null
149 //      * @return the current date, not null
150 //      * @throws DateTimeException if the current date cannot be obtained
151 //      */
152 //     public static JapaneseDate now(Clock clock) {
153 //         return new JapaneseDate(LocalDate.now(clock));
154 //     }
155 
156 //     /**
157 //      * Obtains a {@code JapaneseDate} representing a date _in the Japanese calendar
158 //      * system from the era, year-of-era, month-of-year and day-of-month fields.
159 //      * !(p)
160 //      * This returns a {@code JapaneseDate} with the specified fields.
161 //      * The day must be valid for the year and month, otherwise an exception will be thrown.
162 //      * !(p)
163 //      * The Japanese month and day-of-month are the same as those _in the
164 //      * ISO calendar system. They are not reset when the era changes.
165 //      * For example:
166 //      * !(pre)
167 //      *  6th Jan Showa 64 = ISO 1989-01-06
168 //      *  7th Jan Showa 64 = ISO 1989-01-07
169 //      *  8th Jan Heisei 1 = ISO 1989-01-08
170 //      *  9th Jan Heisei 1 = ISO 1989-01-09
171 //      * </pre>
172 //      *
173 //      * @param era  the Japanese era, not null
174 //      * @param yearOfEra  the Japanese year-of-era
175 //      * @param month  the Japanese month-of-year, from 1 to 12
176 //      * @param dayOfMonth  the Japanese day-of-month, from 1 to 31
177 //      * @return the date _in Japanese calendar system, not null
178 //      * @throws DateTimeException if the value of any field is _out of range,
179 //      *  or if the day-of-month is invalid for the month-year,
180 //      *  or if the date is not a Japanese era
181 //      */
182 //      ///@gxc
183 //     // public static JapaneseDate of(JapaneseEra era, int yearOfEra, int month, int dayOfMonth) {
184 //     //     assert(era, "era");
185 //     //     LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null);
186 //     //     jdate.setEra(era.getPrivateEra()).setDate(yearOfEra, month, dayOfMonth);
187 //     //     if (!JapaneseChronology.JCAL.validate(jdate)) {
188 //     //         throw new DateTimeException("year, month, and day not valid for Era");
189 //     //     }
190 //     //     LocalDate date = LocalDate.of(jdate.getNormalizedYear(), month, dayOfMonth);
191 //     //     return new JapaneseDate(era, yearOfEra, date);
192 //     // }
193 
194 //     /**
195 //      * Obtains a {@code JapaneseDate} representing a date _in the Japanese calendar
196 //      * system from the proleptic-year, month-of-year and day-of-month fields.
197 //      * !(p)
198 //      * This returns a {@code JapaneseDate} with the specified fields.
199 //      * The day must be valid for the year and month, otherwise an exception will be thrown.
200 //      * !(p)
201 //      * The Japanese proleptic year, month and day-of-month are the same as those
202 //      * _in the ISO calendar system. They are not reset when the era changes.
203 //      *
204 //      * @param prolepticYear  the Japanese proleptic-year
205 //      * @param month  the Japanese month-of-year, from 1 to 12
206 //      * @param dayOfMonth  the Japanese day-of-month, from 1 to 31
207 //      * @return the date _in Japanese calendar system, not null
208 //      * @throws DateTimeException if the value of any field is _out of range,
209 //      *  or if the day-of-month is invalid for the month-year
210 //      */
211 //     public static JapaneseDate of(int prolepticYear, int month, int dayOfMonth) {
212 //         return new JapaneseDate(LocalDate.of(prolepticYear, month, dayOfMonth));
213 //     }
214 
215 //     /**
216 //      * Obtains a {@code JapaneseDate} representing a date _in the Japanese calendar
217 //      * system from the era, year-of-era and day-of-year fields.
218 //      * !(p)
219 //      * This returns a {@code JapaneseDate} with the specified fields.
220 //      * The day must be valid for the year, otherwise an exception will be thrown.
221 //      * !(p)
222 //      * The day-of-year _in this factory is expressed relative to the start of the year-of-era.
223 //      * This definition changes the normal meaning of day-of-year only _in those years
224 //      * where the year-of-era is reset to one due to a change _in the era.
225 //      * For example:
226 //      * !(pre)
227 //      *  6th Jan Showa 64 = day-of-year 6
228 //      *  7th Jan Showa 64 = day-of-year 7
229 //      *  8th Jan Heisei 1 = day-of-year 1
230 //      *  9th Jan Heisei 1 = day-of-year 2
231 //      * </pre>
232 //      *
233 //      * @param era  the Japanese era, not null
234 //      * @param yearOfEra  the Japanese year-of-era
235 //      * @param dayOfYear  the chronology day-of-year, from 1 to 366
236 //      * @return the date _in Japanese calendar system, not null
237 //      * @throws DateTimeException if the value of any field is _out of range,
238 //      *  or if the day-of-year is invalid for the year
239 //      */
240 //      ///@gxc
241 //     // static JapaneseDate ofYearDay(JapaneseEra era, int yearOfEra, int dayOfYear) {
242 //     //     assert(era, "era");
243 //     //     CalendarDate firstDay = era.getPrivateEra().getSinceDate();
244 //     //     LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null);
245 //     //     jdate.setEra(era.getPrivateEra());
246 //     //     if (yearOfEra == 1) {
247 //     //         jdate.setDate(yearOfEra, firstDay.getMonth(), firstDay.getDayOfMonth() + dayOfYear - 1);
248 //     //     } else {
249 //     //         jdate.setDate(yearOfEra, 1, dayOfYear);
250 //     //     }
251 //     //     JapaneseChronology.JCAL.normalize(jdate);
252 //     //     if (era.getPrivateEra() != jdate.getEra() || yearOfEra != jdate.getYear()) {
253 //     //         throw new DateTimeException("Invalid parameters");
254 //     //     }
255 //     //     LocalDate localdate = LocalDate.of(jdate.getNormalizedYear(),
256 //     //                                   jdate.getMonth(), jdate.getDayOfMonth());
257 //     //     return new JapaneseDate(era, yearOfEra, localdate);
258 //     // }
259 
260 //     /**
261 //      * Obtains a {@code JapaneseDate} from a temporal object.
262 //      * !(p)
263 //      * This obtains a date _in the Japanese calendar system based on the specified temporal.
264 //      * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
265 //      * which this factory converts to an instance of {@code JapaneseDate}.
266 //      * !(p)
267 //      * The conversion typically uses the {@link ChronoField#EPOCH_DAY EPOCH_DAY}
268 //      * field, which is standardized across calendar systems.
269 //      * !(p)
270 //      * This method matches the signature of the functional interface {@link TemporalQuery}
271 //      * allowing it to be used as a query via method reference, {@code JapaneseDate::from}.
272 //      *
273 //      * @param temporal  the temporal object to convert, not null
274 //      * @return the date _in Japanese calendar system, not null
275 //      * @throws DateTimeException if unable to convert to a {@code JapaneseDate}
276 //      */
277 //     public static JapaneseDate from(TemporalAccessor temporal) {
278 //         return JapaneseChronology.INSTANCE.date(temporal);
279 //     }
280 
281 //     //-----------------------------------------------------------------------
282 //     /**
283 //      * Creates an instance from an ISO date.
284 //      *
285 //      * @param isoDate  the standard local date, validated not null
286 //      */
287 //     this(LocalDate isoDate) {
288 //         if (isoDate.isBefore(MEIJI_6_ISODATE)) {
289 //             throw new DateTimeException("JapaneseDate before Meiji 6 is not supported");
290 //         }
291 //         LocalGregorianCalendar.Date jdate = toPrivateJapaneseDate(isoDate);
292 //         this.era = JapaneseEra.toJapaneseEra(jdate.getEra());
293 //         this.yearOfEra = jdate.getYear();
294 //         this.isoDate = isoDate;
295 //     }
296 
297 //     /**
298 //      * Constructs a {@code JapaneseDate}. This constructor does NOT validate the given parameters,
299 //      * and {@code era} and {@code year} must agree with {@code isoDate}.
300 //      *
301 //      * @param era  the era, validated not null
302 //      * @param year  the year-of-era, validated
303 //      * @param isoDate  the standard local date, validated not null
304 //      */
305 //     this(JapaneseEra era, int year, LocalDate isoDate) {
306 //         if (isoDate.isBefore(MEIJI_6_ISODATE)) {
307 //             throw new DateTimeException("JapaneseDate before Meiji 6 is not supported");
308 //         }
309 //         this.era = era;
310 //         this.yearOfEra = year;
311 //         this.isoDate = isoDate;
312 //     }
313 
314 //     //-----------------------------------------------------------------------
315 //     /**
316 //      * Gets the chronology of this date, which is the Japanese calendar system.
317 //      * !(p)
318 //      * The {@code Chronology} represents the calendar system _in use.
319 //      * The era and other fields _in {@link ChronoField} are defined by the chronology.
320 //      *
321 //      * @return the Japanese chronology, not null
322 //      */
323 //     override
324 //     public JapaneseChronology getChronology() {
325 //         return JapaneseChronology.INSTANCE;
326 //     }
327 
328 //     /**
329 //      * Gets the era applicable at this date.
330 //      * !(p)
331 //      * The Japanese calendar system has multiple eras defined by {@link JapaneseEra}.
332 //      *
333 //      * @return the era applicable at this date, not null
334 //      */
335 //     override
336 //     public JapaneseEra getEra() {
337 //         return era;
338 //     }
339 
340 //     /**
341 //      * Returns the length of the month represented by this date.
342 //      * !(p)
343 //      * This returns the length of the month _in days.
344 //      * Month lengths match those of the ISO calendar system.
345 //      *
346 //      * @return the length of the month _in days
347 //      */
348 //     override
349 //     public int lengthOfMonth() {
350 //         return isoDate.lengthOfMonth();
351 //     }
352 
353 //     override
354 //     public int lengthOfYear() {
355 //         Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE);
356 //         jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET);
357 //         jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth());
358 //         return  jcal.getActualMaximum(Calendar.DAY_OF_YEAR);
359 //     }
360 
361 //     //-----------------------------------------------------------------------
362 //     /**
363 //      * Checks if the specified field is supported.
364 //      * !(p)
365 //      * This checks if this date can be queried for the specified field.
366 //      * If false, then calling the {@link #range(TemporalField) range} and
367 //      * {@link #get(TemporalField) get} methods will throw an exception.
368 //      * !(p)
369 //      * If the field is a {@link ChronoField} then the query is implemented here.
370 //      * The supported fields are:
371 //      * !(ul)
372 //      * !(li){@code DAY_OF_WEEK}
373 //      * !(li){@code DAY_OF_MONTH}
374 //      * !(li){@code DAY_OF_YEAR}
375 //      * !(li){@code EPOCH_DAY}
376 //      * !(li){@code MONTH_OF_YEAR}
377 //      * !(li){@code PROLEPTIC_MONTH}
378 //      * !(li){@code YEAR_OF_ERA}
379 //      * !(li){@code YEAR}
380 //      * !(li){@code ERA}
381 //      * </ul>
382 //      * All other {@code ChronoField} instances will return false.
383 //      * !(p)
384 //      * If the field is not a {@code ChronoField}, then the result of this method
385 //      * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
386 //      * passing {@code this} as the argument.
387 //      * Whether the field is supported is determined by the field.
388 //      *
389 //      * @param field  the field to check, null returns false
390 //      * @return true if the field is supported on this date, false if not
391 //      */
392 //     override
393 //     public bool isSupported(TemporalField field) {
394 //         if (field == ALIGNED_DAY_OF_WEEK_IN_MONTH || field == ALIGNED_DAY_OF_WEEK_IN_YEAR ||
395 //                 field == ALIGNED_WEEK_OF_MONTH || field == ALIGNED_WEEK_OF_YEAR) {
396 //             return false;
397 //         }
398 //         return super.isSupported(field);
399 //     }
400 
401 //     override
402 //     public ValueRange range(TemporalField field) {
403 //         if (cast(ChronoField)(field) !is null) {
404 //             if (isSupported(field)) {
405 //                 ChronoField f = cast(ChronoField) field;
406 //                 switch (f) {
407 //                     case DAY_OF_MONTH: return ValueRange.of(1, lengthOfMonth());
408 //                     case DAY_OF_YEAR: return ValueRange.of(1, lengthOfYear());
409 //                     case YEAR_OF_ERA: {
410 //                         Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE);
411 //                         jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET);
412 //                         jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth());
413 //                         return ValueRange.of(1, jcal.getActualMaximum(Calendar.YEAR));
414 //                     }
415 //                 }
416 //                 return getChronology().range(f);
417 //             }
418 //             throw new UnsupportedTemporalTypeException("Unsupported field: " ~ field);
419 //         }
420 //         return field.rangeRefinedBy(this);
421 //     }
422 
423 //     override
424 //     public long getLong(TemporalField field) {
425 //         if (cast(ChronoField)(field) !is null) {
426 //             // same as ISO:
427 //             // DAY_OF_WEEK, DAY_OF_MONTH, EPOCH_DAY, MONTH_OF_YEAR, PROLEPTIC_MONTH, YEAR
428 //             //
429 //             // calendar specific fields
430 //             // DAY_OF_YEAR, YEAR_OF_ERA, ERA
431 //             switch (cast(ChronoField) field) {
432 //                 case ALIGNED_DAY_OF_WEEK_IN_MONTH:
433 //                 case ALIGNED_DAY_OF_WEEK_IN_YEAR:
434 //                 case ALIGNED_WEEK_OF_MONTH:
435 //                 case ALIGNED_WEEK_OF_YEAR:
436 //                     throw new UnsupportedTemporalTypeException("Unsupported field: " ~ field);
437 //                 case YEAR_OF_ERA:
438 //                     return yearOfEra;
439 //                 case ERA:
440 //                     return era.getValue();
441 //                 case DAY_OF_YEAR:
442 //                     Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE);
443 //                     jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET);
444 //                     jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth());
445 //                     return jcal.get(Calendar.DAY_OF_YEAR);
446 //             }
447 //             return isoDate.getLong(field);
448 //         }
449 //         return field.getFrom(this);
450 //     }
451 
452 //     /**
453 //      * Returns a {@code LocalGregorianCalendar.Date} converted from the given {@code isoDate}.
454 //      *
455 //      * @param isoDate  the local date, not null
456 //      * @return a {@code LocalGregorianCalendar.Date}, not null
457 //      */
458 //      ///@gxc
459 //     // private static LocalGregorianCalendar.Date toPrivateJapaneseDate(LocalDate isoDate) {
460 //     //     LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null);
461 //     //     sun.util.calendar.Era sunEra = JapaneseEra.privateEraFrom(isoDate);
462 //     //     int year = isoDate.getYear();
463 //     //     if (sunEra !is null) {
464 //     //         year -= sunEra.getSinceDate().getYear() - 1;
465 //     //     }
466 //     //     jdate.setEra(sunEra).setYear(year).setMonth(isoDate.getMonthValue()).setDayOfMonth(isoDate.getDayOfMonth());
467 //     //     JapaneseChronology.JCAL.normalize(jdate);
468 //     //     return jdate;
469 //     // }
470 
471 //     //-----------------------------------------------------------------------
472 //     override
473 //     public JapaneseDate _with(TemporalField field, long newValue) {
474 //         if (cast(ChronoField)(field) !is null) {
475 //             ChronoField f = cast(ChronoField) field;
476 //             if (getLong(f) == newValue) {  // getLong() validates for supported fields
477 //                 return this;
478 //             }
479 //             switch (f) {
480 //                 case YEAR_OF_ERA:
481 //                 case YEAR:
482 //                 case ERA: {
483 //                     int nvalue = getChronology().range(f).checkValidIntValue(newValue, f);
484 //                     switch (f) {
485 //                         case YEAR_OF_ERA:
486 //                             return this.withYear(nvalue);
487 //                         case YEAR:
488 //                             return _with(isoDate.withYear(nvalue));
489 //                         case ERA: {
490 //                             return this.withYear(JapaneseEra.of(nvalue), yearOfEra);
491 //                         }
492 //                     }
493 //                 }
494 //             }
495 //             // YEAR, PROLEPTIC_MONTH and others are same as ISO
496 //             return _with(isoDate._with(field, newValue));
497 //         }
498 //         return super._with(field, newValue);
499 //     }
500 
501 //     /**
502 //      * {@inheritDoc}
503 //      * @throws DateTimeException {@inheritDoc}
504 //      * @throws ArithmeticException {@inheritDoc}
505 //      */
506 //     override
507 //     public  JapaneseDate _with(TemporalAdjuster adjuster) {
508 //         return super._with(adjuster);
509 //     }
510 
511 //     /**
512 //      * {@inheritDoc}
513 //      * @throws DateTimeException {@inheritDoc}
514 //      * @throws ArithmeticException {@inheritDoc}
515 //      */
516 //     override
517 //     public JapaneseDate plus(TemporalAmount amount) {
518 //         return super.plus(amount);
519 //     }
520 
521 //     /**
522 //      * {@inheritDoc}
523 //      * @throws DateTimeException {@inheritDoc}
524 //      * @throws ArithmeticException {@inheritDoc}
525 //      */
526 //     override
527 //     public JapaneseDate minus(TemporalAmount amount) {
528 //         return super.minus(amount);
529 //     }
530 //     //-----------------------------------------------------------------------
531 //     /**
532 //      * Returns a copy of this date with the year altered.
533 //      * !(p)
534 //      * This method changes the year of the date.
535 //      * If the month-day is invalid for the year, then the previous valid day
536 //      * will be selected instead.
537 //      * !(p)
538 //      * This instance is immutable and unaffected by this method call.
539 //      *
540 //      * @param era  the era to set _in the result, not null
541 //      * @param yearOfEra  the year-of-era to set _in the returned date
542 //      * @return a {@code JapaneseDate} based on this date with the requested year, never null
543 //      * @throws DateTimeException if {@code year} is invalid
544 //      */
545 //     private JapaneseDate withYear(JapaneseEra era, int yearOfEra) {
546 //         int year = JapaneseChronology.INSTANCE.prolepticYear(era, yearOfEra);
547 //         return _with(isoDate.withYear(year));
548 //     }
549 
550 //     /**
551 //      * Returns a copy of this date with the year-of-era altered.
552 //      * !(p)
553 //      * This method changes the year-of-era of the date.
554 //      * If the month-day is invalid for the year, then the previous valid day
555 //      * will be selected instead.
556 //      * !(p)
557 //      * This instance is immutable and unaffected by this method call.
558 //      *
559 //      * @param year  the year to set _in the returned date
560 //      * @return a {@code JapaneseDate} based on this date with the requested year-of-era, never null
561 //      * @throws DateTimeException if {@code year} is invalid
562 //      */
563 //     private JapaneseDate withYear(int year) {
564 //         return withYear(getEra(), year);
565 //     }
566 
567 //     //-----------------------------------------------------------------------
568 //     override
569 //     JapaneseDate plusYears(long years) {
570 //         return _with(isoDate.plusYears(years));
571 //     }
572 
573 //     override
574 //     JapaneseDate plusMonths(long months) {
575 //         return _with(isoDate.plusMonths(months));
576 //     }
577 
578 //     override
579 //     JapaneseDate plusWeeks(long weeksToAdd) {
580 //         return _with(isoDate.plusWeeks(weeksToAdd));
581 //     }
582 
583 //     override
584 //     JapaneseDate plusDays(long days) {
585 //         return _with(isoDate.plusDays(days));
586 //     }
587 
588 //     override
589 //     public JapaneseDate plus(long amountToAdd, TemporalUnit unit) {
590 //         return super.plus(amountToAdd, unit);
591 //     }
592 
593 //     override
594 //     public JapaneseDate minus(long amountToAdd, TemporalUnit unit) {
595 //         return super.minus(amountToAdd, unit);
596 //     }
597 
598 //     override
599 //     JapaneseDate minusYears(long yearsToSubtract) {
600 //         return super.minusYears(yearsToSubtract);
601 //     }
602 
603 //     override
604 //     JapaneseDate minusMonths(long monthsToSubtract) {
605 //         return super.minusMonths(monthsToSubtract);
606 //     }
607 
608 //     override
609 //     JapaneseDate minusWeeks(long weeksToSubtract) {
610 //         return super.minusWeeks(weeksToSubtract);
611 //     }
612 
613 //     override
614 //     JapaneseDate minusDays(long daysToSubtract) {
615 //         return super.minusDays(daysToSubtract);
616 //     }
617 
618 //     private JapaneseDate _with(LocalDate newDate) {
619 //         return (newDate.equals(isoDate) ? this : new JapaneseDate(newDate));
620 //     }
621 
622 //     override        // for javadoc and covariant return type
623 //     /*@SuppressWarnings("unchecked")*/
624 //     public final ChronoLocalDateTime!(JapaneseDate) atTime(LocalTime localTime) {
625 //         return cast(ChronoLocalDateTime!(JapaneseDate))super.atTime(localTime);
626 //     }
627 
628 //     override
629 //     public ChronoPeriod until(ChronoLocalDate endDate) {
630 //         Period period = isoDate.until(endDate);
631 //         return getChronology().period(period.getYears(), period.getMonths(), period.getDays());
632 //     }
633 
634 //     override  // override for performance
635 //     public long toEpochDay() {
636 //         return isoDate.toEpochDay();
637 //     }
638 
639 //     //-------------------------------------------------------------------------
640 //     /**
641 //      * Compares this date to another date, including the chronology.
642 //      * !(p)
643 //      * Compares this {@code JapaneseDate} with another ensuring that the date is the same.
644 //      * !(p)
645 //      * Only objects of type {@code JapaneseDate} are compared, other types return false.
646 //      * To compare the dates of two {@code TemporalAccessor} instances, including dates
647 //      * _in two different chronologies, use {@link ChronoField#EPOCH_DAY} as a comparator.
648 //      *
649 //      * @param obj  the object to check, null returns false
650 //      * @return true if this is equal to the other date
651 //      */
652 //     override  // override for performance
653 //     public bool opEquals(Object obj) {
654 //         if (this is obj) {
655 //             return true;
656 //         }
657 //         if (cast(JapaneseDate)(obj) !is null) {
658 //             JapaneseDate otherDate = cast(JapaneseDate) obj;
659 //             return this.isoDate.equals(otherDate.isoDate);
660 //         }
661 //         return false;
662 //     }
663 
664 //     /**
665 //      * A hash code for this date.
666 //      *
667 //      * @return a suitable hash code based only on the Chronology and the date
668 //      */
669 //     override  // override for performance
670 //     public size_t toHash() @trusted nothrow {
671 //         return getChronology().getId().toHash() ^ isoDate.toHash();
672 //     }
673 
674 //     //-----------------------------------------------------------------------
675 //     /**
676 //      * Defend against malicious streams.
677 //      *
678 //      * @param s the stream to read
679 //      * @throws InvalidObjectException always
680 //      */
681 //     private void readObject(ObjectInputStream s) /*throws InvalidObjectException*/ {
682 //         throw new InvalidObjectException("Deserialization via serialization delegate");
683 //     }
684 
685 //     /**
686 //      * Writes the object using a
687 //      * <a href="{@docRoot}/serialized-form.html#hunt.time.chrono.Ser">dedicated serialized form</a>.
688 //      * @serialData
689 //      * !(pre)
690 //      *  _out.writeByte(4);                 // identifies a JapaneseDate
691 //      *  _out.writeInt(get(YEAR));
692 //      *  _out.writeByte(get(MONTH_OF_YEAR));
693 //      *  _out.writeByte(get(DAY_OF_MONTH));
694 //      * </pre>
695 //      *
696 //      * @return the instance of {@code Ser}, not null
697 //      */
698 //     private Object writeReplace() {
699 //         return new Ser(Ser.JAPANESE_DATE_TYPE, this);
700 //     }
701 
702 //     void writeExternal(DataOutput _out) /*throws IOException*/ {
703 //         // JapaneseChronology is implicit _in the JAPANESE_DATE_TYPE
704 //         _out.writeInt(get(YEAR));
705 //         _out.writeByte(get(MONTH_OF_YEAR));
706 //         _out.writeByte(get(DAY_OF_MONTH));
707 //     }
708 
709 //     static JapaneseDate readExternal(DataInput _in) /*throws IOException*/ {
710 //         int year = _in.readInt();
711 //         int month = _in.readByte();
712 //         int dayOfMonth = _in.readByte();
713 //         return JapaneseChronology.INSTANCE.date(year, month, dayOfMonth);
714 //     }
715 
716 // }