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
23 * questions.
24 */
25
26/*
27 * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos
28 *
29 * All rights reserved.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions are met:
33 *
34 *  * Redistributions of source code must retain the above copyright notice,
35 *    this list of conditions and the following disclaimer.
36 *
37 *  * Redistributions in binary form must reproduce the above copyright notice,
38 *    this list of conditions and the following disclaimer in the documentation
39 *    and/or other materials provided with the distribution.
40 *
41 *  * Neither the name of JSR-310 nor the names of its contributors
42 *    may be used to endorse or promote products derived from this software
43 *    without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
47 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
48 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
49 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
50 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
52 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
53 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
54 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
55 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 */
57package java.time.temporal;
58
59import java.time.Duration;
60
61/**
62 * A standard set of date periods units.
63 * <p>
64 * This set of units provide unit-based access to manipulate a date, time or date-time.
65 * The standard set of units can be extended by implementing {@link TemporalUnit}.
66 * <p>
67 * These units are intended to be applicable in multiple calendar systems.
68 * For example, most non-ISO calendar systems define units of years, months and days,
69 * just with slightly different rules.
70 * The documentation of each unit explains how it operates.
71 *
72 * @implSpec
73 * This is a final, immutable and thread-safe enum.
74 *
75 * @since 1.8
76 */
77public enum ChronoUnit implements TemporalUnit {
78
79    /**
80     * Unit that represents the concept of a nanosecond, the smallest supported unit of time.
81     * For the ISO calendar system, it is equal to the 1,000,000,000th part of the second unit.
82     */
83    NANOS("Nanos", Duration.ofNanos(1)),
84    /**
85     * Unit that represents the concept of a microsecond.
86     * For the ISO calendar system, it is equal to the 1,000,000th part of the second unit.
87     */
88    MICROS("Micros", Duration.ofNanos(1000)),
89    /**
90     * Unit that represents the concept of a millisecond.
91     * For the ISO calendar system, it is equal to the 1000th part of the second unit.
92     */
93    MILLIS("Millis", Duration.ofNanos(1000_000)),
94    /**
95     * Unit that represents the concept of a second.
96     * For the ISO calendar system, it is equal to the second in the SI system
97     * of units, except around a leap-second.
98     */
99    SECONDS("Seconds", Duration.ofSeconds(1)),
100    /**
101     * Unit that represents the concept of a minute.
102     * For the ISO calendar system, it is equal to 60 seconds.
103     */
104    MINUTES("Minutes", Duration.ofSeconds(60)),
105    /**
106     * Unit that represents the concept of an hour.
107     * For the ISO calendar system, it is equal to 60 minutes.
108     */
109    HOURS("Hours", Duration.ofSeconds(3600)),
110    /**
111     * Unit that represents the concept of half a day, as used in AM/PM.
112     * For the ISO calendar system, it is equal to 12 hours.
113     */
114    HALF_DAYS("HalfDays", Duration.ofSeconds(43200)),
115    /**
116     * Unit that represents the concept of a day.
117     * For the ISO calendar system, it is the standard day from midnight to midnight.
118     * The estimated duration of a day is {@code 24 Hours}.
119     * <p>
120     * When used with other calendar systems it must correspond to the day defined by
121     * the rising and setting of the Sun on Earth. It is not required that days begin
122     * at midnight - when converting between calendar systems, the date should be
123     * equivalent at midday.
124     */
125    DAYS("Days", Duration.ofSeconds(86400)),
126    /**
127     * Unit that represents the concept of a week.
128     * For the ISO calendar system, it is equal to 7 days.
129     * <p>
130     * When used with other calendar systems it must correspond to an integral number of days.
131     */
132    WEEKS("Weeks", Duration.ofSeconds(7 * 86400L)),
133    /**
134     * Unit that represents the concept of a month.
135     * For the ISO calendar system, the length of the month varies by month-of-year.
136     * The estimated duration of a month is one twelfth of {@code 365.2425 Days}.
137     * <p>
138     * When used with other calendar systems it must correspond to an integral number of days.
139     */
140    MONTHS("Months", Duration.ofSeconds(31556952L / 12)),
141    /**
142     * Unit that represents the concept of a year.
143     * For the ISO calendar system, it is equal to 12 months.
144     * The estimated duration of a year is {@code 365.2425 Days}.
145     * <p>
146     * When used with other calendar systems it must correspond to an integral number of days
147     * or months roughly equal to a year defined by the passage of the Earth around the Sun.
148     */
149    YEARS("Years", Duration.ofSeconds(31556952L)),
150    /**
151     * Unit that represents the concept of a decade.
152     * For the ISO calendar system, it is equal to 10 years.
153     * <p>
154     * When used with other calendar systems it must correspond to an integral number of days
155     * and is normally an integral number of years.
156     */
157    DECADES("Decades", Duration.ofSeconds(31556952L * 10L)),
158    /**
159     * Unit that represents the concept of a century.
160     * For the ISO calendar system, it is equal to 100 years.
161     * <p>
162     * When used with other calendar systems it must correspond to an integral number of days
163     * and is normally an integral number of years.
164     */
165    CENTURIES("Centuries", Duration.ofSeconds(31556952L * 100L)),
166    /**
167     * Unit that represents the concept of a millennium.
168     * For the ISO calendar system, it is equal to 1000 years.
169     * <p>
170     * When used with other calendar systems it must correspond to an integral number of days
171     * and is normally an integral number of years.
172     */
173    MILLENNIA("Millennia", Duration.ofSeconds(31556952L * 1000L)),
174    /**
175     * Unit that represents the concept of an era.
176     * The ISO calendar system doesn't have eras thus it is impossible to add
177     * an era to a date or date-time.
178     * The estimated duration of the era is artificially defined as {@code 1,000,000,000 Years}.
179     * <p>
180     * When used with other calendar systems there are no restrictions on the unit.
181     */
182    ERAS("Eras", Duration.ofSeconds(31556952L * 1000_000_000L)),
183    /**
184     * Artificial unit that represents the concept of forever.
185     * This is primarily used with {@link TemporalField} to represent unbounded fields
186     * such as the year or era.
187     * The estimated duration of this unit is artificially defined as the largest duration
188     * supported by {@link Duration}.
189     */
190    FOREVER("Forever", Duration.ofSeconds(Long.MAX_VALUE, 999_999_999));
191
192    private final String name;
193    private final Duration duration;
194
195    private ChronoUnit(String name, Duration estimatedDuration) {
196        this.name = name;
197        this.duration = estimatedDuration;
198    }
199
200    //-----------------------------------------------------------------------
201    /**
202     * Gets the estimated duration of this unit in the ISO calendar system.
203     * <p>
204     * All of the units in this class have an estimated duration.
205     * Days vary due to daylight saving time, while months have different lengths.
206     *
207     * @return the estimated duration of this unit, not null
208     */
209    @Override
210    public Duration getDuration() {
211        return duration;
212    }
213
214    /**
215     * Checks if the duration of the unit is an estimate.
216     * <p>
217     * All time units in this class are considered to be accurate, while all date
218     * units in this class are considered to be estimated.
219     * <p>
220     * This definition ignores leap seconds, but considers that Days vary due to
221     * daylight saving time and months have different lengths.
222     *
223     * @return true if the duration is estimated, false if accurate
224     */
225    @Override
226    public boolean isDurationEstimated() {
227        return this.compareTo(DAYS) >= 0;
228    }
229
230    //-----------------------------------------------------------------------
231    /**
232     * Checks if this unit is a date unit.
233     * <p>
234     * All units from days to eras inclusive are date-based.
235     * Time-based units and {@code FOREVER} return false.
236     *
237     * @return true if a date unit, false if a time unit
238     */
239    @Override
240    public boolean isDateBased() {
241        return this.compareTo(DAYS) >= 0 && this != FOREVER;
242    }
243
244    /**
245     * Checks if this unit is a time unit.
246     * <p>
247     * All units from nanos to half-days inclusive are time-based.
248     * Date-based units and {@code FOREVER} return false.
249     *
250     * @return true if a time unit, false if a date unit
251     */
252    @Override
253    public boolean isTimeBased() {
254        return this.compareTo(DAYS) < 0;
255    }
256
257    //-----------------------------------------------------------------------
258    @Override
259    public boolean isSupportedBy(Temporal temporal) {
260        return temporal.isSupported(this);
261    }
262
263    @SuppressWarnings("unchecked")
264    @Override
265    public <R extends Temporal> R addTo(R temporal, long amount) {
266        return (R) temporal.plus(amount, this);
267    }
268
269    //-----------------------------------------------------------------------
270    @Override
271    public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive) {
272        return temporal1Inclusive.until(temporal2Exclusive, this);
273    }
274
275    //-----------------------------------------------------------------------
276    @Override
277    public String toString() {
278        return name;
279    }
280
281}
282