KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.joda.time.Chronology;
19 import org.joda.time.DateTimeConstants;
20
21 /**
22  * Abstract Chronology for implementing chronologies based on Gregorian/Julian formulae.
23  * Most of the utility methods required by subclasses are package-private,
24  * reflecting the intention that they be defined in the same package.
25  * <p>
26  * BasicGJChronology is thread-safe and immutable, and all subclasses must
27  * be as well.
28  *
29  * @author Stephen Colebourne
30  * @author Brian S O'Neill
31  * @author Guy Allard
32  * @since 1.2, refactored from CommonGJChronology
33  */

34 abstract class BasicGJChronology extends BasicChronology {
35
36     /** Serialization lock */
37     private static final long serialVersionUID = 538276888268L;
38
39     // These arrays are NOT public. We trust ourselves not to alter the array.
40
// They use zero-based array indexes so the that valid range of months is
41
// automatically checked.
42
private static final int[] MIN_DAYS_PER_MONTH_ARRAY = {
43         31,28,31,30,31,30,31,31,30,31,30,31
44     };
45     private static final int[] MAX_DAYS_PER_MONTH_ARRAY = {
46         31,29,31,30,31,30,31,31,30,31,30,31
47     };
48     private static final long[] MIN_TOTAL_MILLIS_BY_MONTH_ARRAY;
49     private static final long[] MAX_TOTAL_MILLIS_BY_MONTH_ARRAY;
50     private static final long FEB_29 = (31L + 29 - 1) * DateTimeConstants.MILLIS_PER_DAY;
51
52     static {
53         MIN_TOTAL_MILLIS_BY_MONTH_ARRAY = new long[12];
54         MAX_TOTAL_MILLIS_BY_MONTH_ARRAY = new long[12];
55
56         long minSum = 0;
57         long maxSum = 0;
58         for (int i = 0; i < 11; i++) {
59             long millis = MIN_DAYS_PER_MONTH_ARRAY[i]
60                 * (long)DateTimeConstants.MILLIS_PER_DAY;
61             minSum += millis;
62             MIN_TOTAL_MILLIS_BY_MONTH_ARRAY[i + 1] = minSum;
63
64             millis = MAX_DAYS_PER_MONTH_ARRAY[i]
65                 * (long)DateTimeConstants.MILLIS_PER_DAY;
66             maxSum += millis;
67             MAX_TOTAL_MILLIS_BY_MONTH_ARRAY[i + 1] = maxSum;
68         }
69     }
70
71     /**
72      * Constructor.
73      */

74     BasicGJChronology(Chronology base, Object JavaDoc param, int minDaysInFirstWeek) {
75         super(base, param, minDaysInFirstWeek);
76     }
77
78     //-----------------------------------------------------------------------
79
int getMonthOfYear(long millis, int year) {
80         // Perform a binary search to get the month. To make it go even faster,
81
// compare using ints instead of longs. The number of milliseconds per
82
// year exceeds the limit of a 32-bit int's capacity, so divide by
83
// 1024. No precision is lost (except time of day) since the number of
84
// milliseconds per day contains 1024 as a factor. After the division,
85
// the instant isn't measured in milliseconds, but in units of
86
// (128/125)seconds.
87

88         int i = (int)((millis - getYearMillis(year)) >> 10);
89
90         // There are 86400000 milliseconds per day, but divided by 1024 is
91
// 84375. There are 84375 (128/125)seconds per day.
92

93         return
94             (isLeapYear(year))
95             ? ((i < 182 * 84375)
96                ? ((i < 91 * 84375)
97                   ? ((i < 31 * 84375) ? 1 : (i < 60 * 84375) ? 2 : 3)
98                   : ((i < 121 * 84375) ? 4 : (i < 152 * 84375) ? 5 : 6))
99                : ((i < 274 * 84375)
100                   ? ((i < 213 * 84375) ? 7 : (i < 244 * 84375) ? 8 : 9)
101                   : ((i < 305 * 84375) ? 10 : (i < 335 * 84375) ? 11 : 12)))
102             : ((i < 181 * 84375)
103                ? ((i < 90 * 84375)
104                   ? ((i < 31 * 84375) ? 1 : (i < 59 * 84375) ? 2 : 3)
105                   : ((i < 120 * 84375) ? 4 : (i < 151 * 84375) ? 5 : 6))
106                : ((i < 273 * 84375)
107                   ? ((i < 212 * 84375) ? 7 : (i < 243 * 84375) ? 8 : 9)
108                   : ((i < 304 * 84375) ? 10 : (i < 334 * 84375) ? 11 : 12)));
109     }
110
111     //-----------------------------------------------------------------------
112
/**
113      * Gets the number of days in the specified month and year.
114      *
115      * @param year the year
116      * @param month the month
117      * @return the number of days
118      */

119     int getDaysInYearMonth(int year, int month) {
120         if (isLeapYear(year)) {
121             return MAX_DAYS_PER_MONTH_ARRAY[month - 1];
122         } else {
123             return MIN_DAYS_PER_MONTH_ARRAY[month - 1];
124         }
125     }
126
127     //-----------------------------------------------------------------------
128
int getDaysInMonthMax(int month) {
129         return MAX_DAYS_PER_MONTH_ARRAY[month - 1];
130     }
131
132     //-----------------------------------------------------------------------
133
int getDaysInMonthMaxForSet(long instant, int value) {
134         return (value > 28 ? getDaysInMonthMax(instant) : 28);
135     }
136
137     //-----------------------------------------------------------------------
138
long getTotalMillisByYearMonth(int year, int month) {
139         if (isLeapYear(year)) {
140             return MAX_TOTAL_MILLIS_BY_MONTH_ARRAY[month - 1];
141         } else {
142             return MIN_TOTAL_MILLIS_BY_MONTH_ARRAY[month - 1];
143         }
144     }
145
146     //-----------------------------------------------------------------------
147
long getYearDifference(long minuendInstant, long subtrahendInstant) {
148         int minuendYear = getYear(minuendInstant);
149         int subtrahendYear = getYear(subtrahendInstant);
150     
151         // Inlined remainder method to avoid duplicate calls to get.
152
long minuendRem = minuendInstant - getYearMillis(minuendYear);
153         long subtrahendRem = subtrahendInstant - getYearMillis(subtrahendYear);
154     
155         // Balance leap year differences on remainders.
156
if (subtrahendRem >= FEB_29) {
157             if (isLeapYear(subtrahendYear)) {
158                 if (!isLeapYear(minuendYear)) {
159                     subtrahendRem -= DateTimeConstants.MILLIS_PER_DAY;
160                 }
161             } else if (minuendRem >= FEB_29 && isLeapYear(minuendYear)) {
162                 minuendRem -= DateTimeConstants.MILLIS_PER_DAY;
163             }
164         }
165     
166         int difference = minuendYear - subtrahendYear;
167         if (minuendRem < subtrahendRem) {
168             difference--;
169         }
170         return difference;
171     }
172
173     //-----------------------------------------------------------------------
174
long setYear(long instant, int year) {
175         int thisYear = getYear(instant);
176         int dayOfYear = getDayOfYear(instant, thisYear);
177         int millisOfDay = getMillisOfDay(instant);
178
179         if (dayOfYear > (31 + 28)) { // after Feb 28
180
if (isLeapYear(thisYear)) {
181                 // Current date is Feb 29 or later.
182
if (!isLeapYear(year)) {
183                     // Moving to a non-leap year, Feb 29 does not exist.
184
dayOfYear--;
185                 }
186             } else {
187                 // Current date is Mar 01 or later.
188
if (isLeapYear(year)) {
189                     // Moving to a leap year, account for Feb 29.
190
dayOfYear++;
191                 }
192             }
193         }
194
195         instant = getYearMonthDayMillis(year, 1, dayOfYear);
196         instant += millisOfDay;
197
198         return instant;
199     }
200
201 }
202
Popular Tags