KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ibm > icu > util > SimpleDateRule


1 /*
2  *******************************************************************************
3  * Copyright (C) 1996-2006, International Business Machines Corporation and *
4  * others. All Rights Reserved. *
5  *******************************************************************************
6  */

7
8 package com.ibm.icu.util;
9
10 import java.util.Date JavaDoc;
11
12 /**
13  * Simple implementation of DateRule.
14  * @draft ICU 2.8 (retainAll)
15  * @provisional This API might change or be removed in a future release.
16  */

17 public class SimpleDateRule implements DateRule
18 {
19     /**
20      * Construct a rule for a fixed date within a month
21      *
22      * @param month The month in which this rule occurs (0-based).
23      * @param dayOfMonth The date in that month (1-based).
24      * @draft ICU 2.8
25      * @provisional This API might change or be removed in a future release.
26      */

27     public SimpleDateRule(int month, int dayOfMonth)
28     {
29         this.month = month;
30         this.dayOfMonth = dayOfMonth;
31         this.dayOfWeek = 0;
32     }
33
34     // temporary
35
/* package */SimpleDateRule(int month, int dayOfMonth, Calendar cal)
36     {
37         this.month = month;
38         this.dayOfMonth = dayOfMonth;
39         this.dayOfWeek = 0;
40         this.calendar = cal;
41     }
42
43     /**
44      * Construct a rule for a weekday within a month, e.g. the first Monday.
45      *
46      * @param month The month in which this rule occurs (0-based).
47      * @param dayOfMonth A date within that month (1-based).
48      * @param dayOfWeek The day of the week on which this rule occurs.
49      * @param after If true, this rule selects the first dayOfWeek
50      * on or after dayOfMonth. If false, the rule selects
51      * the first dayOfWeek on or before dayOfMonth.
52      * @draft ICU 2.8
53      * @provisional This API might change or be removed in a future release.
54      */

55     public SimpleDateRule(int month, int dayOfMonth, int dayOfWeek, boolean after)
56     {
57         this.month = month;
58         this.dayOfMonth = dayOfMonth;
59         this.dayOfWeek = after ? dayOfWeek : -dayOfWeek;
60     }
61
62     /**
63      * Return the first occurrance of the event represented by this rule
64      * that is on or after the given start date.
65      *
66      * @param start Only occurrances on or after this date are returned.
67      *
68      * @return The date on which this event occurs, or null if it
69      * does not occur on or after the start date.
70      *
71      * @see #firstBetween
72      * @draft ICU 2.8
73      * @provisional This API might change or be removed in a future release.
74      */

75     public Date JavaDoc firstAfter(Date JavaDoc start)
76     {
77         return doFirstBetween(start, null);
78     }
79
80     /**
81      * Return the first occurrance of the event represented by this rule
82      * that is on or after the given start date and before the given
83      * end date.
84      *
85      * @param start Only occurrances on or after this date are returned.
86      * @param end Only occurrances before this date are returned.
87      *
88      * @return The date on which this event occurs, or null if it
89      * does not occur between the start and end dates.
90      *
91      * @see #firstAfter
92      * @draft ICU 2.8
93      * @provisional This API might change or be removed in a future release.
94      */

95     public Date JavaDoc firstBetween(Date JavaDoc start, Date JavaDoc end)
96     {
97         // Pin to the min/max dates for this rule
98
return doFirstBetween(start, end);
99     }
100
101     /**
102      * Checks whether this event occurs on the given date. This does
103      * <em>not</em> take time of day into account; instead it checks
104      * whether this event and the given date are on the same day.
105      * This is useful for applications such as determining whether a given
106      * day is a holiday.
107      *
108      * @param date The date to check.
109      * @return true if this event occurs on the given date.
110      * @draft ICU 2.8
111      * @provisional This API might change or be removed in a future release.
112      */

113     public boolean isOn(Date JavaDoc date)
114     {
115         Calendar c = calendar;
116
117         synchronized(c) {
118             c.setTime(date);
119
120             int dayOfYear = c.get(Calendar.DAY_OF_YEAR);
121
122             c.setTime(computeInYear(c.get(Calendar.YEAR), c));
123
124 // System.out.println(" isOn: dayOfYear = " + dayOfYear);
125
// System.out.println(" holiday = " + c.get(Calendar.DAY_OF_YEAR));
126

127             return c.get(Calendar.DAY_OF_YEAR) == dayOfYear;
128         }
129     }
130
131     /**
132      * Check whether this event occurs at least once between the two
133      * dates given.
134      * @draft ICU 2.8
135      * @provisional This API might change or be removed in a future release.
136      */

137     public boolean isBetween(Date JavaDoc start, Date JavaDoc end)
138     {
139         return firstBetween(start, end) != null; // TODO: optimize?
140
}
141
142     private Date JavaDoc doFirstBetween(Date JavaDoc start, Date JavaDoc end)
143     {
144         Calendar c = calendar;
145
146         synchronized(c) {
147             c.setTime(start);
148
149             int year = c.get(Calendar.YEAR);
150             int month = c.get(Calendar.MONTH);
151
152             // If the rule is earlier in the year than the start date
153
// we have to go to the next year.
154
if (month > this.month) {
155                 year++;
156             }
157
158             // Figure out when the rule lands in the given year
159
Date JavaDoc result = computeInYear(year, c);
160
161             // If the rule is in the same month as the start date, it's possible
162
// to get a result that's before the start. If so, go to next year.
163
if (month == this.month && result.before(start)) {
164                 result = computeInYear(year+1, c);
165             }
166
167             if (end != null && result.after(end)) {
168                 return null;
169             }
170             return result;
171         }
172     }
173
174     private Date JavaDoc computeInYear(int year, Calendar c)
175     {
176         synchronized(c) {
177             c.clear();
178             c.set(Calendar.ERA, c.getMaximum(Calendar.ERA));
179             c.set(Calendar.YEAR, year);
180             c.set(Calendar.MONTH, month);
181             c.set(Calendar.DATE, dayOfMonth);
182
183             //System.out.println(" computeInYear: start at " + c.getTime().toString());
184

185             if (dayOfWeek != 0) {
186                 c.setTime(c.getTime()); // JDK 1.1.2 workaround
187
int weekday = c.get(Calendar.DAY_OF_WEEK);
188
189                 //System.out.println(" weekday = " + weekday);
190
//System.out.println(" dayOfYear = " + c.get(Calendar.DAY_OF_YEAR));
191

192                 int delta = 0;
193                 if (dayOfWeek > 0) {
194                     // We want the first occurrance of the given day of the week
195
// on or after the specified date in the month.
196
delta = (dayOfWeek - weekday + 7) % 7;
197                 }
198                 else {
199                     // We want the first occurrance of the (-dayOfWeek)
200
// on or before the specified date in the month.
201
delta = -((dayOfWeek + weekday + 7) % 7);
202                 }
203                 //System.out.println(" adding " + delta + " days");
204
c.add(Calendar.DATE, delta);
205             }
206
207             return c.getTime();
208         }
209     }
210
211     /**
212      * @draft ICU 2.8
213      * @provisional This API might change or be removed in a future release.
214      */

215 // public void setCalendar(Calendar c) {
216
// calendar = c;
217
// }
218

219     private static GregorianCalendar gCalendar = new GregorianCalendar();
220
221     private Calendar calendar = gCalendar;
222
223     private int month;
224     private int dayOfMonth;
225     private int dayOfWeek;
226 };
227
Popular Tags