1 /*
2  *  Copyright 2001-2013 Stephen Colebourne
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */

16 package org.joda.time.chrono;
17
18 import org.joda.time.DateTimeFieldType;
19 import org.joda.time.DurationField;
20 import org.joda.time.field.FieldUtils;
21 import org.joda.time.field.ImpreciseDateTimeField;
22
23 /**
24  * A year field suitable for many calendars.
25  *
26  * @author Guy Allard
27  * @author Stephen Colebourne
28  * @author Brian S O'Neill
29  * @since 1.1, refactored from GJYearDateTimeField
30  */

31 class BasicYearDateTimeField extends ImpreciseDateTimeField {
32
33     /** Serialization version. */
34     @SuppressWarnings("unused")
35     private static final long serialVersionUID = -98628754872287L;
36
37     /** The underlying basic chronology. */
38     protected final BasicChronology iChronology;
39
40     /**
41      * Restricted constructor.
42      * 
43      * @param chronology  the chronology this field belogs to
44      */

45     BasicYearDateTimeField(BasicChronology chronology) {
46         super(DateTimeFieldType.year(), chronology.getAverageMillisPerYear());
47         iChronology = chronology;
48     }
49
50     public boolean isLenient() {
51         return false;
52     }
53
54     public int get(long instant) {
55         return iChronology.getYear(instant);
56     }
57
58     public long add(long instant, int years) {
59         if (years == 0) {
60             return instant;
61         }
62         int thisYear = get(instant);
63         int newYear = FieldUtils.safeAdd(thisYear, years);
64         return set(instant, newYear);
65     }
66
67     public long add(long instant, long years) {
68         return add(instant, FieldUtils.safeToInt(years));
69     }
70
71     public long addWrapField(long instant, int years) {
72         if (years == 0) {
73             return instant;
74         }
75         // Return newly calculated millis value
76         int thisYear = iChronology.getYear(instant);
77         int wrappedYear = FieldUtils.getWrappedValue
78             (thisYear, years, iChronology.getMinYear(), iChronology.getMaxYear());
79         return set(instant, wrappedYear);
80     }
81
82     public long set(long instant, int year) {
83         FieldUtils.verifyValueBounds
84             (this, year, iChronology.getMinYear(), iChronology.getMaxYear());
85         return iChronology.setYear(instant, year);
86     }
87
88     public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) {
89         if (minuendInstant < subtrahendInstant) {
90             return -iChronology.getYearDifference(subtrahendInstant, minuendInstant);
91         }
92         return iChronology.getYearDifference(minuendInstant, subtrahendInstant);
93     }
94
95     public DurationField getRangeDurationField() {
96         return null;
97     }
98
99     public boolean isLeap(long instant) {
100         return iChronology.isLeapYear(get(instant));
101     }
102
103     public int getLeapAmount(long instant) {
104         if (iChronology.isLeapYear(get(instant))) {
105             return 1;
106         } else {
107             return 0;
108         }
109     }
110
111     public DurationField getLeapDurationField() {
112         return iChronology.days();
113     }
114
115     public int getMinimumValue() {
116         return iChronology.getMinYear();
117     }
118
119     public int getMaximumValue() {
120         return iChronology.getMaxYear();
121     }
122
123     public long roundFloor(long instant) {
124         return iChronology.getYearMillis(get(instant));
125     }
126
127     public long roundCeiling(long instant) {
128         int year = get(instant);
129         long yearStartMillis = iChronology.getYearMillis(year);
130         if (instant != yearStartMillis) {
131             // Bump up to start of next year.
132             instant = iChronology.getYearMillis(year + 1);
133         }
134         return instant;
135     }
136
137     public long remainder(long instant) {
138         return instant - roundFloor(instant);
139     }
140
141     /**
142      * Serialization singleton
143      */

144     private Object readResolve() {
145         return iChronology.year();
146     }
147 }
148