EMMA Coverage Report (generated Tue Oct 28 00:01:11 GMT 2008)
[all classes][org.joda.time.chrono]

COVERAGE SUMMARY FOR SOURCE FILE [BasicChronology.java]

nameclass, %method, %block, %line, %
BasicChronology.java100% (3/3)100% (41/41)99%  (963/975)99%  (189/190)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class BasicChronology100% (1/1)100% (36/36)99%  (931/943)99%  (180/181)
BasicChronology (Chronology, Object, int): void 100% (1/1)60%  (18/30)83%  (5/6)
<static initializer> 100% (1/1)100% (111/111)100% (19/19)
assemble (AssembledChronology$Fields): void 100% (1/1)100% (185/185)100% (38/38)
equals (Object): boolean 100% (1/1)100% (4/4)100% (1/1)
getDateMidnightMillis (int, int, int): long 100% (1/1)100% (28/28)100% (4/4)
getDateTimeMillis (int, int, int, int): long 100% (1/1)100% (26/26)100% (4/4)
getDateTimeMillis (int, int, int, int, int, int, int): long 100% (1/1)100% (59/59)100% (7/7)
getDayOfMonth (long): int 100% (1/1)100% (15/15)100% (3/3)
getDayOfMonth (long, int): int 100% (1/1)100% (11/11)100% (2/2)
getDayOfMonth (long, int, int): int 100% (1/1)100% (20/20)100% (3/3)
getDayOfWeek (long): int 100% (1/1)100% (37/37)100% (6/6)
getDayOfYear (long): int 100% (1/1)100% (7/7)100% (1/1)
getDayOfYear (long, int): int 100% (1/1)100% (13/13)100% (2/2)
getDaysInMonthMax (): int 100% (1/1)100% (2/2)100% (1/1)
getDaysInMonthMax (long): int 100% (1/1)100% (14/14)100% (3/3)
getDaysInMonthMaxForSet (long, int): int 100% (1/1)100% (4/4)100% (1/1)
getDaysInYear (int): int 100% (1/1)100% (8/8)100% (1/1)
getDaysInYearMax (): int 100% (1/1)100% (2/2)100% (1/1)
getFirstWeekOfYearMillis (int): long 100% (1/1)100% (32/32)100% (5/5)
getMaxMonth (): int 100% (1/1)100% (2/2)100% (1/1)
getMaxMonth (int): int 100% (1/1)100% (3/3)100% (1/1)
getMillisOfDay (long): int 100% (1/1)100% (18/18)100% (3/3)
getMinimumDaysInFirstWeek (): int 100% (1/1)100% (3/3)100% (1/1)
getMonthOfYear (long): int 100% (1/1)100% (7/7)100% (1/1)
getWeekOfWeekyear (long): int 100% (1/1)100% (7/7)100% (1/1)
getWeekOfWeekyear (long, int): int 100% (1/1)100% (35/35)100% (7/7)
getWeeksInYear (int): int 100% (1/1)100% (17/17)100% (3/3)
getWeekyear (long): int 100% (1/1)100% (29/29)100% (7/7)
getYear (long): int 100% (1/1)100% (63/63)100% (17/17)
getYearInfo (int): BasicChronology$YearInfo 100% (1/1)100% (30/30)100% (5/5)
getYearMillis (int): long 100% (1/1)100% (5/5)100% (1/1)
getYearMonthDayMillis (int, int, int): long 100% (1/1)100% (20/20)100% (3/3)
getYearMonthMillis (int, int): long 100% (1/1)100% (13/13)100% (3/3)
getZone (): DateTimeZone 100% (1/1)100% (10/10)100% (3/3)
hashCode (): int 100% (1/1)100% (14/14)100% (1/1)
toString (): String 100% (1/1)100% (59/59)100% (15/15)
     
class BasicChronology$HalfdayField100% (1/1)100% (4/4)100% (23/23)100% (5/5)
BasicChronology$HalfdayField (): void 100% (1/1)100% (6/6)100% (2/2)
getAsText (int, Locale): String 100% (1/1)100% (5/5)100% (1/1)
getMaximumTextLength (Locale): int 100% (1/1)100% (4/4)100% (1/1)
set (long, String, Locale): long 100% (1/1)100% (8/8)100% (1/1)
     
