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