2 *******************************************************************************
\r
3 * Copyright (C) 1996-2008, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.util;
\r
10 import java.util.Date;
\r
13 * Simple implementation of DateRule.
\r
14 * @draft ICU 2.8 (retainAll)
\r
15 * @provisional This API might change or be removed in a future release.
\r
17 public class SimpleDateRule implements DateRule
\r
20 * Construct a rule for a fixed date within a month
\r
22 * @param month The month in which this rule occurs (0-based).
\r
23 * @param dayOfMonth The date in that month (1-based).
\r
25 * @provisional This API might change or be removed in a future release.
\r
27 public SimpleDateRule(int month, int dayOfMonth)
\r
30 this.dayOfMonth = dayOfMonth;
\r
35 /* package */SimpleDateRule(int month, int dayOfMonth, Calendar cal)
\r
38 this.dayOfMonth = dayOfMonth;
\r
40 this.calendar = cal;
\r
44 * Construct a rule for a weekday within a month, e.g. the first Monday.
\r
46 * @param month The month in which this rule occurs (0-based).
\r
47 * @param dayOfMonth A date within that month (1-based).
\r
48 * @param dayOfWeek The day of the week on which this rule occurs.
\r
49 * @param after If true, this rule selects the first dayOfWeek
\r
50 * on or after dayOfMonth. If false, the rule selects
\r
51 * the first dayOfWeek on or before dayOfMonth.
\r
53 * @provisional This API might change or be removed in a future release.
\r
55 public SimpleDateRule(int month, int dayOfMonth, int dayOfWeek, boolean after)
\r
58 this.dayOfMonth = dayOfMonth;
\r
59 this.dayOfWeek = after ? dayOfWeek : -dayOfWeek;
\r
63 * Return the first occurrance of the event represented by this rule
\r
64 * that is on or after the given start date.
\r
66 * @param start Only occurrances on or after this date are returned.
\r
68 * @return The date on which this event occurs, or null if it
\r
69 * does not occur on or after the start date.
\r
71 * @see #firstBetween
\r
73 * @provisional This API might change or be removed in a future release.
\r
75 public Date firstAfter(Date start)
\r
77 return doFirstBetween(start, null);
\r
81 * Return the first occurrance of the event represented by this rule
\r
82 * that is on or after the given start date and before the given
\r
85 * @param start Only occurrances on or after this date are returned.
\r
86 * @param end Only occurrances before this date are returned.
\r
88 * @return The date on which this event occurs, or null if it
\r
89 * does not occur between the start and end dates.
\r
93 * @provisional This API might change or be removed in a future release.
\r
95 public Date firstBetween(Date start, Date end)
\r
97 // Pin to the min/max dates for this rule
\r
98 return doFirstBetween(start, end);
\r
102 * Checks whether this event occurs on the given date. This does
\r
103 * <em>not</em> take time of day into account; instead it checks
\r
104 * whether this event and the given date are on the same day.
\r
105 * This is useful for applications such as determining whether a given
\r
106 * day is a holiday.
\r
108 * @param date The date to check.
\r
109 * @return true if this event occurs on the given date.
\r
111 * @provisional This API might change or be removed in a future release.
\r
113 public boolean isOn(Date date)
\r
115 Calendar c = calendar;
\r
120 int dayOfYear = c.get(Calendar.DAY_OF_YEAR);
\r
122 c.setTime(computeInYear(c.get(Calendar.YEAR), c));
\r
124 // System.out.println(" isOn: dayOfYear = " + dayOfYear);
\r
125 // System.out.println(" holiday = " + c.get(Calendar.DAY_OF_YEAR));
\r
127 return c.get(Calendar.DAY_OF_YEAR) == dayOfYear;
\r
132 * Check whether this event occurs at least once between the two
\r
135 * @provisional This API might change or be removed in a future release.
\r
137 public boolean isBetween(Date start, Date end)
\r
139 return firstBetween(start, end) != null; // TODO: optimize?
\r
142 private Date doFirstBetween(Date start, Date end)
\r
144 Calendar c = calendar;
\r
149 int year = c.get(Calendar.YEAR);
\r
150 int mon = c.get(Calendar.MONTH);
\r
152 // If the rule is earlier in the year than the start date
\r
153 // we have to go to the next year.
\r
154 if (mon > this.month) {
\r
158 // Figure out when the rule lands in the given year
\r
159 Date result = computeInYear(year, c);
\r
161 // If the rule is in the same month as the start date, it's possible
\r
162 // to get a result that's before the start. If so, go to next year.
\r
163 if (mon == this.month && result.before(start)) {
\r
164 result = computeInYear(year+1, c);
\r
167 if (end != null && result.after(end)) {
\r
174 private Date computeInYear(int year, Calendar c)
\r
178 c.set(Calendar.ERA, c.getMaximum(Calendar.ERA));
\r
179 c.set(Calendar.YEAR, year);
\r
180 c.set(Calendar.MONTH, month);
\r
181 c.set(Calendar.DATE, dayOfMonth);
\r
183 //System.out.println(" computeInYear: start at " + c.getTime().toString());
\r
185 if (dayOfWeek != 0) {
\r
186 c.setTime(c.getTime()); // JDK 1.1.2 workaround
\r
187 int weekday = c.get(Calendar.DAY_OF_WEEK);
\r
189 //System.out.println(" weekday = " + weekday);
\r
190 //System.out.println(" dayOfYear = " + c.get(Calendar.DAY_OF_YEAR));
\r
193 if (dayOfWeek > 0) {
\r
194 // We want the first occurrance of the given day of the week
\r
195 // on or after the specified date in the month.
\r
196 delta = (dayOfWeek - weekday + 7) % 7;
\r
199 // We want the first occurrance of the (-dayOfWeek)
\r
200 // on or before the specified date in the month.
\r
201 delta = -((dayOfWeek + weekday + 7) % 7);
\r
203 //System.out.println(" adding " + delta + " days");
\r
204 c.add(Calendar.DATE, delta);
\r
207 return c.getTime();
\r
213 * @provisional This API might change or be removed in a future release.
\r
215 // public void setCalendar(Calendar c) {
\r
219 private static GregorianCalendar gCalendar = new GregorianCalendar();
\r
221 private Calendar calendar = gCalendar;
\r
224 private int dayOfMonth;
\r
225 private int dayOfWeek;
\r