• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *  * Redistributions of source code must retain the above copyright notice,
10  *    this list of conditions and the following disclaimer.
11  *
12  *  * Redistributions in binary form must reproduce the above copyright notice,
13  *    this list of conditions and the following disclaimer in the documentation
14  *    and/or other materials provided with the distribution.
15  *
16  *  * Neither the name of JSR-310 nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 package org.threeten.bp.chrono;
33 
34 import static org.threeten.bp.temporal.ChronoUnit.DAYS;
35 import static org.threeten.bp.temporal.ChronoUnit.MONTHS;
36 import static org.threeten.bp.temporal.ChronoUnit.YEARS;
37 
38 import java.io.Serializable;
39 import java.util.Arrays;
40 import java.util.Collections;
41 import java.util.List;
42 
43 import org.threeten.bp.DateTimeException;
44 import org.threeten.bp.jdk8.Jdk8Methods;
45 import org.threeten.bp.temporal.ChronoField;
46 import org.threeten.bp.temporal.Temporal;
47 import org.threeten.bp.temporal.TemporalAmount;
48 import org.threeten.bp.temporal.TemporalQueries;
49 import org.threeten.bp.temporal.TemporalUnit;
50 import org.threeten.bp.temporal.UnsupportedTemporalTypeException;
51 
52 /**
53  * An implementation of {@code ChronoPeriod}.
54  */
55 final class ChronoPeriodImpl
56         extends ChronoPeriod
57         implements Serializable {
58 
59     /**
60      * Serialization version.
61      */
62     private static final long serialVersionUID = 275618735781L;
63 
64     private final Chronology chronology;
65     private final int years;
66     private final int months;
67     private final int days;
68 
ChronoPeriodImpl(Chronology chronology, int years, int months, int days)69     public ChronoPeriodImpl(Chronology chronology, int years, int months, int days) {
70         this.chronology = chronology;
71         this.years = years;
72         this.months = months;
73         this.days = days;
74     }
75 
76     //-------------------------------------------------------------------------
77     @Override
get(TemporalUnit unit)78     public long get(TemporalUnit unit) {
79         if (unit == YEARS) {
80             return years;
81         }
82         if (unit == MONTHS) {
83             return months;
84         }
85         if (unit == DAYS) {
86             return days;
87         }
88         throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
89     }
90 
91     @Override
getUnits()92     public List<TemporalUnit> getUnits() {
93         return Collections.unmodifiableList(Arrays.<TemporalUnit>asList(YEARS, MONTHS, DAYS));
94     }
95 
96     @Override
getChronology()97     public Chronology getChronology() {
98         return chronology;
99     }
100 
101     //-------------------------------------------------------------------------
102     @Override
plus(TemporalAmount amountToAdd)103     public ChronoPeriod plus(TemporalAmount amountToAdd) {
104         if (amountToAdd instanceof ChronoPeriodImpl) {
105             ChronoPeriodImpl amount = (ChronoPeriodImpl) amountToAdd;
106             if (amount.getChronology().equals(getChronology())) {
107                 return new ChronoPeriodImpl(
108                         chronology,
109                         Jdk8Methods.safeAdd(years, amount.years),
110                         Jdk8Methods.safeAdd(months, amount.months),
111                         Jdk8Methods.safeAdd(days, amount.days));
112             }
113         }
114         throw new DateTimeException("Unable to add amount: " + amountToAdd);
115     }
116 
117     @Override
minus(TemporalAmount amountToSubtract)118     public ChronoPeriod minus(TemporalAmount amountToSubtract) {
119         if (amountToSubtract instanceof ChronoPeriodImpl) {
120             ChronoPeriodImpl amount = (ChronoPeriodImpl) amountToSubtract;
121             if (amount.getChronology().equals(getChronology())) {
122                 return new ChronoPeriodImpl(
123                         chronology,
124                         Jdk8Methods.safeSubtract(years, amount.years),
125                         Jdk8Methods.safeSubtract(months, amount.months),
126                         Jdk8Methods.safeSubtract(days, amount.days));
127             }
128         }
129         throw new DateTimeException("Unable to subtract amount: " + amountToSubtract);
130     }
131 
132     @Override
multipliedBy(int scalar)133     public ChronoPeriod multipliedBy(int scalar) {
134         return new ChronoPeriodImpl(
135                 chronology,
136                 Jdk8Methods.safeMultiply(years, scalar),
137                 Jdk8Methods.safeMultiply(months, scalar),
138                 Jdk8Methods.safeMultiply(days, scalar));
139     }
140 
141     @Override
normalized()142     public ChronoPeriod normalized() {
143         if (chronology.range(ChronoField.MONTH_OF_YEAR).isFixed()) {
144             long monthLength = chronology.range(ChronoField.MONTH_OF_YEAR).getMaximum() - chronology.range(ChronoField.MONTH_OF_YEAR).getMinimum() + 1;
145             long total = years * monthLength + months;
146             int years = Jdk8Methods.safeToInt(total / monthLength);
147             int months = Jdk8Methods.safeToInt(total % monthLength);
148             return new ChronoPeriodImpl(chronology, years, months, days);
149         }
150         return this;
151     }
152 
153     @Override
addTo(Temporal temporal)154     public Temporal addTo(Temporal temporal) {
155         Jdk8Methods.requireNonNull(temporal, "temporal");
156         Chronology temporalChrono = temporal.query(TemporalQueries.chronology());
157         if (temporalChrono != null && chronology.equals(temporalChrono) == false) {
158             throw new DateTimeException("Invalid chronology, required: " + chronology.getId() + ", but was: " + temporalChrono.getId());
159         }
160         if (years != 0) {
161             temporal = temporal.plus(years, YEARS);
162         }
163         if (months != 0) {
164             temporal = temporal.plus(months, MONTHS);
165         }
166         if (days != 0) {
167             temporal = temporal.plus(days, DAYS);
168         }
169         return temporal;
170     }
171 
172     @Override
subtractFrom(Temporal temporal)173     public Temporal subtractFrom(Temporal temporal) {
174         Jdk8Methods.requireNonNull(temporal, "temporal");
175         Chronology temporalChrono = temporal.query(TemporalQueries.chronology());
176         if (temporalChrono != null && chronology.equals(temporalChrono) == false) {
177             throw new DateTimeException("Invalid chronology, required: " + chronology.getId() + ", but was: " + temporalChrono.getId());
178         }
179         if (years != 0) {
180             temporal = temporal.minus(years, YEARS);
181         }
182         if (months != 0) {
183             temporal = temporal.minus(months, MONTHS);
184         }
185         if (days != 0) {
186             temporal = temporal.minus(days, DAYS);
187         }
188         return temporal;
189     }
190 
191     //-------------------------------------------------------------------------
192     @Override
equals(Object obj)193     public boolean equals(Object obj) {
194         if (this == obj) {
195             return true;
196         }
197         if (obj instanceof ChronoPeriodImpl) {
198             ChronoPeriodImpl other = (ChronoPeriodImpl) obj;
199             return years == other.years && months == other.months &&
200                     days == other.days && chronology.equals(other.chronology);
201         }
202         return false;
203     }
204 
205     @Override
hashCode()206     public int hashCode() {
207         return chronology.hashCode() + Integer.rotateLeft(years, 16) + Integer.rotateLeft(months, 8) + days;
208     }
209 
210     @Override
toString()211     public String toString() {
212         if (isZero()) {
213             return chronology + " P0D";
214         } else {
215             StringBuilder buf = new StringBuilder();
216             buf.append(chronology).append(' ').append('P');
217             if (years != 0) {
218                 buf.append(years).append('Y');
219             }
220             if (months != 0) {
221                 buf.append(months).append('M');
222             }
223             if (days != 0) {
224                 buf.append(days).append('D');
225             }
226             return buf.toString();
227         }
228     }
229 
230 }
231