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.Month;
13 
14 import hunt.time.temporal.ChronoField;
15 import hunt.time.temporal.ChronoUnit;
16 
17 import hunt.time.chrono.Chronology;
18 import hunt.time.chrono.IsoChronology;
19 // import hunt.time.format.DateTimeFormatterBuilder;
20 import hunt.time.format.TextStyle;
21 import hunt.time.temporal.ChronoField;
22 import hunt.time.temporal.Temporal;
23 import hunt.time.temporal.TemporalAccessor;
24 import hunt.time.temporal.TemporalAdjuster;
25 import hunt.time.temporal.TemporalField;
26 import hunt.time.temporal.TemporalQueries;
27 import hunt.time.temporal.TemporalQuery;
28 import hunt.time.Exceptions;
29 import hunt.time.temporal.ValueRange;
30 import hunt.time.Exceptions;
31 import hunt.time.LocalDate;
32 import hunt.time.util.Common;
33 
34 import hunt.Enum;
35 import hunt.util.Locale;
36 
37 import std.conv;
38 import std.concurrency : initOnce;
39 
40 /**
41  * A month-of-year, such as 'July'.
42  * !(p)
43  * {@code Month} is an enum representing the 12 months of the year -
44  * January, February, March, April, May, June, July, August, September, October,
45  * November and December.
46  * !(p)
47  * In addition to the textual enum name, each month-of-year has an {@code int} value.
48  * The {@code int} value follows normal usage and the ISO-8601 standard,
49  * from 1 (January) to 12 (December). It is recommended that applications use the enum
50  * rather than the {@code int} value to ensure code clarity.
51  * !(p)
52  * !(b)Do not use {@code ordinal()} to obtain the numeric representation of {@code Month}.
53  * Use {@code getValue()} instead.</b>
54  * !(p)
55  * This enum represents a common concept that is found _in many calendar systems.
56  * As such, this enum may be used by any calendar system that has the month-of-year
57  * concept defined exactly equivalent to the ISO-8601 calendar system.
58  *
59  * @implSpec
60  * This is an immutable and thread-safe enum.
61  *
62  * @since 1.8
63  */
64 class Month : AbstractEnum!Month, TemporalAccessor, TemporalAdjuster {
65 
66     /**
67      * The singleton instance for the month of January with 31 days.
68      * This has the numeric value of {@code 1}.
69      */
70     static Month JANUARY() {
71         __gshared Month m;
72         return initOnce!(m)(new Month(0, "JANUARY"));
73     }
74 
75     /**
76      * The singleton instance for the month of February with 28 days, or 29 _in a leap year.
77      * This has the numeric value of {@code 2}.
78      */
79     static Month FEBRUARY() {
80         __gshared Month m;
81         return initOnce!(m)(new Month(1, "FEBRUARY"));
82     }
83 
84     /**
85      * The singleton instance for the month of March with 31 days.
86      * This has the numeric value of {@code 3}.
87      */
88     static Month MARCH() {
89         __gshared Month m;
90         return initOnce!(m)(new Month(2, "MARCH"));
91     }
92     
93     /**
94      * The singleton instance for the month of April with 30 days.
95      * This has the numeric value of {@code 4}.
96      */
97     static Month APRIL() {
98         __gshared Month m;
99         return initOnce!(m)(new Month(3, "APRIL"));
100     }
101     
102     /**
103      * The singleton instance for the month of May with 31 days.
104      * This has the numeric value of {@code 5}.
105      */
106     static Month MAY() {
107         __gshared Month m;
108         return initOnce!(m)(new Month(5, "MAY"));
109     }
110     
111     /**
112      * The singleton instance for the month of June with 30 days.
113      * This has the numeric value of {@code 6}.
114      */
115     static Month JUNE() {
116         __gshared Month m;
117         return initOnce!(m)(new Month(5, "JUNE"));
118     }
119     
120     /**
121      * The singleton instance for the month of July with 31 days.
122      * This has the numeric value of {@code 7}.
123      */
124     static Month JULY() {
125         __gshared Month m;
126         return initOnce!(m)(new Month(6, "JULY"));
127     }
128     
129     /**
130      * The singleton instance for the month of August with 31 days.
131      * This has the numeric value of {@code 8}.
132      */
133     static Month AUGUST() {
134         __gshared Month m;
135         return initOnce!(m)(new Month(7, "AUGUST"));
136     }
137     
138     /**
139      * The singleton instance for the month of September with 30 days.
140      * This has the numeric value of {@code 9}.
141      */
142     static Month SEPTEMBER() {
143         __gshared Month m;
144         return initOnce!(m)(new Month(8, "SEPTEMBER"));
145     }
146     
147     /**
148      * The singleton instance for the month of October with 31 days.
149      * This has the numeric value of {@code 10}.
150      */
151     static Month OCTOBER() {
152         __gshared Month m;
153         return initOnce!(m)(new Month(9, "OCTOBER"));
154     }
155     
156     /**
157      * The singleton instance for the month of November with 30 days.
158      * This has the numeric value of {@code 11}.
159      */
160     static Month NOVEMBER() {
161         __gshared Month m;
162         return initOnce!(m)(new Month(10, "NOVEMBER"));
163     }
164     
165     /**
166      * The singleton instance for the month of December with 31 days.
167      * This has the numeric value of {@code 12}.
168      */
169     static Month DECEMBER() {
170         __gshared Month m;
171         return initOnce!(m)(new Month(11, "DECEMBER"));
172     }
173 
174 
175     this(int ordinal, string name) {
176         super(name, ordinal);
177     }
178 
179     alias ENUMS = values;
180 
181     /**
182      * Private cache of all the constants.
183      */
184     static Month[] values() {
185         __gshared Month[] _e;
186         return initOnce!(_e)({ 
187             Month[] _ENUMS;
188             if(_ENUMS.length == 0) {
189             /**
190             * The singleton instance for the month of January with 31 days.
191             * This has the numeric value of {@code 1}.
192             */
193                 _ENUMS ~= JANUARY;
194             /**
195             * The singleton instance for the month of February with 28 days, or 29 _in a leap year.
196             * This has the numeric value of {@code 2}.
197             */
198                 _ENUMS ~= FEBRUARY;
199             /**
200             * The singleton instance for the month of March with 31 days.
201             * This has the numeric value of {@code 3}.
202             */
203                 _ENUMS ~= MARCH;
204             /**
205             * The singleton instance for the month of April with 30 days.
206             * This has the numeric value of {@code 4}.
207             */
208                 _ENUMS ~= APRIL;
209             /**
210             * The singleton instance for the month of May with 31 days.
211             * This has the numeric value of {@code 5}.
212             */
213                 _ENUMS ~= MAY;
214             /**
215             * The singleton instance for the month of June with 30 days.
216             * This has the numeric value of {@code 6}.
217             */
218                 _ENUMS ~= JUNE;
219             /**
220             * The singleton instance for the month of July with 31 days.
221             * This has the numeric value of {@code 7}.
222             */
223                 _ENUMS ~= JULY;
224             /**
225             * The singleton instance for the month of August with 31 days.
226             * This has the numeric value of {@code 8}.
227             */
228                 _ENUMS ~= AUGUST;
229             /**
230             * The singleton instance for the month of September with 30 days.
231             * This has the numeric value of {@code 9}.
232             */
233                 _ENUMS ~= SEPTEMBER;
234             /**
235             * The singleton instance for the month of October with 31 days.
236             * This has the numeric value of {@code 10}.
237             */
238                 _ENUMS ~= OCTOBER;
239             /**
240             * The singleton instance for the month of November with 30 days.
241             * This has the numeric value of {@code 11}.
242             */
243                 _ENUMS ~= NOVEMBER;
244 
245             /**
246             * The singleton instance for the month of December with 31 days.
247             * This has the numeric value of {@code 12}.
248             */
249                 _ENUMS ~= DECEMBER;
250             }
251             return _ENUMS;
252         }());
253     }
254 
255 
256     //-----------------------------------------------------------------------
257     /**
258      * Obtains an instance of {@code Month} from an {@code int} value.
259      * !(p)
260      * {@code Month} is an enum representing the 12 months of the year.
261      * This factory allows the enum to be obtained from the {@code int} value.
262      * The {@code int} value follows the ISO-8601 standard, from 1 (January) to 12 (December).
263      *
264      * @param month  the month-of-year to represent, from 1 (January) to 12 (December)
265      * @return the month-of-year, not null
266      * @throws DateTimeException if the month-of-year is invalid
267      */
268     static Month of(int month)
269     {
270         if (month < 1 || month > 12)
271         {
272             throw new DateTimeException("Invalid value for MonthOfYear: " ~ month.to!string);
273         }
274         return ENUMS[month - 1];
275     }
276 
277     //-----------------------------------------------------------------------
278     /**
279      * Obtains an instance of {@code Month} from a temporal object.
280      * !(p)
281      * This obtains a month based on the specified temporal.
282      * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
283      * which this factory converts to an instance of {@code Month}.
284      * !(p)
285      * The conversion extracts the {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} field.
286      * The extraction is only permitted if the temporal object has an ISO
287      * chronology, or can be converted to a {@code LocalDate}.
288      * !(p)
289      * This method matches the signature of the functional interface {@link TemporalQuery}
290      * allowing it to be used as a query via method reference, {@code Month::from}.
291      *
292      * @param temporal  the temporal object to convert, not null
293      * @return the month-of-year, not null
294      * @throws DateTimeException if unable to convert to a {@code Month}
295      */
296     static Month from(TemporalAccessor temporal)
297     {
298         if (cast(Month)(temporal) !is null)
299         {
300             return cast(Month) temporal;
301         }
302         try
303         {
304             if ((IsoChronology.INSTANCE == Chronology.from(temporal)) == false)
305             {
306                 temporal = LocalDate.from(temporal);
307             }
308             return of(temporal.get(ChronoField.MONTH_OF_YEAR));
309         }
310         catch (DateTimeException ex)
311         {
312             throw new DateTimeException("Unable to obtain Month from TemporalAccessor: " ~ typeid(temporal)
313                     .name ~ " of type " ~ typeid(temporal).stringof, ex);
314         }
315     }
316 
317     //-----------------------------------------------------------------------
318     /**
319      * Gets the month-of-year {@code int} value.
320      * !(p)
321      * The values are numbered following the ISO-8601 standard,
322      * from 1 (January) to 12 (December).
323      *
324      * @return the month-of-year, from 1 (January) to 12 (December)
325      */
326     int getValue()
327     {
328         return ordinal() + 1;
329     }
330 
331     //-----------------------------------------------------------------------
332     /**
333      * Gets the textual representation, such as 'Jan' or 'December'.
334      * !(p)
335      * This returns the textual name used to identify the month-of-year,
336      * suitable for presentation to the user.
337      * The parameters control the style of the returned text and the locale.
338      * !(p)
339      * If no textual mapping is found then the {@link #getValue() numeric value} is returned.
340      *
341      * @param style  the length of the text required, not null
342      * @param locale  the locale to use, not null
343      * @return the text value of the month-of-year, not null
344      */
345     // string getDisplayName(TextStyle style, Locale locale)
346     // {
347     //     return new DateTimeFormatterBuilder().appendText(ChronoField.MONTH_OF_YEAR,
348     //             style).toFormatter(locale).format(this);
349     // }
350 
351     //-----------------------------------------------------------------------
352     /**
353      * Checks if the specified field is supported.
354      * !(p)
355      * This checks if this month-of-year can be queried for the specified field.
356      * If false, then calling the {@link #range(TemporalField) range} and
357      * {@link #get(TemporalField) get} methods will throw an exception.
358      * !(p)
359      * If the field is {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} then
360      * this method returns true.
361      * All other {@code ChronoField} instances will return false.
362      * !(p)
363      * If the field is not a {@code ChronoField}, then the result of this method
364      * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
365      * passing {@code this} as the argument.
366      * Whether the field is supported is determined by the field.
367      *
368      * @param field  the field to check, null returns false
369      * @return true if the field is supported on this month-of-year, false if not
370      */
371     override bool isSupported(TemporalField field)
372     {
373         if (cast(ChronoField)(field) !is null)
374         {
375             return field == ChronoField.MONTH_OF_YEAR;
376         }
377         return field !is null && field.isSupportedBy(this);
378     }
379 
380     /**
381      * Gets the range of valid values for the specified field.
382      * !(p)
383      * The range object expresses the minimum and maximum valid values for a field.
384      * This month is used to enhance the accuracy of the returned range.
385      * If it is not possible to return the range, because the field is not supported
386      * or for some other reason, an exception is thrown.
387      * !(p)
388      * If the field is {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} then the
389      * range of the month-of-year, from 1 to 12, will be returned.
390      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
391      * !(p)
392      * If the field is not a {@code ChronoField}, then the result of this method
393      * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
394      * passing {@code this} as the argument.
395      * Whether the range can be obtained is determined by the field.
396      *
397      * @param field  the field to query the range for, not null
398      * @return the range of valid values for the field, not null
399      * @throws DateTimeException if the range for the field cannot be obtained
400      * @throws UnsupportedTemporalTypeException if the field is not supported
401      */
402     override ValueRange range(TemporalField field)
403     {
404         if (field == ChronoField.MONTH_OF_YEAR)
405         {
406             return field.range();
407         }
408         return  /* TemporalAccessor. super.*/ super_range(field);
409     }
410 
411     ValueRange super_range(TemporalField field)
412     {
413         if (cast(ChronoField)(field) !is null)
414         {
415             if (isSupported(field))
416             {
417                 return field.range();
418             }
419             throw new UnsupportedTemporalTypeException("Unsupported field: " ~ typeid(field).name);
420         }
421         assert(field, "field");
422         return field.rangeRefinedBy(this);
423     }
424     /**
425      * Gets the value of the specified field from this month-of-year as an {@code int}.
426      * !(p)
427      * This queries this month for the value of the specified field.
428      * The returned value will always be within the valid range of values for the field.
429      * If it is not possible to return the value, because the field is not supported
430      * or for some other reason, an exception is thrown.
431      * !(p)
432      * If the field is {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} then the
433      * value of the month-of-year, from 1 to 12, will be returned.
434      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
435      * !(p)
436      * If the field is not a {@code ChronoField}, then the result of this method
437      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
438      * passing {@code this} as the argument. Whether the value can be obtained,
439      * and what the value represents, is determined by the field.
440      *
441      * @param field  the field to get, not null
442      * @return the value for the field, within the valid range of values
443      * @throws DateTimeException if a value for the field cannot be obtained or
444      *         the value is outside the range of valid values for the field
445      * @throws UnsupportedTemporalTypeException if the field is not supported or
446      *         the range of values exceeds an {@code int}
447      * @throws ArithmeticException if numeric overflow occurs
448      */
449     override int get(TemporalField field)
450     {
451         if (field == ChronoField.MONTH_OF_YEAR)
452         {
453             return getValue();
454         }
455         return  /* TemporalAccessor. super.*/ super_get(field);
456     }
457 
458     int super_get(TemporalField field)
459     {
460         ValueRange range = range(field);
461         if (range.isIntValue() == false)
462         {
463             throw new UnsupportedTemporalTypeException("Invalid field " ~ typeid(field)
464                     .name ~ " for get() method, use getLong() instead");
465         }
466         long value = getLong(field);
467         if (range.isValidValue(value) == false)
468         {
469             throw new DateTimeException("Invalid value for " ~ typeid(field)
470                     .name ~ " (valid values " ~ range.toString ~ "): " ~ value.to!string);
471         }
472         return cast(int) value;
473     }
474 
475     /**
476      * Gets the value of the specified field from this month-of-year as a {@code long}.
477      * !(p)
478      * This queries this month for the value of the specified field.
479      * If it is not possible to return the value, because the field is not supported
480      * or for some other reason, an exception is thrown.
481      * !(p)
482      * If the field is {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} then the
483      * value of the month-of-year, from 1 to 12, will be returned.
484      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
485      * !(p)
486      * If the field is not a {@code ChronoField}, then the result of this method
487      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
488      * passing {@code this} as the argument. Whether the value can be obtained,
489      * and what the value represents, is determined by the field.
490      *
491      * @param field  the field to get, not null
492      * @return the value for the field
493      * @throws DateTimeException if a value for the field cannot be obtained
494      * @throws UnsupportedTemporalTypeException if the field is not supported
495      * @throws ArithmeticException if numeric overflow occurs
496      */
497     override long getLong(TemporalField field)
498     {
499         if (field == ChronoField.MONTH_OF_YEAR)
500         {
501             return getValue();
502         }
503         else if (cast(ChronoField)(field) !is null)
504         {
505             throw new UnsupportedTemporalTypeException("Unsupported field: " ~ typeid(field).name);
506         }
507         return field.getFrom(this);
508     }
509 
510     //-----------------------------------------------------------------------
511     /**
512      * Returns the month-of-year that is the specified number of months after this one.
513      * !(p)
514      * The calculation rolls around the end of the year from December to January.
515      * The specified period may be negative.
516      * !(p)
517      * This instance is immutable and unaffected by this method call.
518      *
519      * @param months  the months to add, positive or negative
520      * @return the resulting month, not null
521      */
522     Month plus(long months)
523     {
524         int amount = cast(int)(months % 12);
525         return ENUMS[(ordinal() + (amount + 12)) % 12];
526     }
527 
528     /**
529      * Returns the month-of-year that is the specified number of months before this one.
530      * !(p)
531      * The calculation rolls around the start of the year from January to December.
532      * The specified period may be negative.
533      * !(p)
534      * This instance is immutable and unaffected by this method call.
535      *
536      * @param months  the months to subtract, positive or negative
537      * @return the resulting month, not null
538      */
539     Month minus(long months)
540     {
541         return plus(-(months % 12));
542     }
543 
544     //-----------------------------------------------------------------------
545     /**
546      * Gets the length of this month _in days.
547      * !(p)
548      * This takes a flag to determine whether to return the length for a leap year or not.
549      * !(p)
550      * February has 28 days _in a standard year and 29 days _in a leap year.
551      * April, June, September and November have 30 days.
552      * All other months have 31 days.
553      *
554      * @param leapYear  true if the length is required for a leap year
555      * @return the length of this month _in days, from 28 to 31
556      */
557     int length(bool leapYear)
558     {
559         switch (_ordinal)
560         {
561         case 1:
562             return (leapYear ? 29 : 28);
563         case 3:
564         case 5:
565         case 8:
566         case 10:
567             return 30;
568         default:
569             return 31;
570         }
571     }
572 
573     /**
574      * Gets the minimum length of this month _in days.
575      * !(p)
576      * February has a minimum length of 28 days.
577      * April, June, September and November have 30 days.
578      * All other months have 31 days.
579      *
580      * @return the minimum length of this month _in days, from 28 to 31
581      */
582     int minLength()
583     {
584         switch (_ordinal)
585         {
586         case 1:
587             return 28;
588         case 3:
589         case 5:
590         case 8:
591         case 10:
592             return 30;
593         default:
594             return 31;
595         }
596     }
597 
598     /**
599      * Gets the maximum length of this month _in days.
600      * !(p)
601      * February has a maximum length of 29 days.
602      * April, June, September and November have 30 days.
603      * All other months have 31 days.
604      *
605      * @return the maximum length of this month _in days, from 29 to 31
606      */
607     int maxLength()
608     {
609         switch (_ordinal)
610         {
611         case 1:
612             return 29;
613         case 3:
614         case 5:
615         case 8:
616         case 10:
617             return 30;
618         default:
619             return 31;
620         }
621     }
622 
623     //-----------------------------------------------------------------------
624     /**
625      * Gets the day-of-year corresponding to the first day of this month.
626      * !(p)
627      * This returns the day-of-year that this month begins on, using the leap
628      * year flag to determine the length of February.
629      *
630      * @param leapYear  true if the length is required for a leap year
631      * @return the day of year corresponding to the first day of this month, from 1 to 336
632      */
633     int firstDayOfYear(bool leapYear)
634     {
635         int leap = leapYear ? 1 : 0;
636         switch (_name)
637         {
638         case "JANUARY":
639             return 1;
640         case "FEBRUARY":
641             return 32;
642         case "MARCH":
643             return 60 + leap;
644         case "APRIL":
645             return 91 + leap;
646         case "MAY":
647             return 121 + leap;
648         case "JUNE":
649             return 152 + leap;
650         case "JULY":
651             return 182 + leap;
652         case "AUGUST":
653             return 213 + leap;
654         case "SEPTEMBER":
655             return 244 + leap;
656         case "OCTOBER":
657             return 274 + leap;
658         case "NOVEMBER":
659             return 305 + leap;
660         case "DECEMBER":
661         default:
662             return 335 + leap;
663         }
664     }
665 
666     /**
667      * Gets the month corresponding to the first month of this quarter.
668      * !(p)
669      * The year can be divided into four quarters.
670      * This method returns the first month of the quarter for the base month.
671      * January, February and March return January.
672      * April, May and June return April.
673      * July, August and September return July.
674      * October, November and December return October.
675      *
676      * @return the first month of the quarter corresponding to this month, not null
677      */
678     Month firstMonthOfQuarter()
679     {
680         return ENUMS[(ordinal() / 3) * 3];
681     }
682 
683     //-----------------------------------------------------------------------
684     /**
685      * Queries this month-of-year using the specified query.
686      * !(p)
687      * This queries this month-of-year using the specified query strategy object.
688      * The {@code TemporalQuery} object defines the logic to be used to
689      * obtain the result. Read the documentation of the query to understand
690      * what the result of this method will be.
691      * !(p)
692      * The result of this method is obtained by invoking the
693      * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
694      * specified query passing {@code this} as the argument.
695      *
696      * @param !(R) the type of the result
697      * @param query  the query to invoke, not null
698      * @return the query result, null may be returned (defined by the query)
699      * @throws DateTimeException if unable to query (defined by the query)
700      * @throws ArithmeticException if numeric overflow occurs (defined by the query)
701      */
702     /*@SuppressWarnings("unchecked")*/
703     // override
704     R query(R)(TemporalQuery!(R) query)
705     {
706         if (query == TemporalQueries.chronology())
707         {
708             return cast(R) IsoChronology.INSTANCE;
709         }
710         else if (query == TemporalQueries.precision())
711         {
712             return cast(R)(ChronoUnit.MONTHS);
713         }
714         return  /* TemporalAccessor. */ super_query(query);
715     }
716 
717     R super_query(R)(TemporalQuery!(R) query)
718     {
719         if (query == TemporalQueries.zoneId() || query == TemporalQueries.chronology()
720                 || query == TemporalQueries.precision())
721         {
722             return null;
723         }
724         return query.queryFrom(this);
725     }
726 
727     /**
728      * Adjusts the specified temporal object to have this month-of-year.
729      * !(p)
730      * This returns a temporal object of the same observable type as the input
731      * with the month-of-year changed to be the same as this.
732      * !(p)
733      * The adjustment is equivalent to using {@link Temporal#_with(TemporalField, long)}
734      * passing {@link ChronoField#MONTH_OF_YEAR} as the field.
735      * If the specified temporal object does not use the ISO calendar system then
736      * a {@code DateTimeException} is thrown.
737      * !(p)
738      * In most cases, it is clearer to reverse the calling pattern by using
739      * {@link Temporal#_with(TemporalAdjuster)}:
740      * !(pre)
741      *   // these two lines are equivalent, but the second approach is recommended
742      *   temporal = thisMonth.adjustInto(temporal);
743      *   temporal = temporal._with(thisMonth);
744      * </pre>
745      * !(p)
746      * For example, given a date _in May, the following are output:
747      * !(pre)
748      *   dateInMay._with(JANUARY);    // four months earlier
749      *   dateInMay._with(APRIL);      // one months earlier
750      *   dateInMay._with(MAY);        // same date
751      *   dateInMay._with(JUNE);       // one month later
752      *   dateInMay._with(DECEMBER);   // seven months later
753      * </pre>
754      * !(p)
755      * This instance is immutable and unaffected by this method call.
756      *
757      * @param temporal  the target object to be adjusted, not null
758      * @return the adjusted object, not null
759      * @throws DateTimeException if unable to make the adjustment
760      * @throws ArithmeticException if numeric overflow occurs
761      */
762     override Temporal adjustInto(Temporal temporal)
763     {
764         if ((Chronology.from(temporal) == IsoChronology.INSTANCE) == false)
765         {
766             throw new DateTimeException("Adjustment only supported on ISO date-time");
767         }
768         return temporal._with(ChronoField.MONTH_OF_YEAR, getValue());
769     }
770 
771     override string toString()
772     {
773         return this._name;
774     }
775 
776 }