KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > joda > time > chrono > BasicChronology


1 /*
2  * Copyright 2001-2005 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 java.util.Locale JavaDoc;
19
20 import org.joda.time.Chronology;
21 import org.joda.time.DateTimeConstants;
22 import org.joda.time.DateTimeField;
23 import org.joda.time.DateTimeFieldType;
24 import org.joda.time.DateTimeZone;
25 import org.joda.time.DurationField;
26 import org.joda.time.DurationFieldType;
27 import org.joda.time.field.DividedDateTimeField;
28 import org.joda.time.field.FieldUtils;
29 import org.joda.time.field.MillisDurationField;
30 import org.joda.time.field.ZeroIsMaxDateTimeField;
31 import org.joda.time.field.OffsetDateTimeField;
32 import org.joda.time.field.PreciseDateTimeField;
33 import org.joda.time.field.PreciseDurationField;
34 import org.joda.time.field.RemainderDateTimeField;
35
36 /**
37  * Abstract implementation for calendar systems that use a typical
38  * day/month/year/leapYear model.
39  * Most of the utility methods required by subclasses are package-private,
40  * reflecting the intention that they be defined in the same package.
41  * <p>
42  * BasicChronology is thread-safe and immutable, and all subclasses must
43  * be as well.
44  *
45  * @author Stephen Colebourne
46  * @author Brian S O'Neill
47  * @author Guy Allard
48  * @since 1.2, renamed from BaseGJChronology
49  */

