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 import java.time.chrono.ChronoLocalDate;
  61 import java.time.chrono.ChronoLocalDateTime;
  62 import java.time.chrono.ChronoZonedDateTime;
  63 
  64 /**
  65  * A standard set of date periods units.
  66  * <p>
  67  * This set of units provide unit-based access to manipulate a date, time or date-time.
  68  * The standard set of units can be extended by implementing {@link TemporalUnit}.
  69  * <p>
  70  * These units are intended to be applicable in multiple calendar systems.
  71  * For example, most non-ISO calendar systems define units of years, months and days,
  72  * just with slightly different rules.
  73  * The documentation of each unit explains how it operates.
  74  *
  75  * <h3>Specification for implementors</h3>
  76  * This is a final, immutable and thread-safe enum.
  77  *
  78  * @since 1.8
  79  */
  80 public enum ChronoUnit implements TemporalUnit {
  81 
  82     /**
  83      * Unit that represents the concept of a nanosecond, the smallest supported unit of time.
  84      * For the ISO calendar system, it is equal to the 1,000,000,000th part of the second unit.
  85      */
  86     NANOS("Nanos", Duration.ofNanos(1)),
  87     /**
  88      * Unit that represents the concept of a microsecond.
  89      * For the ISO calendar system, it is equal to the 1,000,000th part of the second unit.
  90      */
  91     MICROS("Micros", Duration.ofNanos(1000)),
  92     /**
  93      * Unit that represents the concept of a millisecond.
  94      * For the ISO calendar system, it is equal to the 1000th part of the second unit.
  95      */
  96     MILLIS("Millis", Duration.ofNanos(1000_000)),
  97     /**
  98      * Unit that represents the concept of a second.
  99      * For the ISO calendar system, it is equal to the second in the SI system
 100      * of units, except around a leap-second.
 101      */
 102     SECONDS("Seconds", Duration.ofSeconds(1)),
 103     /**
 104      * Unit that represents the concept of a minute.
 105      * For the ISO calendar system, it is equal to 60 seconds.
 106      */
 107     MINUTES("Minutes", Duration.ofSeconds(60)),
 108     /**
 109      * Unit that represents the concept of an hour.
 110      * For the ISO calendar system, it is equal to 60 minutes.
 111      */
 112     HOURS("Hours", Duration.ofSeconds(3600)),
 113     /**
 114      * Unit that represents the concept of half a day, as used in AM/PM.
 115      * For the ISO calendar system, it is equal to 12 hours.
 116      */
 117     HALF_DAYS("HalfDays", Duration.ofSeconds(43200)),
 118     /**
 119      * Unit that represents the concept of a day.
 120      * For the ISO calendar system, it is the standard day from midnight to midnight.
 121      * The estimated duration of a day is {@code 24 Hours}.
 122      * <p>
 123      * When used with other calendar systems it must correspond to the day defined by
 124      * the rising and setting of the Sun on Earth. It is not required that days begin
 125      * at midnight - when converting between calendar systems, the date should be
 126      * equivalent at midday.
 127      */
 128     DAYS("Days", Duration.ofSeconds(86400)),
 129     /**
 130      * Unit that represents the concept of a week.
 131      * For the ISO calendar system, it is equal to 7 days.
 132      * <p>
 133      * When used with other calendar systems it must correspond to an integral number of days.
 134      */
 135     WEEKS("Weeks", Duration.ofSeconds(7 * 86400L)),
 136     /**
 137      * Unit that represents the concept of a month.
 138      * For the ISO calendar system, the length of the month varies by month-of-year.
 139      * The estimated duration of a month is one twelfth of {@code 365.2425 Days}.
 140      * <p>
 141      * When used with other calendar systems it must correspond to an integral number of days.
 142      */
 143     MONTHS("Months", Duration.ofSeconds(31556952L / 12)),
 144     /**
 145      * Unit that represents the concept of a year.
 146      * For the ISO calendar system, it is equal to 12 months.
 147      * The estimated duration of a year is {@code 365.2425 Days}.
 148      * <p>
 149      * When used with other calendar systems it must correspond to an integral number of days
 150      * or months roughly equal to a year defined by the passage of the Earth around the Sun.
 151      */
 152     YEARS("Years", Duration.ofSeconds(31556952L)),
 153     /**
 154      * Unit that represents the concept of a decade.
 155      * For the ISO calendar system, it is equal to 10 years.
 156      * <p>
 157      * When used with other calendar systems it must correspond to an integral number of days
 158      * and is normally an integral number of years.
 159      */
 160     DECADES("Decades", Duration.ofSeconds(31556952L * 10L)),
 161     /**
 162      * Unit that represents the concept of a century.
 163      * For the ISO calendar system, it is equal to 100 years.
 164      * <p>
 165      * When used with other calendar systems it must correspond to an integral number of days
 166      * and is normally an integral number of years.
 167      */
 168     CENTURIES("Centuries", Duration.ofSeconds(31556952L * 100L)),
 169     /**
 170      * Unit that represents the concept of a millennium.
 171      * For the ISO calendar system, it is equal to 1000 years.
 172      * <p>
 173      * When used with other calendar systems it must correspond to an integral number of days
 174      * and is normally an integral number of years.
 175      */
 176     MILLENNIA("Millennia", Duration.ofSeconds(31556952L * 1000L)),
 177     /**
 178      * Unit that represents the concept of an era.
 179      * The ISO calendar system doesn't have eras thus it is impossible to add
 180      * an era to a date or date-time.
 181      * The estimated duration of the era is artificially defined as {@code 1,000,00,000 Years}.
 182      * <p>
 183      * When used with other calendar systems there are no restrictions on the unit.
 184      */
 185     ERAS("Eras", Duration.ofSeconds(31556952L * 1000_000_000L)),
 186     /**
 187      * Artificial unit that represents the concept of forever.
 188      * This is primarily used with {@link TemporalField} to represent unbounded fields
 189      * such as the year or era.
 190      * The estimated duration of the era is artificially defined as the largest duration
 191      * supported by {@code Duration}.
 192      */
 193     FOREVER("Forever", Duration.ofSeconds(Long.MAX_VALUE, 999_999_999));
 194 
 195     private final String name;
 196     private final Duration duration;
 197 
 198     private ChronoUnit(String name, Duration estimatedDuration) {
 199         this.name = name;
 200         this.duration = estimatedDuration;
 201     }
 202 
 203     //-----------------------------------------------------------------------
 204     @Override
 205     public String getName() {
 206         return name;
 207     }
 208 
 209     //-----------------------------------------------------------------------
 210     /**
 211      * Gets the estimated duration of this unit in the ISO calendar system.
 212      * <p>
 213      * All of the units in this class have an estimated duration.
 214      * Days vary due to daylight saving time, while months have different lengths.
 215      *
 216      * @return the estimated duration of this unit, not null
 217      */
 218     @Override
 219     public Duration getDuration() {
 220         return duration;
 221     }
 222 
 223     /**
 224      * Checks if the duration of the unit is an estimate.
 225      * <p>
 226      * All time units in this class are considered to be accurate, while all date
 227      * units in this class are considered to be estimated.
 228      * <p>
 229      * This definition ignores leap seconds, but considers that Days vary due to
 230      * daylight saving time and months have different lengths.
 231      *
 232      * @return true if the duration is estimated, false if accurate
 233      */
 234     @Override
 235     public boolean isDurationEstimated() {
 236         return isDateUnit();
 237     }
 238 
 239     //-----------------------------------------------------------------------
 240     /**
 241      * Checks if this unit is a date unit.
 242      *
 243      * @return true if a date unit, false if a time unit
 244      */
 245     public boolean isDateUnit() {
 246         return this.compareTo(DAYS) >= 0;
 247     }
 248 
 249     /**
 250      * Checks if this unit is a time unit.
 251      *
 252      * @return true if a time unit, false if a date unit
 253      */
 254     public boolean isTimeUnit() {
 255         return this.compareTo(DAYS) < 0;
 256     }
 257 
 258     //-----------------------------------------------------------------------
 259     @Override
 260     public boolean isSupportedBy(Temporal temporal) {
 261         if (this == FOREVER) {
 262             return false;
 263         }
 264         if (temporal instanceof ChronoLocalDate) {
 265             return isDateUnit();
 266         }
 267         if (temporal instanceof ChronoLocalDateTime || temporal instanceof ChronoZonedDateTime) {
 268             return true;
 269         }
 270         return TemporalUnit.super.isSupportedBy(temporal);
 271     }
 272 
 273     @SuppressWarnings("unchecked")
 274     @Override
 275     public <R extends Temporal> R addTo(R temporal, long amount) {
 276         return (R) temporal.plus(amount, this);
 277     }
 278 
 279     //-----------------------------------------------------------------------
 280     @Override
 281     public long between(Temporal temporal1, Temporal temporal2) {
 282         return temporal1.periodUntil(temporal2, this);
 283     }
 284 
 285     //-----------------------------------------------------------------------
 286     @Override
 287     public String toString() {
 288         return getName();
 289     }
 290 
 291 }