1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.joda.time.chrono;
17
18 import java.util.HashMap;
19 import java.util.Map;
20
21 import org.joda.time.Chronology;
22 import org.joda.time.DateTime;
23 import org.joda.time.DateTimeConstants;
24 import org.joda.time.DateTimeField;
25 import org.joda.time.DateTimeZone;
26 import org.joda.time.field.SkipDateTimeField;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public final class EthiopicChronology extends BasicFixedMonthChronology {
52
53
54 private static final long serialVersionUID = -5972804258688333942L;
55
56
57
58
59
60 public static final int EE = DateTimeConstants.CE;
61
62
63 private static final DateTimeField ERA_FIELD = new BasicSingleEraDateTimeField("EE");
64
65
66 private static final int MIN_YEAR = -292269337;
67
68
69 private static final int MAX_YEAR = 292272984;
70
71
72 private static final Map<DateTimeZone, EthiopicChronology[]> cCache = new HashMap<DateTimeZone, EthiopicChronology[]>();
73
74
75 private static final EthiopicChronology INSTANCE_UTC;
76 static {
77
78 INSTANCE_UTC = getInstance(DateTimeZone.UTC);
79 }
80
81
82
83
84
85
86
87
88 public static EthiopicChronology getInstanceUTC() {
89 return INSTANCE_UTC;
90 }
91
92
93
94
95
96
97 public static EthiopicChronology getInstance() {
98 return getInstance(DateTimeZone.getDefault(), 4);
99 }
100
101
102
103
104
105
106
107 public static EthiopicChronology getInstance(DateTimeZone zone) {
108 return getInstance(zone, 4);
109 }
110
111
112
113
114
115
116
117
118 public static EthiopicChronology getInstance(DateTimeZone zone, int minDaysInFirstWeek) {
119 if (zone == null) {
120 zone = DateTimeZone.getDefault();
121 }
122 EthiopicChronology chrono;
123 synchronized (cCache) {
124 EthiopicChronology[] chronos = cCache.get(zone);
125 if (chronos == null) {
126 chronos = new EthiopicChronology[7];
127 cCache.put(zone, chronos);
128 }
129 try {
130 chrono = chronos[minDaysInFirstWeek - 1];
131 } catch (ArrayIndexOutOfBoundsException e) {
132 throw new IllegalArgumentException
133 ("Invalid min days in first week: " + minDaysInFirstWeek);
134 }
135 if (chrono == null) {
136 if (zone == DateTimeZone.UTC) {
137
138 chrono = new EthiopicChronology(null, null, minDaysInFirstWeek);
139
140 DateTime lowerLimit = new DateTime(1, 1, 1, 0, 0, 0, 0, chrono);
141 chrono = new EthiopicChronology
142 (LimitChronology.getInstance(chrono, lowerLimit, null),
143 null, minDaysInFirstWeek);
144 } else {
145 chrono = getInstance(DateTimeZone.UTC, minDaysInFirstWeek);
146 chrono = new EthiopicChronology
147 (ZonedChronology.getInstance(chrono, zone), null, minDaysInFirstWeek);
148 }
149 chronos[minDaysInFirstWeek - 1] = chrono;
150 }
151 }
152 return chrono;
153 }
154
155
156
157
158
159
160 EthiopicChronology(Chronology base, Object param, int minDaysInFirstWeek) {
161 super(base, param, minDaysInFirstWeek);
162 }
163
164
165
166
167 private Object readResolve() {
168 Chronology base = getBase();
169 return base == null ?
170 getInstance(DateTimeZone.UTC, getMinimumDaysInFirstWeek()) :
171 getInstance(base.getZone(), getMinimumDaysInFirstWeek());
172 }
173
174
175
176
177
178
179
180
181 public Chronology withUTC() {
182 return INSTANCE_UTC;
183 }
184
185
186
187
188
189
190
191 public Chronology withZone(DateTimeZone zone) {
192 if (zone == null) {
193 zone = DateTimeZone.getDefault();
194 }
195 if (zone == getZone()) {
196 return this;
197 }
198 return getInstance(zone);
199 }
200
201
202 long calculateFirstDayOfYearMillis(int year) {
203
204
205
206
207 int relativeYear = year - 1963;
208 int leapYears;
209 if (relativeYear <= 0) {
210
211
212 leapYears = (relativeYear + 3) >> 2;
213 } else {
214 leapYears = relativeYear >> 2;
215
216 if (!isLeapYear(year)) {
217 leapYears++;
218 }
219 }
220
221 long millis = (relativeYear * 365L + leapYears)
222 * (long)DateTimeConstants.MILLIS_PER_DAY;
223
224
225
226 return millis + (365L - 112) * DateTimeConstants.MILLIS_PER_DAY;
227 }
228
229
230 int getMinYear() {
231 return MIN_YEAR;
232 }
233
234
235 int getMaxYear() {
236 return MAX_YEAR;
237 }
238
239
240 long getApproxMillisAtEpochDividedByTwo() {
241 return (1962L * MILLIS_PER_YEAR + 112L * DateTimeConstants.MILLIS_PER_DAY) / 2;
242 }
243
244
245 protected void assemble(Fields fields) {
246 if (getBase() == null) {
247 super.assemble(fields);
248
249
250 fields.year = new SkipDateTimeField(this, fields.year);
251 fields.weekyear = new SkipDateTimeField(this, fields.weekyear);
252
253 fields.era = ERA_FIELD;
254 fields.monthOfYear = new BasicMonthOfYearDateTimeField(this, 13);
255 fields.months = fields.monthOfYear.getDurationField();
256 }
257 }
258
259 }