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  */
  57 package java.time.temporal;
  58 
  59 import 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  * <h3>Specification for implementors</h3>
  73  * This is a final, immutable and thread-safe enum.
  74  *
  75  * @since 1.8
  76  */
  77 public 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,00,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 the era is artificially defined as the largest duration
 188      * supported by {@code 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     @Override
 202     public String getName() {
 203         return name;
 204     }
 205 
 206     //-----------------------------------------------------------------------
 207     /**
 208      * Gets the estimated duration of this unit in the ISO calendar system.
 209      * <p>
 210      * All of the units in this class have an estimated duration.
 211      * Days vary due to daylight saving time, while months have different lengths.
 212      *
 213      * @return the estimated duration of this unit, not null
 214      */
 215     @Override
 216     public Duration getDuration() {
 217         return duration;
 218     }
 219 
 220     /**
 221      * Checks if the duration of the unit is an estimate.
 222      * <p>
 223      * All time units in this class are considered to be accurate, while all date
 224      * units in this class are considered to be estimated.
 225      * <p>
 226      * This definition ignores leap seconds, but considers that Days vary due to
 227      * daylight saving time and months have different lengths.
 228      *
 229      * @return true if the duration is estimated, false if accurate
 230      */
 231     @Override
 232     public boolean isDurationEstimated() {
 233         return isDateUnit();
 234     }
 235 
 236     //-----------------------------------------------------------------------
 237     /**
 238      * Checks if this unit is a date unit.
 239      *
 240      * @return true if a date unit, false if a time unit
 241      */
 242     public boolean isDateUnit() {
 243         return this.compareTo(DAYS) >= 0;
 244     }
 245 
 246     /**
 247      * Checks if this unit is a time unit.
 248      *
 249      * @return true if a time unit, false if a date unit
 250      */
 251     public boolean isTimeUnit() {
 252         return this.compareTo(DAYS) < 0;
 253     }
 254 
 255     //-----------------------------------------------------------------------
 256     @Override
 257     public boolean isSupported(Temporal temporal) {
 258         if (this == FOREVER) {
 259             return false;
 260         }
 261         if (temporal instanceof ChronoLocalDate) {
 262             return isDateUnit();
 263         }
 264         if (temporal instanceof ChronoLocalDateTime || temporal instanceof ChronoZonedDateTime) {
 265             return true;
 266         }
 267         return TemporalUnit.super.isSupported(temporal);
 268     }
 269 
 270     @SuppressWarnings("unchecked")
 271     @Override
 272     public <R extends Temporal> R doPlus(R dateTime, long periodToAdd) {
 273         return (R) dateTime.plus(periodToAdd, this);
 274     }
 275 
 276     //-----------------------------------------------------------------------
 277     @Override
 278     public <R extends Temporal> SimplePeriod between(R dateTime1, R dateTime2) {
 279         return new SimplePeriod(dateTime1.periodUntil(dateTime2, this), this);
 280     }
 281 
 282     //-----------------------------------------------------------------------
 283     @Override
 284     public String toString() {
 285         return getName();
 286     }
 287 
 288 }