001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.validator.routines;
018:
019: import java.text.DateFormat;
020: import java.text.Format;
021: import java.util.Calendar;
022: import java.util.Date;
023: import java.util.Locale;
024: import java.util.TimeZone;
025:
026: /**
027: * <p><b>Date Validation</b> and Conversion routines (<code>java.util.Date</code>).</p>
028: *
029: * <p>This validator provides a number of methods for validating/converting
030: * a <code>String</code> date value to a <code>java.util.Date</code> using
031: * <code>java.text.DateFormat</code> to parse either:</p>
032: * <ul>
033: * <li>using the default format for the default <code>Locale</code></li>
034: * <li>using a specified pattern with the default <code>Locale</code></li>
035: * <li>using the default format for a specified <code>Locale</code></li>
036: * <li>using a specified pattern with a specified <code>Locale</code></li>
037: * </ul>
038: *
039: * <p>For each of the above mechanisms, conversion method (i.e the
040: * <code>validate</code> methods) implementations are provided which
041: * either use the default <code>TimeZone</code> or allow the
042: * <code>TimeZone</code> to be specified.</p>
043: *
044: * <p>Use one of the <code>isValid()</code> methods to just validate or
045: * one of the <code>validate()</code> methods to validate and receive a
046: * <i>converted</i> <code>Date</code> value.</p>
047: *
048: * <p>Implementations of the <code>validate()</code> method are provided
049: * to create <code>Date</code> objects for different <i>time zones</i>
050: * if the system default is not appropriate.</p>
051: *
052: * <p>Once a value has been sucessfully converted the following
053: * methods can be used to perform various date comparison checks:</p>
054: * <ul>
055: * <li><code>compareDates()</code> compares the day, month and
056: * year of two dates, returing 0, -1 or +1 indicating
057: * whether the first date is equal, before or after the second.</li>
058: * <li><code>compareWeeks()</code> compares the week and
059: * year of two dates, returing 0, -1 or +1 indicating
060: * whether the first week is equal, before or after the second.</li>
061: * <li><code>compareMonths()</code> compares the month and
062: * year of two dates, returing 0, -1 or +1 indicating
063: * whether the first month is equal, before or after the second.</li>
064: * <li><code>compareQuarters()</code> compares the quarter and
065: * year of two dates, returing 0, -1 or +1 indicating
066: * whether the first quarter is equal, before or after the second.</li>
067: * <li><code>compareYears()</code> compares the
068: * year of two dates, returing 0, -1 or +1 indicating
069: * whether the first year is equal, before or after the second.</li>
070: * </ul>
071: *
072: * <p>So that the same mechanism used for parsing an <i>input</i> value
073: * for validation can be used to format <i>output</i>, corresponding
074: * <code>format()</code> methods are also provided. That is you can
075: * format either:</p>
076: * <ul>
077: * <li>using a specified pattern</li>
078: * <li>using the format for a specified <code>Locale</code></li>
079: * <li>using the format for the <i>default</i> <code>Locale</code></li>
080: * </ul>
081: *
082: * @version $Revision: 478334 $ $Date: 2006-11-22 21:31:54 +0000 (Wed, 22 Nov 2006) $
083: * @since Validator 1.3.0
084: */
085: public class DateValidator extends AbstractCalendarValidator {
086:
087: private static final DateValidator VALIDATOR = new DateValidator();
088:
089: /**
090: * Return a singleton instance of this validator.
091: * @return A singleton instance of the DateValidator.
092: */
093: public static DateValidator getInstance() {
094: return VALIDATOR;
095: }
096:
097: /**
098: * Construct a <i>strict</i> instance with <i>short</i>
099: * date style.
100: */
101: public DateValidator() {
102: this (true, DateFormat.SHORT);
103: }
104:
105: /**
106: * Construct an instance with the specified <i>strict</i>
107: * and <i>date style</i> parameters.
108: *
109: * @param strict <code>true</code> if strict
110: * <code>Format</code> parsing should be used.
111: * @param dateStyle the date style to use for Locale validation.
112: */
113: public DateValidator(boolean strict, int dateStyle) {
114: super (strict, dateStyle, -1);
115: }
116:
117: /**
118: * <p>Validate/convert a <code>Date</code> using the default
119: * <code>Locale</code> and <code>TimeZone</code>.
120: *
121: * @param value The value validation is being performed on.
122: * @return The parsed <code>Date</code> if valid or <code>null</code>
123: * if invalid.
124: */
125: public Date validate(String value) {
126: return (Date) parse(value, (String) null, (Locale) null,
127: (TimeZone) null);
128: }
129:
130: /**
131: * <p>Validate/convert a <code>Date</code> using the specified
132: * <code>TimeZone</code> and default <code>Locale</code>.
133: *
134: * @param value The value validation is being performed on.
135: * @param timeZone The Time Zone used to parse the date, system default if null.
136: * @return The parsed <code>Date</code> if valid or <code>null</code> if invalid.
137: */
138: public Date validate(String value, TimeZone timeZone) {
139: return (Date) parse(value, (String) null, (Locale) null,
140: timeZone);
141: }
142:
143: /**
144: * <p>Validate/convert a <code>Date</code> using the specified
145: * <i>pattern</i> and default <code>TimeZone</code>.
146: *
147: * @param value The value validation is being performed on.
148: * @param pattern The pattern used to validate the value against, or the
149: * default for the <code>Locale</code> if <code>null</code>.
150: * @return The parsed <code>Date</code> if valid or <code>null</code> if invalid.
151: */
152: public Date validate(String value, String pattern) {
153: return (Date) parse(value, pattern, (Locale) null,
154: (TimeZone) null);
155: }
156:
157: /**
158: * <p>Validate/convert a <code>Date</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, or the
163: * default for the <code>Locale</code> if <code>null</code>.
164: * @param timeZone The Time Zone used to parse the date, system default if null.
165: * @return The parsed <code>Date</code> if valid or <code>null</code> if invalid.
166: */
167: public Date validate(String value, String pattern, TimeZone timeZone) {
168: return (Date) parse(value, pattern, (Locale) null, timeZone);
169: }
170:
171: /**
172: * <p>Validate/convert a <code>Date</code> using the specified
173: * <code>Locale</code> and default <code>TimeZone</code>.
174: *
175: * @param value The value validation is being performed on.
176: * @param locale The locale to use for the date format, system default if null.
177: * @return The parsed <code>Date</code> if valid or <code>null</code> if invalid.
178: */
179: public Date validate(String value, Locale locale) {
180: return (Date) parse(value, (String) null, locale,
181: (TimeZone) null);
182: }
183:
184: /**
185: * <p>Validate/convert a <code>Date</code> using the specified
186: * <code>Locale</code> and <code>TimeZone</code>.
187: *
188: * @param value The value validation is being performed on.
189: * @param locale The locale to use for the date format, system default if null.
190: * @param timeZone The Time Zone used to parse the date, system default if null.
191: * @return The parsed <code>Date</code> if valid or <code>null</code> if invalid.
192: */
193: public Date validate(String value, Locale locale, TimeZone timeZone) {
194: return (Date) parse(value, (String) null, locale, timeZone);
195: }
196:
197: /**
198: * <p>Validate/convert a <code>Date</code> using the specified pattern
199: * and <code>Locale</code> and the default <code>TimeZone</code>.
200: *
201: * @param value The value validation is being performed on.
202: * @param pattern The pattern used to validate the value against, or the
203: * default for the <code>Locale</code> if <code>null</code>.
204: * @param locale The locale to use for the date format, system default if null.
205: * @return The parsed <code>Date</code> if valid or <code>null</code> if invalid.
206: */
207: public Date validate(String value, String pattern, Locale locale) {
208: return (Date) parse(value, pattern, locale, (TimeZone) null);
209: }
210:
211: /**
212: * <p>Validate/convert a <code>Date</code> using the specified
213: * pattern, and <code>Locale</code> and <code>TimeZone</code>.
214: *
215: * @param value The value validation is being performed on.
216: * @param pattern The pattern used to validate the value against, or the
217: * default for the <code>Locale</code> if <code>null</code>.
218: * @param locale The locale to use for the date format, system default if null.
219: * @param timeZone The Time Zone used to parse the date, system default if null.
220: * @return The parsed <code>Date</code> if valid or <code>null</code> if invalid.
221: */
222: public Date validate(String value, String pattern, Locale locale,
223: TimeZone timeZone) {
224: return (Date) parse(value, pattern, locale, timeZone);
225: }
226:
227: /**
228: * <p>Compare Dates (day, month and year - not time).</p>
229: *
230: * @param value The <code>Calendar</code> value to check.
231: * @param compare The <code>Calendar</code> to compare the value to.
232: * @param timeZone The Time Zone used to compare the dates, system default if null.
233: * @return Zero if the dates are equal, -1 if first
234: * date is less than the seconds and +1 if the first
235: * date is greater than.
236: */
237: public int compareDates(Date value, Date compare, TimeZone timeZone) {
238: Calendar calendarValue = getCalendar(value, timeZone);
239: Calendar calendarCompare = getCalendar(compare, timeZone);
240: return compare(calendarValue, calendarCompare, Calendar.DATE);
241: }
242:
243: /**
244: * <p>Compare Weeks (week and year).</p>
245: *
246: * @param value The <code>Date</code> value to check.
247: * @param compare The <code>Date</code> to compare the value to.
248: * @param timeZone The Time Zone used to compare the dates, system default if null.
249: * @return Zero if the weeks are equal, -1 if first
250: * parameter's week is less than the seconds and +1 if the first
251: * parameter's week is greater than.
252: */
253: public int compareWeeks(Date value, Date compare, TimeZone timeZone) {
254: Calendar calendarValue = getCalendar(value, timeZone);
255: Calendar calendarCompare = getCalendar(compare, timeZone);
256: return compare(calendarValue, calendarCompare,
257: Calendar.WEEK_OF_YEAR);
258: }
259:
260: /**
261: * <p>Compare Months (month and year).</p>
262: *
263: * @param value The <code>Date</code> value to check.
264: * @param compare The <code>Date</code> to compare the value to.
265: * @param timeZone The Time Zone used to compare the dates, system default if null.
266: * @return Zero if the months are equal, -1 if first
267: * parameter's month is less than the seconds and +1 if the first
268: * parameter's month is greater than.
269: */
270: public int compareMonths(Date value, Date compare, TimeZone timeZone) {
271: Calendar calendarValue = getCalendar(value, timeZone);
272: Calendar calendarCompare = getCalendar(compare, timeZone);
273: return compare(calendarValue, calendarCompare, Calendar.MONTH);
274: }
275:
276: /**
277: * <p>Compare Quarters (quarter and year).</p>
278: *
279: * @param value The <code>Date</code> value to check.
280: * @param compare The <code>Date</code> to compare the value to.
281: * @param timeZone The Time Zone used to compare the dates, system default if null.
282: * @return Zero if the months are equal, -1 if first
283: * parameter's quarter is less than the seconds and +1 if the first
284: * parameter's quarter is greater than.
285: */
286: public int compareQuarters(Date value, Date compare,
287: TimeZone timeZone) {
288: return compareQuarters(value, compare, timeZone, 1);
289: }
290:
291: /**
292: * <p>Compare Quarters (quarter and year).</p>
293: *
294: * @param value The <code>Date</code> value to check.
295: * @param compare The <code>Date</code> to compare the value to.
296: * @param timeZone The Time Zone used to compare the dates, system default if null.
297: * @param monthOfFirstQuarter The month that the first quarter starts.
298: * @return Zero if the quarters are equal, -1 if first
299: * parameter's quarter is less than the seconds and +1 if the first
300: * parameter's quarter is greater than.
301: */
302: public int compareQuarters(Date value, Date compare,
303: TimeZone timeZone, int monthOfFirstQuarter) {
304: Calendar calendarValue = getCalendar(value, timeZone);
305: Calendar calendarCompare = getCalendar(compare, timeZone);
306: return super .compareQuarters(calendarValue, calendarCompare,
307: monthOfFirstQuarter);
308: }
309:
310: /**
311: * <p>Compare Years.</p>
312: *
313: * @param value The <code>Date</code> value to check.
314: * @param compare The <code>Date</code> to compare the value to.
315: * @param timeZone The Time Zone used to compare the dates, system default if null.
316: * @return Zero if the years are equal, -1 if first
317: * parameter's year is less than the seconds and +1 if the first
318: * parameter's year is greater than.
319: */
320: public int compareYears(Date value, Date compare, TimeZone timeZone) {
321: Calendar calendarValue = getCalendar(value, timeZone);
322: Calendar calendarCompare = getCalendar(compare, timeZone);
323: return compare(calendarValue, calendarCompare, Calendar.YEAR);
324: }
325:
326: /**
327: * <p>Returns the parsed <code>Date</code> unchanged.</p>
328: *
329: * @param value The parsed <code>Date</code> object created.
330: * @param formatter The Format used to parse the value with.
331: * @return The parsed value converted to a <code>Calendar</code>.
332: */
333: protected Object processParsedValue(Object value, Format formatter) {
334: return value;
335: }
336:
337: /**
338: * <p>Convert a <code>Date</code> to a <code>Calendar</code>.</p>
339: *
340: * @param value The date value to be converted.
341: * @return The converted <code>Calendar</code>.
342: */
343: private Calendar getCalendar(Date value, TimeZone timeZone) {
344:
345: Calendar calendar = null;
346: if (timeZone != null) {
347: calendar = Calendar.getInstance(timeZone);
348: } else {
349: calendar = Calendar.getInstance();
350: }
351: calendar.setTime(value);
352: return calendar;
353:
354: }
355:
356: }
|