class BasicChronology$YearInfo100% (1/1)100% (1/1)100% (9/9)100% (4/4)
BasicChronology$YearInfo (int, long): void 100% (1/1)100% (9/9)100% (4/4)

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 */
16package org.joda.time.chrono;
17 
18import java.util.Locale;
19 
20import org.joda.time.Chronology;
21import org.joda.time.DateTimeConstants;
22import org.joda.time.DateTimeField;
23import org.joda.time.DateTimeFieldType;
24import org.joda.time.DateTimeZone;
25import org.joda.time.DurationField;
26import org.joda.time.DurationFieldType;
27import org.joda.time.field.DividedDateTimeField;
28import org.joda.time.field.FieldUtils;
29import org.joda.time.field.MillisDurationField;
30import org.joda.time.field.OffsetDateTimeField;
31import org.joda.time.field.PreciseDateTimeField;
32import org.joda.time.field.PreciseDurationField;
33import org.joda.time.field.RemainderDateTimeField;
34import org.joda.time.field.ZeroIsMaxDateTimeField;
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 */
50abstract 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 param, int minDaysInFirstWeek) {
131        super(base, param);
132 
133        if (minDaysInFirstWeek < 1 || minDaysInFirstWeek > 7) {
134            throw new IllegalArgumentException
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 {
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 {
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    /**
189     * Checks if this chronology instance equals another.
190     * 
191     * @param obj  the object to compare to
192     * @return true if equal
193     * @since 1.6
194     */
195    public boolean equals(Object obj) {
196        return super.equals(obj);
197    }
198 
199    /**
200     * A suitable hash code for the chronology.
201     * 
202     * @return the hash code
203     * @since 1.6
204     */
205    public int hashCode() {
206        return getClass().getName().hashCode() * 11 + getZone().hashCode() + getMinimumDaysInFirstWeek();
207    }
208 
209    // Output
210    //-----------------------------------------------------------------------
211    /**
212     * Gets a debugging toString.
213     * 
214     * @return a debugging string
215     */
216    public String toString() {
217        StringBuffer sb = new StringBuffer(60);
218        String name = getClass().getName();
219        int index = name.lastIndexOf('.');
220        if (index >= 0) {
221            name = name.substring(index + 1);
222        }
223        sb.append(name);
224        sb.append('[');
225        DateTimeZone zone = getZone();
226        if (zone != null) {
227            sb.append(zone.getID());
228        }
229        if (getMinimumDaysInFirstWeek() != 4) {
230            sb.append(",mdfw=");
231            sb.append(getMinimumDaysInFirstWeek());
232        }
233        sb.append(']');
234        return sb.toString();
235    }
236 
237    protected void assemble(Fields fields) {
238        // First copy fields that are the same for all Gregorian and Julian
239        // chronologies.
240 
241        fields.millis = cMillisField;
242        fields.seconds = cSecondsField;
243        fields.minutes = cMinutesField;
244        fields.hours = cHoursField;
245        fields.halfdays = cHalfdaysField;
246        fields.days = cDaysField;
247        fields.weeks = cWeeksField;
248 
249        fields.millisOfSecond = cMillisOfSecondField;
250        fields.millisOfDay = cMillisOfDayField;
251        fields.secondOfMinute = cSecondOfMinuteField;
252        fields.secondOfDay = cSecondOfDayField;
253        fields.minuteOfHour = cMinuteOfHourField;
254        fields.minuteOfDay = cMinuteOfDayField;
255        fields.hourOfDay = cHourOfDayField;
256        fields.hourOfHalfday = cHourOfHalfdayField;
257        fields.clockhourOfDay = cClockhourOfDayField;
258        fields.clockhourOfHalfday = cClockhourOfHalfdayField;
259        fields.halfdayOfDay = cHalfdayOfDayField;
260 
261        // Now create fields that have unique behavior for Gregorian and Julian
262        // chronologies.
263 
264        fields.year = new BasicYearDateTimeField(this);
265        fields.yearOfEra = new GJYearOfEraDateTimeField(fields.year, this);
266 
267        // Define one-based centuryOfEra and yearOfCentury.
268        DateTimeField field = new OffsetDateTimeField(
269            fields.yearOfEra, 99);
270        fields.centuryOfEra = new DividedDateTimeField(
271            field, DateTimeFieldType.centuryOfEra(), 100);
272        
273        field = new RemainderDateTimeField(
274            (DividedDateTimeField) fields.centuryOfEra);
275        fields.yearOfCentury = new OffsetDateTimeField(
276            field, DateTimeFieldType.yearOfCentury(), 1);
277 
278        fields.era = new GJEraDateTimeField(this);
279        fields.dayOfWeek = new GJDayOfWeekDateTimeField(this, fields.days);
280        fields.dayOfMonth = new BasicDayOfMonthDateTimeField(this, fields.days);
281        fields.dayOfYear = new BasicDayOfYearDateTimeField(this, fields.days);
282        fields.monthOfYear = new GJMonthOfYearDateTimeField(this);
283        fields.weekyear = new BasicWeekyearDateTimeField(this);
284        fields.weekOfWeekyear = new BasicWeekOfWeekyearDateTimeField(this, fields.weeks);
285        
286        field = new RemainderDateTimeField(
287            fields.weekyear, DateTimeFieldType.weekyearOfCentury(), 100);
288        fields.weekyearOfCentury = new OffsetDateTimeField(
289            field, DateTimeFieldType.weekyearOfCentury(), 1);
290        
291        // The remaining (imprecise) durations are available from the newly
292        // created datetime fields.
293 
294        fields.years = fields.year.getDurationField();
295        fields.centuries = fields.centuryOfEra.getDurationField();
296        fields.months = fields.monthOfYear.getDurationField();
297        fields.weekyears = fields.weekyear.getDurationField();
298    }
299 
300    //-----------------------------------------------------------------------
301    /**
302     * Get the number of days in the year.
303     *
304     * @return 366
305     */
306    int getDaysInYearMax() {
307        return 366;
308    }
309 
310    /**
311     * Get the number of days in the year.
312     *
313     * @param year  the year to use
314     * @return 366 if a leap year, otherwise 365
315     */
316    int getDaysInYear(int year) {
317        return isLeapYear(year) ? 366 : 365;
318    }
319 
320    /**
321     * Get the number of weeks in the year.
322     *
323     * @param year  the year to use
324     * @return number of weeks in the year
325     */
326    int getWeeksInYear(int year) {
327        long firstWeekMillis1 = getFirstWeekOfYearMillis(year);
328        long firstWeekMillis2 = getFirstWeekOfYearMillis(year + 1);
329        return (int) ((firstWeekMillis2 - firstWeekMillis1) / DateTimeConstants.MILLIS_PER_WEEK);
330    }
331 
332    /**
333     * Get the millis for the first week of a year.
334     *
335     * @param year  the year to use
336     * @return millis
337     */
338    long getFirstWeekOfYearMillis(int year) {
339        long jan1millis = getYearMillis(year);
340        int jan1dayOfWeek = getDayOfWeek(jan1millis);
341        
342        if (jan1dayOfWeek > (8 - iMinDaysInFirstWeek)) {
343            // First week is end of previous year because it doesn't have enough days.
344            return jan1millis + (8 - jan1dayOfWeek)
345                * (long)DateTimeConstants.MILLIS_PER_DAY;
346        } else {
347            // First week is start of this year because it has enough days.
348            return jan1millis - (jan1dayOfWeek - 1)
349                * (long)DateTimeConstants.MILLIS_PER_DAY;
350        }
351    }
352 
353    /**
354     * Get the milliseconds for the start of a year.
355     *
356     * @param year The year to use.
357     * @return millis from 1970-01-01T00:00:00Z
358     */
359    long getYearMillis(int year) {
360        return getYearInfo(year).iFirstDayMillis;
361    }
362 
363    /**
364     * Get the milliseconds for the start of a month.
365     *
366     * @param year The year to use.
367     * @param month The month to use
368     * @return millis from 1970-01-01T00:00:00Z
369     */
370    long getYearMonthMillis(int year, int month) {
371        long millis = getYearMillis(year);
372        millis += getTotalMillisByYearMonth(year, month);
373        return millis;
374    }
375 
376    /**
377     * Get the milliseconds for a particular date.
378     *
379     * @param year The year to use.
380     * @param month The month to use
381     * @param dayOfMonth The day of the month to use
382     * @return millis from 1970-01-01T00:00:00Z
383     */
384    long getYearMonthDayMillis(int year, int month, int dayOfMonth) {
385        long millis = getYearMillis(year);
386        millis += getTotalMillisByYearMonth(year, month);
387        return millis + (dayOfMonth - 1) * (long)DateTimeConstants.MILLIS_PER_DAY;
388    }
389    
390    /**
391     * @param instant millis from 1970-01-01T00:00:00Z
392     */
393    int getYear(long instant) {
394        // Get an initial estimate of the year, and the millis value that
395        // represents the start of that year. Then verify estimate and fix if
396        // necessary.
397 
398        // Initial estimate uses values divided by two to avoid overflow.
399        long unitMillis = getAverageMillisPerYearDividedByTwo();
400        long i2 = (instant >> 1) + getApproxMillisAtEpochDividedByTwo();
401        if (i2 < 0) {
402            i2 = i2 - unitMillis + 1;
403        }
404        int year = (int) (i2 / unitMillis);
405 
406        long yearStart = getYearMillis(year);
407        long diff = instant - yearStart;
408 
409        if (diff < 0) {
410            year--;
411        } else if (diff >= DateTimeConstants.MILLIS_PER_DAY * 365L) {
412            // One year may need to be added to fix estimate.
413            long oneYear;
414            if (isLeapYear(year)) {
415                oneYear = DateTimeConstants.MILLIS_PER_DAY * 366L;
416            } else {
417                oneYear = DateTimeConstants.MILLIS_PER_DAY * 365L;
418            }
419 
420            yearStart += oneYear;
421 
422            if (yearStart <= instant) {
423                // Didn't go too far, so actually add one year.
424                year++;
425            }
426        }
427 
428        return year;
429    }
430 
431    /**
432     * @param millis from 1970-01-01T00:00:00Z
433     */
434    int getMonthOfYear(long millis) {
435        return getMonthOfYear(millis, getYear(millis));
436    }
437 
438    /**
439     * @param millis from 1970-01-01T00:00:00Z
440     * @param year precalculated year of millis
441     */
442    abstract int getMonthOfYear(long millis, int year);
443 
444    /**
445     * @param millis from 1970-01-01T00:00:00Z
446     */
447    int getDayOfMonth(long millis) {
448        int year = getYear(millis);
449        int month = getMonthOfYear(millis, year);
450        return getDayOfMonth(millis, year, month);
451    }
452 
453    /**
454     * @param millis from 1970-01-01T00:00:00Z
455     * @param year precalculated year of millis
456     */
457    int getDayOfMonth(long millis, int year) {
458        int month = getMonthOfYear(millis, year);
459        return getDayOfMonth(millis, year, month);
460    }
461 
462    /**
463     * @param millis from 1970-01-01T00:00:00Z
464     * @param year precalculated year of millis
465     * @param month precalculated month of millis
466     */
467    int getDayOfMonth(long millis, int year, int month) {
468        long dateMillis = getYearMillis(year);
469        dateMillis += getTotalMillisByYearMonth(year, month);
470        return (int) ((millis - dateMillis) / DateTimeConstants.MILLIS_PER_DAY) + 1;
471    }
472 
473    /**
474     * @param instant millis from 1970-01-01T00:00:00Z
475     */
476    int getDayOfYear(long instant) {
477        return getDayOfYear(instant, getYear(instant));
478    }
479 
480    /**
481     * @param instant millis from 1970-01-01T00:00:00Z
482     * @param year precalculated year of millis
483     */
484    int getDayOfYear(long instant, int year) {
485        long yearStart = getYearMillis(year);
486        return (int) ((instant - yearStart) / DateTimeConstants.MILLIS_PER_DAY) + 1;
487    }
488 
489    /**
490     * @param instant millis from 1970-01-01T00:00:00Z
491     */
492    int getWeekyear(long instant) {
493        int year = getYear(instant);
494        int week = getWeekOfWeekyear(instant, year);
495        if (week == 1) {
496            return getYear(instant + DateTimeConstants.MILLIS_PER_WEEK);
497        } else if (week > 51) {
498            return getYear(instant - (2 * DateTimeConstants.MILLIS_PER_WEEK));
499        } else {
500            return year;
501        }
502    }
503 
504    /**
505     * @param instant millis from 1970-01-01T00:00:00Z
506     */
507    int getWeekOfWeekyear(long instant) {
508        return getWeekOfWeekyear(instant, getYear(instant));
509    }
510 
511    /**
512     * @param instant millis from 1970-01-01T00:00:00Z
513     * @param year precalculated year of millis
514     */
515    int getWeekOfWeekyear(long instant, int year) {
516        long firstWeekMillis1 = getFirstWeekOfYearMillis(year);
517        if (instant < firstWeekMillis1) {
518            return getWeeksInYear(year - 1);
519        }
520        long firstWeekMillis2 = getFirstWeekOfYearMillis(year + 1);
521        if (instant >= firstWeekMillis2) {
522            return 1;
523        }
524        return (int) ((instant - firstWeekMillis1) / DateTimeConstants.MILLIS_PER_WEEK) + 1;
525    }
526 
527    /**
528     * @param instant millis from 1970-01-01T00:00:00Z
529     */
530    int getDayOfWeek(long instant) {
531        // 1970-01-01 is day of week 4, Thursday.
532 
533        long daysSince19700101;
534        if (instant >= 0) {
535            daysSince19700101 = instant / DateTimeConstants.MILLIS_PER_DAY;
536        } else {
537            daysSince19700101 = (instant - (DateTimeConstants.MILLIS_PER_DAY - 1))
538                / DateTimeConstants.MILLIS_PER_DAY;
539            if (daysSince19700101 < -3) {
540                return 7 + (int) ((daysSince19700101 + 4) % 7);
541            }
542        }
543 
544        return 1 + (int) ((daysSince19700101 + 3) % 7);
545    }
546 
547    /**
548     * @param instant millis from 1970-01-01T00:00:00Z
549     */
550    int getMillisOfDay(long instant) {
551        if (instant >= 0) {
552            return (int) (instant % DateTimeConstants.MILLIS_PER_DAY);
553        } else {
554            return (DateTimeConstants.MILLIS_PER_DAY - 1)
555                + (int) ((instant + 1) % DateTimeConstants.MILLIS_PER_DAY);
556        }
557    }
558 
559    /**
560     * Gets the maximum number of days in any month.
561     * 
562     * @return 31
563     */
564    int getDaysInMonthMax() {
565        return 31;
566    }
567 
568    /**
569     * Gets the maximum number of days in the month specified by the instant.
570     * 
571     * @param instant  millis from 1970-01-01T00:00:00Z
572     * @return the maximum number of days in the month
573     */
574    int getDaysInMonthMax(long instant) {
575        int thisYear = getYear(instant);
576        int thisMonth = getMonthOfYear(instant, thisYear);
577        return getDaysInYearMonth(thisYear, thisMonth);
578    }
579 
580    /**
581     * Gets the maximum number of days in the month specified by the instant.
582     * The value represents what the user is trying to set, and can be
583     * used to optimise this method.
584     * 
585     * @param instant  millis from 1970-01-01T00:00:00Z
586     * @param value  the value being set
587     * @return the maximum number of days in the month
588     */
589    int getDaysInMonthMaxForSet(long instant, int value) {
590        return getDaysInMonthMax(instant);
591    }
592 
593    //-----------------------------------------------------------------------
594    /**
595     * Gets the milliseconds for a date at midnight.
596     * 
597     * @param year  the year
598     * @param monthOfYear  the month
599     * @param dayOfMonth  the day
600     * @return the milliseconds
601     */
602    long getDateMidnightMillis(int year, int monthOfYear, int dayOfMonth) {
603        FieldUtils.verifyValueBounds(DateTimeFieldType.year(), year, getMinYear(), getMaxYear());
604        FieldUtils.verifyValueBounds(DateTimeFieldType.monthOfYear(), monthOfYear, 1, getMaxMonth(year));
605        FieldUtils.verifyValueBounds(DateTimeFieldType.dayOfMonth(), dayOfMonth, 1, getDaysInYearMonth(year, monthOfYear));
606        return getYearMonthDayMillis(year, monthOfYear, dayOfMonth);
607    }
608 
609    /**
610     * Gets the difference between the two instants in years.
611     * 
612     * @param minuendInstant  the first instant
613     * @param subtrahendInstant  the second instant
614     * @return the difference
615     */
616    abstract long getYearDifference(long minuendInstant, long subtrahendInstant);
617 
618    /**
619     * Is the specified year a leap year?
620     * 
621     * @param year  the year to test
622     * @return true if leap
623     */
624    abstract boolean isLeapYear(int year);
625 
626    /**
627     * Gets the number of days in the specified month and year.
628     * 
629     * @param year  the year
630     * @param month  the month
631     * @return the number of days
632     */
633    abstract int getDaysInYearMonth(int year, int month);
634 
635    /**
636     * Gets the maximum days in the specified month.
637     * 
638     * @param month  the month
639     * @return the max days
640     */
641    abstract int getDaysInMonthMax(int month);
642 
643    /**
644     * Gets the total number of millis elapsed in this year at the start
645     * of the specified month, such as zero for month 1.
646     * 
647     * @param year  the year
648     * @param month  the month
649     * @return the elapsed millis at the start of the month
650     */
651    abstract long getTotalMillisByYearMonth(int year, int month);
652 
653    /**
654     * Gets the millisecond value of the first day of the year.
655     * 
656     * @return the milliseconds for the first of the year
657     */
658    abstract long calculateFirstDayOfYearMillis(int year);
659 
660    /**
661     * Gets the minimum supported year.
662     * 
663     * @return the year
664     */
665    abstract int getMinYear();
666 
667    /**
668     * Gets the maximum supported year.
669     * 
670     * @return the year
671     */
672    abstract int getMaxYear();
673 
674    /**
675     * Gets the maximum month for the specified year.
676     * This implementation calls getMaxMonth().
677     * 
678     * @param year  the year
679     * @return the maximum month value
680     */
681    int getMaxMonth(int year) {
682        return getMaxMonth();
683    }
684 
685    /**
686     * Gets the maximum number of months.
687     * 
688     * @return 12
689     */
690    int getMaxMonth() {
691        return 12;
692    }
693 
694    /**
695     * Gets an average value for the milliseconds per year.
696     * 
697     * @return the millis per year
698     */
699    abstract long getAverageMillisPerYear();
700 
701    /**
702     * Gets an average value for the milliseconds per year, divided by two.
703     * 
704     * @return the millis per year divided by two
705     */
706    abstract long getAverageMillisPerYearDividedByTwo();
707 
708    /**
709     * Gets an average value for the milliseconds per month.
710     * 
711     * @return the millis per month
712     */
713    abstract long getAverageMillisPerMonth();
714 
715    /**
716     * Returns a constant representing the approximate number of milliseconds
717     * elapsed from year 0 of this chronology, divided by two. This constant
718     * <em>must</em> be defined as:
719     * <pre>
720     *    (yearAtEpoch * averageMillisPerYear + millisOfYearAtEpoch) / 2
721     * </pre>
722     * where epoch is 1970-01-01 (Gregorian).
723     */
724    abstract long getApproxMillisAtEpochDividedByTwo();
725 
726    /**
727     * Sets the year from an instant and year.
728     * 
729     * @param instant  millis from 1970-01-01T00:00:00Z
730     * @param year  the year to set
731     * @return the updated millis
732     */
733    abstract long setYear(long instant, int year);
734 
735    //-----------------------------------------------------------------------
736    // Although accessed by multiple threads, this method doesn't need to be synchronized.
737    private YearInfo getYearInfo(int year) {
738        YearInfo info = iYearInfoCache[year & CACHE_MASK];
739        if (info == null || info.iYear != year) {
740            info = new YearInfo(year, calculateFirstDayOfYearMillis(year));
741            iYearInfoCache[year & CACHE_MASK] = info;
742        }
743        return info;
744    }
745 
746    private static class HalfdayField extends PreciseDateTimeField {
747        private static final long serialVersionUID = 581601443656929254L;
748 
749        HalfdayField() {
750            super(DateTimeFieldType.halfdayOfDay(), cHalfdaysField, cDaysField);
751        }
752 
753        public String getAsText(int fieldValue, Locale locale) {
754            return GJLocaleSymbols.forLocale(locale).halfdayValueToText(fieldValue);
755        }
756 
757        public long set(long millis, String text, Locale locale) {
758            return set(millis, GJLocaleSymbols.forLocale(locale).halfdayTextToValue(text));
759        }
760 
761        public int getMaximumTextLength(Locale locale) {
762            return GJLocaleSymbols.forLocale(locale).getHalfdayMaxTextLength();
763        }
764    }
765 
766    private static class YearInfo {
767        public final int iYear;
768        public final long iFirstDayMillis;
769 
770        YearInfo(int year, long firstDayMillis) {
771            iYear = year;
772            iFirstDayMillis = firstDayMillis;
773        }
774    }
775 
776}

[all classes][org.joda.time.chrono]
EMMA 2.0.5312 (C) Vladimir Roubtsov