1 /*
2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
44 * and/or other materials provided with the distribution.
45 *
46 * * Neither the name of JSR-310 nor the names of its contributors
47 * may be used to endorse or promote products derived from this software
48 * without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
54 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
55 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
56 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
57 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
58 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
59 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 */
62 package java.time.chrono;
63
64 import java.io.InvalidObjectException;
65 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
66 import static java.time.temporal.ChronoField.ERA;
67 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
68 import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
69 import static java.time.temporal.ChronoField.YEAR;
70 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
71
72 import java.io.ObjectInputStream;
73 import java.io.Serializable;
74 import java.time.Clock;
75 import java.time.DateTimeException;
76 import java.time.Instant;
77 import java.time.LocalDate;
78 import java.time.LocalDateTime;
79 import java.time.Month;
80 import java.time.Period;
81 import java.time.Year;
82 import java.time.ZoneId;
83 import java.time.ZonedDateTime;
84 import java.time.format.ResolverStyle;
85 import java.time.temporal.ChronoField;
86 import java.time.temporal.TemporalAccessor;
87 import java.time.temporal.TemporalField;
88 import java.time.temporal.ValueRange;
89 import java.util.Arrays;
90 import java.util.List;
91 import java.util.Locale;
92 import java.util.Map;
93 import java.util.Objects;
94
95 /**
96 * The ISO calendar system.
97 * <p>
98 * This chronology defines the rules of the ISO calendar system.
99 * This calendar system is based on the ISO-8601 standard, which is the
100 * <i>de facto</i> world calendar.
101 * <p>
102 * The fields are defined as follows:
103 * <ul>
115 * <li>leap-year - Leap years occur every 4 years, except where the year is divisble by 100 and not divisble by 400.
116 * </ul>
117 *
118 * @implSpec
119 * This class is immutable and thread-safe.
120 *
121 * @since 1.8
122 */
123 public final class IsoChronology extends AbstractChronology implements Serializable {
124
125 /**
126 * Singleton instance of the ISO chronology.
127 */
128 public static final IsoChronology INSTANCE = new IsoChronology();
129
130 /**
131 * Serialization version.
132 */
133 private static final long serialVersionUID = -1440403870442975015L;
134
135 /**
136 * Restricted constructor.
137 */
138 private IsoChronology() {
139 }
140
141 //-----------------------------------------------------------------------
142 /**
143 * Gets the ID of the chronology - 'ISO'.
144 * <p>
145 * The ID uniquely identifies the {@code Chronology}.
146 * It can be used to lookup the {@code Chronology} using {@link Chronology#of(String)}.
147 *
148 * @return the chronology ID - 'ISO'
149 * @see #getCalendarType()
150 */
151 @Override
152 public String getId() {
153 return "ISO";
154 }
246 @Override // override with covariant return type
247 public LocalDate dateEpochDay(long epochDay) {
248 return LocalDate.ofEpochDay(epochDay);
249 }
250
251 //-----------------------------------------------------------------------
252 /**
253 * Obtains an ISO local date from another date-time object.
254 * <p>
255 * This is equivalent to {@link LocalDate#from(TemporalAccessor)}.
256 *
257 * @param temporal the date-time object to convert, not null
258 * @return the ISO local date, not null
259 * @throws DateTimeException if unable to create the date
260 */
261 @Override // override with covariant return type
262 public LocalDate date(TemporalAccessor temporal) {
263 return LocalDate.from(temporal);
264 }
265
266 /**
267 * Obtains an ISO local date-time from another date-time object.
268 * <p>
269 * This is equivalent to {@link LocalDateTime#from(TemporalAccessor)}.
270 *
271 * @param temporal the date-time object to convert, not null
272 * @return the ISO local date-time, not null
273 * @throws DateTimeException if unable to create the date-time
274 */
275 @Override // override with covariant return type
276 public LocalDateTime localDateTime(TemporalAccessor temporal) {
277 return LocalDateTime.from(temporal);
278 }
279
280 /**
281 * Obtains an ISO zoned date-time from another date-time object.
282 * <p>
283 * This is equivalent to {@link ZonedDateTime#from(TemporalAccessor)}.
284 *
285 * @param temporal the date-time object to convert, not null
|
1 /*
2 * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
44 * and/or other materials provided with the distribution.
45 *
46 * * Neither the name of JSR-310 nor the names of its contributors
47 * may be used to endorse or promote products derived from this software
48 * without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
54 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
55 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
56 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
57 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
58 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
59 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 */
62 package java.time.chrono;
63
64 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
65 import static java.time.temporal.ChronoField.ERA;
66 import static java.time.temporal.ChronoField.HOUR_OF_DAY;
67 import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
68 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
69 import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
70 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
71 import static java.time.temporal.ChronoField.YEAR;
72 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
73
74 import java.io.InvalidObjectException;
75 import java.io.ObjectInputStream;
76 import java.io.Serializable;
77 import java.time.Clock;
78 import java.time.DateTimeException;
79 import java.time.Instant;
80 import java.time.LocalDate;
81 import java.time.LocalDateTime;
82 import java.time.Month;
83 import java.time.Period;
84 import java.time.Year;
85 import java.time.ZonedDateTime;
86 import java.time.ZoneId;
87 import java.time.ZoneOffset;
88 import java.time.format.ResolverStyle;
89 import java.time.temporal.ChronoField;
90 import java.time.temporal.TemporalAccessor;
91 import java.time.temporal.TemporalField;
92 import java.time.temporal.ValueRange;
93 import java.util.Arrays;
94 import java.util.List;
95 import java.util.Locale;
96 import java.util.Map;
97 import java.util.Objects;
98
99 /**
100 * The ISO calendar system.
101 * <p>
102 * This chronology defines the rules of the ISO calendar system.
103 * This calendar system is based on the ISO-8601 standard, which is the
104 * <i>de facto</i> world calendar.
105 * <p>
106 * The fields are defined as follows:
107 * <ul>
119 * <li>leap-year - Leap years occur every 4 years, except where the year is divisble by 100 and not divisble by 400.
120 * </ul>
121 *
122 * @implSpec
123 * This class is immutable and thread-safe.
124 *
125 * @since 1.8
126 */
127 public final class IsoChronology extends AbstractChronology implements Serializable {
128
129 /**
130 * Singleton instance of the ISO chronology.
131 */
132 public static final IsoChronology INSTANCE = new IsoChronology();
133
134 /**
135 * Serialization version.
136 */
137 private static final long serialVersionUID = -1440403870442975015L;
138
139 private static final long DAYS_0000_TO_1970 = (146097 * 5L) - (30L * 365L + 7L); // taken from LocalDate
140
141 /**
142 * Restricted constructor.
143 */
144 private IsoChronology() {
145 }
146
147 //-----------------------------------------------------------------------
148 /**
149 * Gets the ID of the chronology - 'ISO'.
150 * <p>
151 * The ID uniquely identifies the {@code Chronology}.
152 * It can be used to lookup the {@code Chronology} using {@link Chronology#of(String)}.
153 *
154 * @return the chronology ID - 'ISO'
155 * @see #getCalendarType()
156 */
157 @Override
158 public String getId() {
159 return "ISO";
160 }
252 @Override // override with covariant return type
253 public LocalDate dateEpochDay(long epochDay) {
254 return LocalDate.ofEpochDay(epochDay);
255 }
256
257 //-----------------------------------------------------------------------
258 /**
259 * Obtains an ISO local date from another date-time object.
260 * <p>
261 * This is equivalent to {@link LocalDate#from(TemporalAccessor)}.
262 *
263 * @param temporal the date-time object to convert, not null
264 * @return the ISO local date, not null
265 * @throws DateTimeException if unable to create the date
266 */
267 @Override // override with covariant return type
268 public LocalDate date(TemporalAccessor temporal) {
269 return LocalDate.from(temporal);
270 }
271
272 //-----------------------------------------------------------------------
273 /**
274 * Gets the number of seconds from the epoch of 1970-01-01T00:00:00Z.
275 * <p>
276 * The number of seconds is calculated using the year,
277 * month, day-of-month, hour, minute, second, and zoneOffset.
278 *
279 * @param prolepticYear the year, from MIN_YEAR to MAX_YEAR
280 * @param month the month-of-year, from 1 to 12
281 * @param dayOfMonth the day-of-month, from 1 to 31
282 * @param hour the hour-of-day, from 0 to 23
283 * @param minute the minute-of-hour, from 0 to 59
284 * @param second the second-of-minute, from 0 to 59
285 * @param zoneOffset the zone offset, not null
286 * @return the number of seconds relative to 1970-01-01T00:00:00Z, may be negative
287 * @throws DateTimeException if the value of any field is out of range,
288 * or if the day-of-month is invalid for the month-of-year
289 * @since 9
290 */
291 @Override
292 public long epochSecond(int prolepticYear, int month, int dayOfMonth,
293 int hour, int minute, int second, ZoneOffset zoneOffset) {
294 YEAR.checkValidValue(prolepticYear);
295 MONTH_OF_YEAR.checkValidValue(month);
296 DAY_OF_MONTH.checkValidValue(dayOfMonth);
297 HOUR_OF_DAY.checkValidValue(hour);
298 MINUTE_OF_HOUR.checkValidValue(minute);
299 SECOND_OF_MINUTE.checkValidValue(second);
300 Objects.requireNonNull(zoneOffset, "zoneOffset");
301 if (dayOfMonth > 28) {
302 int dom = numberOfDaysOfMonth(prolepticYear, month);
303 if (dayOfMonth > dom) {
304 if (dayOfMonth == 29) {
305 throw new DateTimeException("Invalid date 'February 29' as '" + prolepticYear + "' is not a leap year");
306 } else {
307 throw new DateTimeException("Invalid date '" + Month.of(month).name() + " " + dayOfMonth + "'");
308 }
309 }
310 }
311
312 long totalDays = 0;
313 int timeinSec = 0;
314 totalDays += 365L * prolepticYear;
315 if (prolepticYear >= 0) {
316 totalDays += (prolepticYear + 3L) / 4 - (prolepticYear + 99L) / 100 + (prolepticYear + 399L) / 400;
317 } else {
318 totalDays -= prolepticYear / -4 - prolepticYear / -100 + prolepticYear / -400;
319 }
320 totalDays += (367 * month - 362) / 12;
321 totalDays += dayOfMonth - 1;
322 if (month > 2) {
323 totalDays--;
324 if (IsoChronology.INSTANCE.isLeapYear(prolepticYear) == false) {
325 totalDays--;
326 }
327 }
328 totalDays -= DAYS_0000_TO_1970;
329 timeinSec = (hour * 60 + minute ) * 60 + second;
330 return Math.addExact(Math.multiplyExact(totalDays, 86400L), timeinSec - zoneOffset.getTotalSeconds());
331 }
332
333 /**
334 * Gets the number of days for the given month in the given year.
335 *
336 * @param year the year to represent, from MIN_YEAR to MAX_YEAR
337 * @param month the month-of-year to represent, from 1 to 12
338 * @return the number of days for the given month in the given year
339 */
340 private int numberOfDaysOfMonth(int year, int month) {
341 int dom;
342 switch (month) {
343 case 2:
344 dom = (IsoChronology.INSTANCE.isLeapYear(year) ? 29 : 28);
345 break;
346 case 4:
347 case 6:
348 case 9:
349 case 11:
350 dom = 30;
351 break;
352 default:
353 dom = 31;
354 break;
355 }
356 return dom;
357 }
358
359
360 /**
361 * Obtains an ISO local date-time from another date-time object.
362 * <p>
363 * This is equivalent to {@link LocalDateTime#from(TemporalAccessor)}.
364 *
365 * @param temporal the date-time object to convert, not null
366 * @return the ISO local date-time, not null
367 * @throws DateTimeException if unable to create the date-time
368 */
369 @Override // override with covariant return type
370 public LocalDateTime localDateTime(TemporalAccessor temporal) {
371 return LocalDateTime.from(temporal);
372 }
373
374 /**
375 * Obtains an ISO zoned date-time from another date-time object.
376 * <p>
377 * This is equivalent to {@link ZonedDateTime#from(TemporalAccessor)}.
378 *
379 * @param temporal the date-time object to convert, not null
|