2 *******************************************************************************
3 * Copyright (C) 1996-2010, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
8 package com.ibm.icu.util;
10 import java.util.Date;
13 * <b>Note:</b> The Holiday framework is a technology preview.
14 * Despite its age, is still draft API, and clients should treat it as such.
16 * Simple implementation of DateRule.
17 * @draft ICU 2.8 (retainAll)
18 * @provisional This API might change or be removed in a future release.
20 public class SimpleDateRule implements DateRule
23 * Construct a rule for a fixed date within a month
25 * @param month The month in which this rule occurs (0-based).
26 * @param dayOfMonth The date in that month (1-based).
28 * @provisional This API might change or be removed in a future release.
30 public SimpleDateRule(int month, int dayOfMonth)
33 this.dayOfMonth = dayOfMonth;
38 /* package */SimpleDateRule(int month, int dayOfMonth, Calendar cal)
41 this.dayOfMonth = dayOfMonth;
47 * Construct a rule for a weekday within a month, e.g. the first Monday.
49 * @param month The month in which this rule occurs (0-based).
50 * @param dayOfMonth A date within that month (1-based).
51 * @param dayOfWeek The day of the week on which this rule occurs.
52 * @param after If true, this rule selects the first dayOfWeek
53 * on or after dayOfMonth. If false, the rule selects
54 * the first dayOfWeek on or before dayOfMonth.
56 * @provisional This API might change or be removed in a future release.
58 public SimpleDateRule(int month, int dayOfMonth, int dayOfWeek, boolean after)
61 this.dayOfMonth = dayOfMonth;
62 this.dayOfWeek = after ? dayOfWeek : -dayOfWeek;
66 * Return the first occurrance of the event represented by this rule
67 * that is on or after the given start date.
69 * @param start Only occurrances on or after this date are returned.
71 * @return The date on which this event occurs, or null if it
72 * does not occur on or after the start date.
76 * @provisional This API might change or be removed in a future release.
78 public Date firstAfter(Date start)
80 return doFirstBetween(start, null);
84 * Return the first occurrance of the event represented by this rule
85 * that is on or after the given start date and before the given
88 * @param start Only occurrances on or after this date are returned.
89 * @param end Only occurrances before this date are returned.
91 * @return The date on which this event occurs, or null if it
92 * does not occur between the start and end dates.
96 * @provisional This API might change or be removed in a future release.
98 public Date firstBetween(Date start, Date end)
100 // Pin to the min/max dates for this rule
101 return doFirstBetween(start, end);
105 * Checks whether this event occurs on the given date. This does
106 * <em>not</em> take time of day into account; instead it checks
107 * whether this event and the given date are on the same day.
108 * This is useful for applications such as determining whether a given
111 * @param date The date to check.
112 * @return true if this event occurs on the given date.
114 * @provisional This API might change or be removed in a future release.
116 public boolean isOn(Date date)
118 Calendar c = calendar;
123 int dayOfYear = c.get(Calendar.DAY_OF_YEAR);
125 c.setTime(computeInYear(c.get(Calendar.YEAR), c));
127 // System.out.println(" isOn: dayOfYear = " + dayOfYear);
128 // System.out.println(" holiday = " + c.get(Calendar.DAY_OF_YEAR));
130 return c.get(Calendar.DAY_OF_YEAR) == dayOfYear;
135 * Check whether this event occurs at least once between the two
138 * @provisional This API might change or be removed in a future release.
140 public boolean isBetween(Date start, Date end)
142 return firstBetween(start, end) != null; // TODO: optimize?
145 private Date doFirstBetween(Date start, Date end)
147 Calendar c = calendar;
152 int year = c.get(Calendar.YEAR);
153 int mon = c.get(Calendar.MONTH);
155 // If the rule is earlier in the year than the start date
156 // we have to go to the next year.
157 if (mon > this.month) {
161 // Figure out when the rule lands in the given year
162 Date result = computeInYear(year, c);
164 // If the rule is in the same month as the start date, it's possible
165 // to get a result that's before the start. If so, go to next year.
166 if (mon == this.month && result.before(start)) {
167 result = computeInYear(year+1, c);
170 if (end != null && result.after(end)) {
177 private Date computeInYear(int year, Calendar c)
181 c.set(Calendar.ERA, c.getMaximum(Calendar.ERA));
182 c.set(Calendar.YEAR, year);
183 c.set(Calendar.MONTH, month);
184 c.set(Calendar.DATE, dayOfMonth);
186 //System.out.println(" computeInYear: start at " + c.getTime().toString());
188 if (dayOfWeek != 0) {
189 c.setTime(c.getTime()); // JDK 1.1.2 workaround
190 int weekday = c.get(Calendar.DAY_OF_WEEK);
192 //System.out.println(" weekday = " + weekday);
193 //System.out.println(" dayOfYear = " + c.get(Calendar.DAY_OF_YEAR));
197 // We want the first occurrance of the given day of the week
198 // on or after the specified date in the month.
199 delta = (dayOfWeek - weekday + 7) % 7;
202 // We want the first occurrance of the (-dayOfWeek)
203 // on or before the specified date in the month.
204 delta = -((dayOfWeek + weekday + 7) % 7);
206 //System.out.println(" adding " + delta + " days");
207 c.add(Calendar.DATE, delta);
216 * @provisional This API might change or be removed in a future release.
218 // public void setCalendar(Calendar c) {
222 private static GregorianCalendar gCalendar = new GregorianCalendar();
224 private Calendar calendar = gCalendar;
227 private int dayOfMonth;
228 private int dayOfWeek;