50 abstract class BasicChronology extends AssembledChronology {
51
52     /** Serialization lock */
53     private static final long serialVersionUID = 8283225332206808863L;
54
55     private static final DurationField cMillisField;
56     private static final DurationField cSecondsField;
57     private static final DurationField cMinutesField;
58     private static final DurationField cHoursField;
59     private static final DurationField cHalfdaysField;
60     private static final DurationField cDaysField;
61     private static final DurationField cWeeksField;
62
63     private static final DateTimeField cMillisOfSecondField;
64     private static final DateTimeField cMillisOfDayField;
65     private static final DateTimeField cSecondOfMinuteField;
66     private static final DateTimeField cSecondOfDayField;
67     private static final DateTimeField cMinuteOfHourField;
68     private static final DateTimeField cMinuteOfDayField;
69     private static final DateTimeField cHourOfDayField;
70     private static final DateTimeField cHourOfHalfdayField;
71     private static final DateTimeField cClockhourOfDayField;
72     private static final DateTimeField cClockhourOfHalfdayField;
73     private static final DateTimeField cHalfdayOfDayField;
74
75     static {
76         cMillisField = MillisDurationField.INSTANCE;
77         cSecondsField = new PreciseDurationField
78             (DurationFieldType.seconds(), DateTimeConstants.MILLIS_PER_SECOND);
79         cMinutesField = new PreciseDurationField
80             (DurationFieldType.minutes(), DateTimeConstants.MILLIS_PER_MINUTE);
81         cHoursField = new PreciseDurationField
82             (DurationFieldType.hours(), DateTimeConstants.MILLIS_PER_HOUR);
83         cHalfdaysField = new PreciseDurationField
84             (DurationFieldType.halfdays(), DateTimeConstants.MILLIS_PER_DAY / 2);
85         cDaysField = new PreciseDurationField
86             (DurationFieldType.days(), DateTimeConstants.MILLIS_PER_DAY);
87         cWeeksField = new PreciseDurationField
88             (DurationFieldType.weeks(), DateTimeConstants.MILLIS_PER_WEEK);
89
90         cMillisOfSecondField = new PreciseDateTimeField
91             (DateTimeFieldType.millisOfSecond(), cMillisField, cSecondsField);
92
93         cMillisOfDayField = new PreciseDateTimeField
94             (DateTimeFieldType.millisOfDay(), cMillisField, cDaysField);
95              
96         cSecondOfMinuteField = new PreciseDateTimeField
97             (DateTimeFieldType.secondOfMinute(), cSecondsField, cMinutesField);
98
99         cSecondOfDayField = new PreciseDateTimeField
100             (DateTimeFieldType.secondOfDay(), cSecondsField, cDaysField);
101
102         cMinuteOfHourField = new PreciseDateTimeField
103             (DateTimeFieldType.minuteOfHour(), cMinutesField, cHoursField);
104
105         cMinuteOfDayField = new PreciseDateTimeField
106             (DateTimeFieldType.minuteOfDay(), cMinutesField, cDaysField);
107
108         cHourOfDayField = new PreciseDateTimeField
109             (DateTimeFieldType.hourOfDay(), cHoursField, cDaysField);
110
111         cHourOfHalfdayField = new PreciseDateTimeField
112             (DateTimeFieldType.hourOfHalfday(), cHoursField, cHalfdaysField);
113
114         cClockhourOfDayField = new ZeroIsMaxDateTimeField
115             (cHourOfDayField, DateTimeFieldType.clockhourOfDay());
116
117         cClockhourOfHalfdayField = new ZeroIsMaxDateTimeField
118             (cHourOfHalfdayField, DateTimeFieldType.clockhourOfHalfday());
119
120         cHalfdayOfDayField = new HalfdayField();
121     }
122
123     private static final int CACHE_SIZE = 1 << 10;
124     private static final int CACHE_MASK = CACHE_SIZE - 1;
125
126     private transient final YearInfo[] iYearInfoCache = new YearInfo[CACHE_SIZE];
127
128     private final int iMinDaysInFirstWeek;
129
130     BasicChronology(Chronology base, Object JavaDoc param, int minDaysInFirstWeek) {
131         super(base, param);
132
133         if (minDaysInFirstWeek < 1 || minDaysInFirstWeek > 7) {
134             throw new IllegalArgumentException JavaDoc
135                 ("Invalid min days in first week: " + minDaysInFirstWeek);
136         }
137
138         iMinDaysInFirstWeek = minDaysInFirstWeek;
139     }
140
141     public DateTimeZone getZone() {
142         Chronology base;
143         if ((base = getBase()) != null) {
144             return base.getZone();
145         }
146         return DateTimeZone.UTC;
147     }
148
149     public long getDateTimeMillis(
150             int year, int monthOfYear, int dayOfMonth, int millisOfDay)
151             throws IllegalArgumentException JavaDoc {
152         Chronology base;
153         if ((base = getBase()) != null) {
154             return base.getDateTimeMillis(year, monthOfYear, dayOfMonth, millisOfDay);
155         }
156
157         FieldUtils.verifyValueBounds
158             (DateTimeFieldType.millisOfDay(), millisOfDay, 0, DateTimeConstants.MILLIS_PER_DAY);
159         return getDateMidnightMillis(year, monthOfYear, dayOfMonth) + millisOfDay;
160     }
161
162     public long getDateTimeMillis(
163             int year, int monthOfYear, int dayOfMonth,
164             int hourOfDay, int minuteOfHour, int secondOfMinute, int millisOfSecond)
165             throws IllegalArgumentException JavaDoc {
166         Chronology base;
167         if ((base = getBase()) != null) {
168             return base.getDateTimeMillis(year, monthOfYear, dayOfMonth,
169                                           hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond);
170         }
171
172         FieldUtils.verifyValueBounds(DateTimeFieldType.hourOfDay(), hourOfDay, 0, 23);
173         FieldUtils.verifyValueBounds(DateTimeFieldType.minuteOfHour(), minuteOfHour, 0, 59);
174         FieldUtils.verifyValueBounds(DateTimeFieldType.secondOfMinute(), secondOfMinute, 0, 59);
175         FieldUtils.verifyValueBounds(DateTimeFieldType.millisOfSecond(), millisOfSecond, 0, 999);
176
177         return getDateMidnightMillis(year, monthOfYear, dayOfMonth)
178             + hourOfDay * DateTimeConstants.MILLIS_PER_HOUR
179             + minuteOfHour * DateTimeConstants.MILLIS_PER_MINUTE
180             + secondOfMinute * DateTimeConstants.MILLIS_PER_SECOND
181             + millisOfSecond;
182     }
183
184     public int getMinimumDaysInFirstWeek() {
185         return iMinDaysInFirstWeek;
186     }
187
188     // Output
189
//-----------------------------------------------------------------------
190
/**
191      * Gets a debugging toString.
192      *
193      * @return a debugging string
194      */

195     public String JavaDoc toString() {
196         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(60);
197         String JavaDoc name = getClass().getName();
198         int index = name.lastIndexOf('.');
199         if (index >= 0) {
200             name = name.substring(index + 1);
201         }
202         sb.append(name);
203         sb.append('[');
204         DateTimeZone zone = getZone();
205         if (zone != null) {
206             sb.append(zone.getID());
207         }
208         if (getMinimumDaysInFirstWeek() != 4) {
209             sb.append(",mdfw=");
210             sb.append(getMinimumDaysInFirstWeek());
211         }
212         sb.append(']');
213         return sb.toString();
214     }
215
216     protected void assemble(Fields fields) {
217         // First copy fields that are the same for all Gregorian and Julian
218
// chronologies.
219

220         fields.millis = cMillisField;
221         fields.seconds = cSecondsField;
222         fields.minutes = cMinutesField;
223         fields.hours = cHoursField;
224         fields.halfdays = cHalfdaysField;
225         fields.days = cDaysField;
226         fields.weeks = cWeeksField;
227
228         fields.millisOfSecond = cMillisOfSecondField;
229         fields.millisOfDay = cMillisOfDayField;
230         fields.secondOfMinute = cSecondOfMinuteField;
231         fields.secondOfDay = cSecondOfDayField;
232         fields.minuteOfHour = cMinuteOfHourField;
233         fields.minuteOfDay = cMinuteOfDayField;
234         fields.hourOfDay = cHourOfDayField;
235         fields.hourOfHalfday = cHourOfHalfdayField;
236         fields.clockhourOfDay = cClockhourOfDayField;
237         fields.clockhourOfHalfday = cClockhourOfHalfdayField;
238         fields.halfdayOfDay = cHalfdayOfDayField;
239
240         // Now create fields that have unique behavior for Gregorian and Julian
241
// chronologies.
242

243         fields.year = new BasicYearDateTimeField(this);
244         fields.yearOfEra = new GJYearOfEraDateTimeField(fields.year, this);
245
246         // Define one-based centuryOfEra and yearOfCentury.
247
DateTimeField field = new OffsetDateTimeField(
248             fields.yearOfEra, 99);
249         fields.centuryOfEra = new DividedDateTimeField(
250             field, DateTimeFieldType.centuryOfEra(), 100);
251         
252         field = new RemainderDateTimeField(
253             (DividedDateTimeField) fields.centuryOfEra);
254         fields.yearOfCentury = new OffsetDateTimeField(
255             field, DateTimeFieldType.yearOfCentury(), 1);
256
257         fields.era = new GJEraDateTimeField(this);
258         fields.dayOfWeek = new GJDayOfWeekDateTimeField(this, fields.days);
259         fields.dayOfMonth = new BasicDayOfMonthDateTimeField(this, fields.days);
260         fields.dayOfYear = new BasicDayOfYearDateTimeField(this, fields.days);
261         fields.monthOfYear = new GJMonthOfYearDateTimeField(this);
262         fields.weekyear = new BasicWeekyearDateTimeField(this);
263         fields.weekOfWeekyear = new BasicWeekOfWeekyearDateTimeField(this, fields.weeks);
264         
265         field = new RemainderDateTimeField(
266             fields.weekyear, DateTimeFieldType.weekyearOfCentury(), 100);
267         fields.weekyearOfCentury = new OffsetDateTimeField(
268             field, DateTimeFieldType.weekyearOfCentury(), 1);
269         
270         // The remaining (imprecise) durations are available from the newly
271
// created datetime fields.
272

273         fields.years = fields.year.getDurationField();
274         fields.centuries = fields.centuryOfEra.getDurationField();
275         fields.months = fields.monthOfYear.getDurationField();
276         fields.weekyears = fields.weekyear.getDurationField();
277     }
278
279     //-----------------------------------------------------------------------
280
/**
281      * Get the number of days in the year.
282      *
283      * @return 366
284      */

285     int getDaysInYearMax() {
286         return 366;
287     }
288
289     /**
290      * Get the number of days in the year.
291      *
292      * @param year the year to use
293      * @return 366 if a leap year, otherwise 365
294      */

295     int getDaysInYear(int year) {
296         return isLeapYear(year) ? 366 : 365;
297     }
298
299     /**
300      * Get the number of weeks in the year.
301      *
302      * @param year the year to use
303      * @return number of weeks in the year
304      */

305     int getWeeksInYear(int year) {
306         long firstWeekMillis1 = getFirstWeekOfYearMillis(year);
307         long firstWeekMillis2 = getFirstWeekOfYearMillis(year + 1);
308         return (int) ((firstWeekMillis2 - firstWeekMillis1) / DateTimeConstants.MILLIS_PER_WEEK);
309     }
310
311     /**
312      * Get the millis for the first week of a year.
313      *
314      * @param year the year to use
315      * @return millis
316      */

317     long getFirstWeekOfYearMillis(int year) {
318         long jan1millis = getYearMillis(year);
319         int jan1dayOfWeek = getDayOfWeek(jan1millis);
320         
321         if (jan1dayOfWeek > (8 - iMinDaysInFirstWeek)) {
322             // First week is end of previous year because it doesn't have enough days.
323
return jan1millis + (8 - jan1dayOfWeek)
324                 * (long)DateTimeConstants.MILLIS_PER_DAY;
325         } else {
326             // First week is start of this year because it has enough days.
327
return jan1millis - (jan1dayOfWeek - 1)
328                 * (long)DateTimeConstants.MILLIS_PER_DAY;
329         }
330     }
331
332     /**
333      * Get the milliseconds for the start of a year.
334      *
335      * @param year The year to use.
336      * @return millis from 1970-01-01T00:00:00Z
337      */

338     long getYearMillis(int year) {
339         return getYearInfo(year).iFirstDayMillis;
340     }
341
342     /**
343      * Get the milliseconds for the start of a month.
344      *
345      * @param year The year to use.
346      * @param month The month to use
347      * @return millis from 1970-01-01T00:00:00Z
348      */

349     long getYearMonthMillis(int year, int month) {
350         long millis = getYearMillis(year);
351         millis += getTotalMillisByYearMonth(year, month);
352         return millis;
353     }
354
355     /**
356      * Get the milliseconds for a particular date.
357      *
358      * @param year The year to use.
359      * @param month The month to use
360      * @param dayOfMonth The day of the month to use
361      * @return millis from 1970-01-01T00:00:00Z
362      */

363     long getYearMonthDayMillis(int year, int month, int dayOfMonth) {
364         long millis = getYearMillis(year);
365         millis += getTotalMillisByYearMonth(year, month);
366         return millis + (dayOfMonth - 1) * (long)DateTimeConstants.MILLIS_PER_DAY;
367     }
368     
369     /**
370      * @param instant millis from 1970-01-01T00:00:00Z
371      */

372     int getYear(long instant) {
373         // Get an initial estimate of the year, and the millis value that
374
// represents the start of that year. Then verify estimate and fix if
375
// necessary.
376

377         // Initial estimate uses values divided by two to avoid overflow.
378
long unitMillis = getAverageMillisPerYearDividedByTwo();
379         long i2 = (instant >> 1) + getApproxMillisAtEpochDividedByTwo();
380         if (i2 < 0) {
381             i2 = i2 - unitMillis + 1;
382         }
383         int year = (int) (i2 / unitMillis);
384
385         long yearStart = getYearMillis(year);
386         long diff = instant - yearStart;
387
388         if (diff < 0) {
389             year--;
390         } else if (diff >= DateTimeConstants.MILLIS_PER_DAY * 365L) {
391             // One year may need to be added to fix estimate.
392
long oneYear;
393             if (isLeapYear(year)) {
394                 oneYear = DateTimeConstants.MILLIS_PER_DAY * 366L;
395             } else {
396                 oneYear = DateTimeConstants.MILLIS_PER_DAY * 365L;
397             }
398
399             yearStart += oneYear;
400
401             if (yearStart <= instant) {
402                 // Didn't go too far, so actually add one year.
403
year++;
404             }
405         }
406
407         return year;
408     }
409
410     /**
411      * @param millis from 1970-01-01T00:00:00Z
412      */

413     int getMonthOfYear(long millis) {
414         return getMonthOfYear(millis, getYear(millis));
415     }
416
417     /**
418      * @param millis from 1970-01-01T00:00:00Z
419      * @param year precalculated year of millis
420      */

421     abstract int getMonthOfYear(long millis, int year);
422
423     /**
424      * @param millis from 1970-01-01T00:00:00Z
425      */

426     int getDayOfMonth(long millis) {
427         int year = getYear(millis);
428         int month = getMonthOfYear(millis, year);
429         return getDayOfMonth(millis, year, month);
430     }
431
432     /**
433      * @param millis from 1970-01-01T00:00:00Z
434      * @param year precalculated year of millis
435      */

436     int getDayOfMonth(long millis, int year) {
437         int month = getMonthOfYear(millis, year);
438         return getDayOfMonth(millis, year, month);
439     }
440
441     /**
442      * @param millis from 1970-01-01T00:00:00Z
443      * @param year precalculated year of millis
444      * @param month precalculated month of millis
445      */

446     int getDayOfMonth(long millis, int year, int month) {
447         long dateMillis = getYearMillis(year);
448         dateMillis += getTotalMillisByYearMonth(year, month);
449         return (int) ((millis - dateMillis) / DateTimeConstants.MILLIS_PER_DAY) + 1;
450     }
451
452     /**
453      * @param instant millis from 1970-01-01T00:00:00Z
454      */

455     int getDayOfYear(long instant) {
456         return getDayOfYear(instant, getYear(instant));
457     }
458
459     /**
460      * @param instant millis from 1970-01-01T00:00:00Z
461      * @param year precalculated year of millis
462      */

463     int getDayOfYear(long instant, int year) {
464         long yearStart = getYearMillis(year);
465         return (int) ((instant - yearStart) / DateTimeConstants.MILLIS_PER_DAY) + 1;
466     }
467
468     /**
469      * @param instant millis from 1970-01-01T00:00:00Z
470      */

471     int getWeekyear(long instant) {
472         int year = getYear(instant);
473         int week = getWeekOfWeekyear(instant, year);
474         if (week == 1) {
475             return getYear(instant + DateTimeConstants.MILLIS_PER_WEEK);
476         } else if (week > 51) {
477             return getYear(instant - (2 * DateTimeConstants.MILLIS_PER_WEEK));
478         } else {
479             return year;
480         }
481     }
482
483     /**
484      * @param instant millis from 1970-01-01T00:00:00Z
485      */

486     int getWeekOfWeekyear(long instant) {
487         return getWeekOfWeekyear(instant, getYear(instant));
488     }
489
490     /**
491      * @param instant millis from 1970-01-01T00:00:00Z
492      * @param year precalculated year of millis
493      */

494     int getWeekOfWeekyear(long instant, int year) {
495         long firstWeekMillis1 = getFirstWeekOfYearMillis(year);
496         if (instant < firstWeekMillis1) {
497             return getWeeksInYear(year - 1);
498         }
499         long firstWeekMillis2 = getFirstWeekOfYearMillis(year + 1);
500         if (instant >= firstWeekMillis2) {
501             return 1;
502         }
503         return (int) ((instant - firstWeekMillis1) / DateTimeConstants.MILLIS_PER_WEEK) + 1;
504     }
505
506     /**
507      * @param instant millis from 1970-01-01T00:00:00Z
508      */

509     int getDayOfWeek(long instant) {
510         // 1970-01-01 is day of week 4, Thursday.
511

512         long daysSince19700101;
513         if (instant >= 0) {
514             daysSince19700101 = instant / DateTimeConstants.MILLIS_PER_DAY;
515         } else {
516             daysSince19700101 = (instant - (DateTimeConstants.MILLIS_PER_DAY - 1))
517                 / DateTimeConstants.MILLIS_PER_DAY;
518             if (daysSince19700101 < -3) {
519                 return 7 + (int) ((daysSince19700101 + 4) % 7);
520             }
521         }
522
523         return 1 + (int) ((daysSince19700101 + 3) % 7);
524     }
525
526     /**
527      * @param instant millis from 1970-01-01T00:00:00Z
528      */

529     int getMillisOfDay(long instant) {
530         if (instant >= 0) {
531             return (int) (instant % DateTimeConstants.MILLIS_PER_DAY);
532         } else {
533             return (DateTimeConstants.MILLIS_PER_DAY - 1)
534                 + (int) ((instant + 1) % DateTimeConstants.MILLIS_PER_DAY);
535         }
536     }
537
538     /**
539      * Gets the maximum number of days in any month.
540      *
541      * @return 31
542      */

543     int getDaysInMonthMax() {
544         return 31;
545     }
546
547     /**
548      * Gets the maximum number of days in the month specified by the instant.
549      *
550      * @param instant millis from 1970-01-01T00:00:00Z
551      * @return the maximum number of days in the month
552      */

553     int getDaysInMonthMax(long instant) {
554         int thisYear = getYear(instant);
555         int thisMonth = getMonthOfYear(instant, thisYear);
556         return getDaysInYearMonth(thisYear, thisMonth);
557     }
558
559     /**
560      * Gets the maximum number of days in the month specified by the instant.
561      * The value represents what the user is trying to set, and can be
562      * used to optimise this method.
563      *
564      * @param instant millis from 1970-01-01T00:00:00Z
565      * @param value the value being set
566      * @return the maximum number of days in the month
567      */

568     int getDaysInMonthMaxForSet(long instant, int value) {
569         return getDaysInMonthMax(instant);
570     }
571
572     //-----------------------------------------------------------------------
573
/**
574      * Gets the milliseconds for a date at midnight.
575      *
576      * @param year the year
577      * @param monthOfYear the month
578      * @param dayOfMonth the day
579      * @return the milliseconds
580      */

581     long getDateMidnightMillis(int year, int monthOfYear, int dayOfMonth) {
582         FieldUtils.verifyValueBounds(DateTimeFieldType.year(), year, getMinYear(), getMaxYear());
583         FieldUtils.verifyValueBounds(DateTimeFieldType.monthOfYear(), monthOfYear, 1, getMaxMonth(year));
584         FieldUtils.verifyValueBounds(DateTimeFieldType.dayOfMonth(), dayOfMonth, 1, getDaysInYearMonth(year, monthOfYear));
585         return getYearMonthDayMillis(year, monthOfYear, dayOfMonth);
586     }
587
588     /**
589      * Gets the difference between the two instants in years.
590      *
591      * @param minuendInstant the first instant
592      * @param subtrahendInstant the second instant
593      * @return the difference
594      */

595     abstract long getYearDifference(long minuendInstant, long subtrahendInstant);
596
597     /**
598      * Is the specified year a leap year?
599      *
600      * @param year the year to test
601      * @return true if leap
602      */

603     abstract boolean isLeapYear(int year);
604
605     /**
606      * Gets the number of days in the specified month and year.
607      *
608      * @param year the year
609      * @param month the month
610      * @return the number of days
611      */

612     abstract int getDaysInYearMonth(int year, int month);
613
614     /**
615      * Gets the maximum days in the specified month.
616      *
617      * @param month the month
618      * @return the max days
619      */

620     abstract int getDaysInMonthMax(int month);
621
622     /**
623      * Gets the total number of millis elapsed in this year at the start
624      * of the specified month, such as zero for month 1.
625      *
626      * @param year the year
627      * @param month the month
628      * @return the elapsed millis at the start of the month
629      */

630     abstract long getTotalMillisByYearMonth(int year, int month);
631
632     /**
633      * Gets the millisecond value of the first day of the year.
634      *
635      * @return the milliseconds for the first of the year
636      */

637     abstract long calculateFirstDayOfYearMillis(int year);
638
639     /**
640      * Gets the minimum supported year.
641      *
642      * @return the year
643      */

644     abstract int getMinYear();
645
646     /**
647      * Gets the maximum supported year.
648      *
649      * @return the year
650      */

651     abstract int getMaxYear();
652
653     /**
654      * Gets the maximum month for the specified year.
655      * This implementation calls getMaxMonth().
656      *
657      * @param year the year
658      * @return the maximum month value
659      */

660     int getMaxMonth(int year) {
661         return getMaxMonth();
662     }
663
664     /**
665      * Gets the maximum number of months.
666      *
667      * @return 12
668      */

669     int getMaxMonth() {
670         return 12;
671     }
672
673     /**
674      * Gets an average value for the milliseconds per year.
675      *
676      * @return the millis per year
677      */

678     abstract long getAverageMillisPerYear();
679
680     /**
681      * Gets an average value for the milliseconds per year, divided by two.
682      *
683      * @return the millis per year divided by two
684      */

685     abstract long getAverageMillisPerYearDividedByTwo();
686
687     /**
688      * Gets an average value for the milliseconds per month.
689      *
690      * @return the millis per month
691      */

692     abstract long getAverageMillisPerMonth();
693
694     /**
695      * Returns a constant representing the approximate number of milliseconds
696      * elapsed from year 0 of this chronology, divided by two. This constant
697      * <em>must</em> be defined as:
698      * <pre>
699      * (yearAtEpoch * averageMillisPerYear + millisOfYearAtEpoch) / 2
700      * </pre>
701      * where epoch is 1970-01-01 (Gregorian).
702      */

703     abstract long getApproxMillisAtEpochDividedByTwo();
704
705     /**
706      * Sets the year from an instant and year.
707      *
708      * @param instant millis from 1970-01-01T00:00:00Z
709      * @param year the year to set
710      * @return the updated millis
711      */

712     abstract long setYear(long instant, int year);
713
714     //-----------------------------------------------------------------------
715
// Although accessed by multiple threads, this method doesn't need to be synchronized.
716
private YearInfo getYearInfo(int year) {
717         YearInfo info = iYearInfoCache[year & CACHE_MASK];
718         if (info == null || info.iYear != year) {
719             info = new YearInfo(year, calculateFirstDayOfYearMillis(year));
720             iYearInfoCache[year & CACHE_MASK] = info;
721         }
722         return info;
723     }
724
725     private static class HalfdayField extends PreciseDateTimeField {
726         private static final long serialVersionUID = 581601443656929254L;
727
728         HalfdayField() {
729             super(DateTimeFieldType.halfdayOfDay(), cHalfdaysField, cDaysField);
730         }
731
732         public String JavaDoc getAsText(int fieldValue, Locale JavaDoc locale) {
733             return GJLocaleSymbols.forLocale(locale).halfdayValueToText(fieldValue);
734         }
735
736         public long set(long millis, String JavaDoc text, Locale JavaDoc locale) {
737             return set(millis, GJLocaleSymbols.forLocale(locale).halfdayTextToValue(text));
738         }
739
740         public int getMaximumTextLength(Locale JavaDoc locale) {
741             return GJLocaleSymbols.forLocale(locale).getHalfdayMaxTextLength();
742         }
743     }
744
745     private static class YearInfo {
746         public final int iYear;
747         public final long iFirstDayMillis;
748
749         YearInfo(int year, long firstDayMillis) {
750             iYear = year;
751             iFirstDayMillis = firstDayMillis;
752         }
753     }
754
755 }
756
Popular Tags