1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.validator.routines;
18
19 import java.text.DateFormat;
20 import java.text.Format;
21 import java.util.Calendar;
22 import java.util.Locale;
23 import java.util.TimeZone;
24
25 /***
26 * <p><b>Calendar Validation</b> and Conversion routines (<code>java.util.Calendar</code>).</p>
27 *
28 * <p>This validator provides a number of methods for validating/converting
29 * a <code>String</code> date value to a <code>java.util.Calendar</code> using
30 * <code>java.text.DateFormat</code> to parse either:</p>
31 * <ul>
32 * <li>using the default format for the default <code>Locale</code></li>
33 * <li>using a specified pattern with the default <code>Locale</code></li>
34 * <li>using the default format for a specified <code>Locale</code></li>
35 * <li>using a specified pattern with a specified <code>Locale</code></li>
36 * </ul>
37 *
38 * <p>For each of the above mechanisms, conversion method (i.e the
39 * <code>validate</code> methods) implementations are provided which
40 * either use the default <code>TimeZone</code> or allow the
41 * <code>TimeZone</code> to be specified.</p>
42 *
43 * <p>Use one of the <code>isValid()</code> methods to just validate or
44 * one of the <code>validate()</code> methods to validate and receive a
45 * <i>converted</i> <code>Calendar</code> value.</p>
46 *
47 * <p>Implementations of the <code>validate()</code> method are provided
48 * to create <code>Calendar</code> objects for different <i>time zones</i>
49 * if the system default is not appropriate.</p>
50 *
51 * <p>Alternatively the CalendarValidator's <code>adjustToTimeZone()</code> method
52 * can be used to adjust the <code>TimeZone</code> of the <code>Calendar</code>
53 * object afterwards.</p>
54 *
55 * <p>Once a value has been sucessfully converted the following
56 * methods can be used to perform various date comparison checks:</p>
57 * <ul>
58 * <li><code>compareDates()</code> compares the day, month and
59 * year of two calendars, returing 0, -1 or +1 indicating
60 * whether the first date is equal, before or after the second.</li>
61 * <li><code>compareWeeks()</code> compares the week and
62 * year of two calendars, returing 0, -1 or +1 indicating
63 * whether the first week is equal, before or after the second.</li>
64 * <li><code>compareMonths()</code> compares the month and
65 * year of two calendars, returing 0, -1 or +1 indicating
66 * whether the first month is equal, before or after the second.</li>
67 * <li><code>compareQuarters()</code> compares the quarter and
68 * year of two calendars, returing 0, -1 or +1 indicating
69 * whether the first quarter is equal, before or after the second.</li>
70 * <li><code>compareYears()</code> compares the
71 * year of two calendars, returing 0, -1 or +1 indicating
72 * whether the first year is equal, before or after the second.</li>
73 * </ul>
74 *
75 * <p>So that the same mechanism used for parsing an <i>input</i> value
76 * for validation can be used to format <i>output</i>, corresponding
77 * <code>format()</code> methods are also provided. That is you can
78 * format either:</p>
79 * <ul>
80 * <li>using a specified pattern</li>
81 * <li>using the format for a specified <code>Locale</code></li>
82 * <li>using the format for the <i>default</i> <code>Locale</code></li>
83 * </ul>
84 *
85 * @version $Revision: 478334 $ $Date: 2006-11-22 21:31:54 +0000 (Wed, 22 Nov 2006) $
86 * @since Validator 1.3.0
87 */
88 public class CalendarValidator extends AbstractCalendarValidator {
89
90 private static final CalendarValidator VALIDATOR = new CalendarValidator();
91
92 /***
93 * Return a singleton instance of this validator.
94 * @return A singleton instance of the CalendarValidator.
95 */
96 public static CalendarValidator getInstance() {
97 return VALIDATOR;
98 }
99
100 /***
101 * Construct a <i>strict</i> instance with <i>short</i>
102 * date style.
103 */
104 public CalendarValidator() {
105 this(true, DateFormat.SHORT);
106 }
107
108 /***
109 * Construct an instance with the specified <i>strict</i>
110 * and <i>date style</i> parameters.
111 *
112 * @param strict <code>true</code> if strict
113 * <code>Format</code> parsing should be used.
114 * @param dateStyle the date style to use for Locale validation.
115 */
116 public CalendarValidator(boolean strict, int dateStyle) {
117 super(strict, dateStyle, -1);
118 }
119
120 /***
121 * <p>Validate/convert a <code>Calendar</code> using the default
122 * <code>Locale</code> and <code>TimeZone</code>.
123 *
124 * @param value The value validation is being performed on.
125 * @return The parsed <code>Calendar</code> if valid or <code>null</code>
126 * if invalid.
127 */
128 public Calendar validate(String value) {
129 return (Calendar)parse(value, (String)null, (Locale)null, (TimeZone)null);
130 }
131
132 /***
133 * <p>Validate/convert a <code>Calendar</code> using the specified
134 * <code>TimeZone</code> and default <code>Locale</code>.
135 *
136 * @param value The value validation is being performed on.
137 * @param timeZone The Time Zone used to parse the date, system default if null.
138 * @return The parsed <code>Calendar</code> if valid or <code>null</code>
139 * if invalid.
140 */
141 public Calendar validate(String value, TimeZone timeZone) {
142 return (Calendar)parse(value, (String)null, (Locale)null, timeZone);
143 }
144
145 /***
146 * <p>Validate/convert a <code>Calendar</code> using the specified
147 * <i>pattern</i> and default <code>TimeZone</code>.
148 *
149 * @param value The value validation is being performed on.
150 * @param pattern The pattern used to validate the value against.
151 * @return The parsed <code>Calendar</code> if valid or <code>null</code> if invalid.
152 */
153 public Calendar validate(String value, String pattern) {
154 return (Calendar)parse(value, pattern, (Locale)null, (TimeZone)null);
155 }
156
157 /***
158 * <p>Validate/convert a <code>Calendar</code> using the specified
159 * <i>pattern</i> and <code>TimeZone</code>.
160 *
161 * @param value The value validation is being performed on.
162 * @param pattern The pattern used to validate the value against.
163 * @param timeZone The Time Zone used to parse the date, system default if null.
164 * @return The parsed <code>Calendar</code> if valid or <code>null</code> if invalid.
165 */
166 public Calendar validate(String value, String pattern, TimeZone timeZone) {
167 return (Calendar)parse(value, pattern, (Locale)null, timeZone);
168 }
169
170 /***
171 * <p>Validate/convert a <code>Calendar</code> using the specified
172 * <code>Locale</code> and default <code>TimeZone</code>.
173 *
174 * @param value The value validation is being performed on.
175 * @param locale The locale to use for the date format, system default if null.
176 * @return The parsed <code>Calendar</code> if valid or <code>null</code> if invalid.
177 */
178 public Calendar validate(String value, Locale locale) {
179 return (Calendar)parse(value, (String)null, locale, (TimeZone)null);
180 }
181
182 /***
183 * <p>Validate/convert a <code>Calendar</code> using the specified
184 * <code>Locale</code> and <code>TimeZone</code>.
185 *
186 * @param value The value validation is being performed on.
187 * @param locale The locale to use for the date format, system default if null.
188 * @param timeZone The Time Zone used to parse the date, system default if null.
189 * @return The parsed <code>Calendar</code> if valid or <code>null</code> if invalid.
190 */
191 public Calendar validate(String value, Locale locale, TimeZone timeZone) {
192 return (Calendar)parse(value, (String)null, locale, timeZone);
193 }
194
195 /***
196 * <p>Validate/convert a <code>Calendar</code> using the specified pattern
197 * and <code>Locale</code> and the default <code>TimeZone</code>.
198 *
199 * @param value The value validation is being performed on.
200 * @param pattern The pattern used to validate the value against, or the
201 * default for the <code>Locale</code> if <code>null</code>.
202 * @param locale The locale to use for the date format, system default if null.
203 * @return The parsed <code>Calendar</code> if valid or <code>null</code> if invalid.
204 */
205 public Calendar validate(String value, String pattern, Locale locale) {
206 return (Calendar)parse(value, pattern, locale, (TimeZone)null);
207 }
208
209 /***
210 * <p>Validate/convert a <code>Calendar</code> using the specified
211 * pattern, and <code>Locale</code> and <code>TimeZone</code>.
212 *
213 * @param value The value validation is being performed on.
214 * @param pattern The pattern used to validate the value against, or the
215 * default for the <code>Locale</code> if <code>null</code>.
216 * @param locale The locale to use for the date format, system default if null.
217 * @param timeZone The Time Zone used to parse the date, system default if null.
218 * @return The parsed <code>Calendar</code> if valid or <code>null</code> if invalid.
219 */
220 public Calendar validate(String value, String pattern, Locale locale, TimeZone timeZone) {
221 return (Calendar)parse(value, pattern, locale, timeZone);
222 }
223
224 /***
225 * <p>Adjusts a Calendar's value to a different TimeZone.</p>
226 *
227 * @param value The value to adjust.
228 * @param timeZone The new time zone to use to adjust the Calendar to.
229 */
230 public static void adjustToTimeZone(Calendar value, TimeZone timeZone) {
231 if (value.getTimeZone().hasSameRules(timeZone)) {
232 value.setTimeZone(timeZone);
233 } else {
234 int year = value.get(Calendar.YEAR);
235 int month = value.get(Calendar.MONTH);
236 int date = value.get(Calendar.DATE);
237 int hour = value.get(Calendar.HOUR_OF_DAY);
238 int minute = value.get(Calendar.MINUTE);
239 value.setTimeZone(timeZone);
240 value.set(year, month, date, hour, minute);
241 }
242 }
243
244 /***
245 * <p>Compare Dates (day, month and year - not time).</p>
246 *
247 * @param value The <code>Calendar</code> value to check.
248 * @param compare The <code>Calendar</code> to compare the value to.
249 * @return Zero if the dates are equal, -1 if first
250 * date is less than the seconds and +1 if the first
251 * date is greater than.
252 */
253 public int compareDates(Calendar value, Calendar compare) {
254 return compare(value, compare, Calendar.DATE);
255 }
256
257 /***
258 * <p>Compare Weeks (week and year).</p>
259 *
260 * @param value The <code>Calendar</code> value to check.
261 * @param compare The <code>Calendar</code> to compare the value to.
262 * @return Zero if the weeks are equal, -1 if first
263 * parameter's week is less than the seconds and +1 if the first
264 * parameter's week is greater than.
265 */
266 public int compareWeeks(Calendar value, Calendar compare) {
267 return compare(value, compare, Calendar.WEEK_OF_YEAR);
268 }
269
270 /***
271 * <p>Compare Months (month and year).</p>
272 *
273 * @param value The <code>Calendar</code> value to check.
274 * @param compare The <code>Calendar</code> to compare the value to.
275 * @return Zero if the months are equal, -1 if first
276 * parameter's month is less than the seconds and +1 if the first
277 * parameter's month is greater than.
278 */
279 public int compareMonths(Calendar value, Calendar compare) {
280 return compare(value, compare, Calendar.MONTH);
281 }
282
283 /***
284 * <p>Compare Quarters (quarter and year).</p>
285 *
286 * @param value The <code>Calendar</code> value to check.
287 * @param compare The <code>Calendar</code> to check the value against.
288 * @return Zero if the quarters are equal, -1 if first
289 * parameter's quarter is less than the seconds and +1 if the first
290 * parameter's quarter is greater than.
291 */
292 public int compareQuarters(Calendar value, Calendar compare) {
293 return compareQuarters(value, compare, 1);
294 }
295
296 /***
297 * <p>Compare Quarters (quarter and year).</p>
298 *
299 * @param value The <code>Calendar</code> value to check.
300 * @param compare The <code>Calendar</code> to compare the value to.
301 * @param monthOfFirstQuarter The month that the first quarter starts.
302 * @return Zero if the quarters are equal, -1 if first
303 * parameter's quarter is less than the seconds and +1 if the first
304 * parameter's quarter is greater than.
305 */
306 public int compareQuarters(Calendar value, Calendar compare, int monthOfFirstQuarter) {
307 return super.compareQuarters(value, compare, monthOfFirstQuarter);
308 }
309
310 /***
311 * <p>Compare Years.</p>
312 *
313 * @param value The <code>Calendar</code> value to check.
314 * @param compare The <code>Calendar</code> to compare the value to.
315 * @return Zero if the years are equal, -1 if first
316 * parameter's year is less than the seconds and +1 if the first
317 * parameter's year is greater than.
318 */
319 public int compareYears(Calendar value, Calendar compare) {
320 return compare(value, compare, Calendar.YEAR);
321 }
322
323 /***
324 * <p>Convert the parsed <code>Date</code> to a <code>Calendar</code>.</p>
325 *
326 * @param value The parsed <code>Date</code> object created.
327 * @param formatter The Format used to parse the value with.
328 * @return The parsed value converted to a <code>Calendar</code>.
329 */
330 protected Object processParsedValue(Object value, Format formatter) {
331 return ((DateFormat)formatter).getCalendar();
332 }
333
334 }