1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 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>Time 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> time 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 for the time.</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 successfully converted the following 56 * methods can be used to perform various time comparison checks:</p> 57 * <ul> 58 * <li><code>compareTime()</code> compares the hours, minutes, seconds 59 * and milliseconds of two calendars, returning 0, -1 or +1 indicating 60 * whether the first time is equal, before or after the second.</li> 61 * <li><code>compareSeconds()</code> compares the hours, minutes and 62 * seconds of two times, returning 0, -1 or +1 indicating 63 * whether the first is equal to, before or after the second.</li> 64 * <li><code>compareMinutes()</code> compares the hours and minutes 65 * two times, returning 0, -1 or +1 indicating 66 * whether the first is equal to, before or after the second.</li> 67 * <li><code>compareHours()</code> compares the hours 68 * of two times, returning 0, -1 or +1 indicating 69 * whether the first is equal to, before or after the second.</li> 70 * </ul> 71 * 72 * <p>So that the same mechanism used for parsing an <i>input</i> value 73 * for validation can be used to format <i>output</i>, corresponding 74 * <code>format()</code> methods are also provided. That is you can 75 * format either:</p> 76 * <ul> 77 * <li>using a specified pattern</li> 78 * <li>using the format for a specified <code>Locale</code></li> 79 * <li>using the format for the <i>default</i> <code>Locale</code></li> 80 * </ul> 81 * 82 * @since 1.3.0 83 */ 84 public class TimeValidator extends AbstractCalendarValidator { 85 86 private static final long serialVersionUID = 3494007492269691581L; 87 88 private static final TimeValidator VALIDATOR = new TimeValidator(); 89 90 /** 91 * Gets the singleton instance of this validator. 92 * @return A singleton instance of the TimeValidator. 93 */ 94 public static TimeValidator getInstance() { 95 return VALIDATOR; 96 } 97 98 /** 99 * Constructs a <i>strict</i> instance with <i>short</i> 100 * time style. 101 */ 102 public TimeValidator() { 103 this(true, DateFormat.SHORT); 104 } 105 106 /** 107 * Constructs an instance with the specified <i>strict</i> 108 * and <i>time style</i> parameters. 109 * 110 * @param strict {@code true} if strict 111 * <code>Format</code> parsing should be used. 112 * @param timeStyle the time style to use for Locale validation. 113 */ 114 public TimeValidator(final boolean strict, final int timeStyle) { 115 super(strict, -1, timeStyle); 116 } 117 118 /** 119 * <p>Compare Hours.</p> 120 * 121 * @param value The <code>Calendar</code> value to check. 122 * @param compare The <code>Calendar</code> to compare the value to. 123 * @return Zero if the hours are equal, -1 if first 124 * parameter's hour is less than the seconds and +1 if the first 125 * parameter's hour is greater than. 126 */ 127 public int compareHours(final Calendar value, final Calendar compare) { 128 return compareTime(value, compare, Calendar.HOUR_OF_DAY); 129 } 130 131 /** 132 * <p>Compare Minutes (hours and minutes).</p> 133 * 134 * @param value The <code>Calendar</code> value to check. 135 * @param compare The <code>Calendar</code> to compare the value to. 136 * @return Zero if the hours are equal, -1 if first 137 * parameter's minutes are less than the seconds and +1 if the first 138 * parameter's minutes are greater than. 139 */ 140 public int compareMinutes(final Calendar value, final Calendar compare) { 141 return compareTime(value, compare, Calendar.MINUTE); 142 } 143 144 /** 145 * <p>Compare Seconds (hours, minutes and seconds).</p> 146 * 147 * @param value The <code>Calendar</code> value to check. 148 * @param compare The <code>Calendar</code> to compare the value to. 149 * @return Zero if the hours are equal, -1 if first 150 * parameter's seconds are less than the seconds and +1 if the first 151 * parameter's seconds are greater than. 152 */ 153 public int compareSeconds(final Calendar value, final Calendar compare) { 154 return compareTime(value, compare, Calendar.SECOND); 155 } 156 157 /** 158 * <p>Compare Times (hour, minute, second and millisecond - not date).</p> 159 * 160 * @param value The <code>Calendar</code> value to check. 161 * @param compare The <code>Calendar</code> to compare the value to. 162 * @return Zero if the hours are equal, -1 if first 163 * time is less than the seconds and +1 if the first 164 * time is greater than. 165 */ 166 public int compareTime(final Calendar value, final Calendar compare) { 167 return compareTime(value, compare, Calendar.MILLISECOND); 168 } 169 170 /** 171 * <p>Convert the parsed <code>Date</code> to a <code>Calendar</code>.</p> 172 * 173 * @param value The parsed <code>Date</code> object created. 174 * @param formatter The Format used to parse the value with. 175 * @return The parsed value converted to a <code>Calendar</code>. 176 */ 177 @Override 178 protected Object processParsedValue(final Object value, final Format formatter) { 179 return ((DateFormat) formatter).getCalendar(); 180 } 181 182 /** 183 * <p>Validate/convert a time using the default <code>Locale</code> 184 * and <code>TimeZone</code>. 185 * 186 * @param value The value validation is being performed on. 187 * @return The parsed <code>Calendar</code> if valid or {@code null} 188 * if invalid. 189 */ 190 public Calendar validate(final String value) { 191 return (Calendar) parse(value, (String) null, (Locale) null, (TimeZone) null); 192 } 193 194 /** 195 * <p>Validate/convert a time using the specified <code>Locale</code> 196 * default <code>TimeZone</code>. 197 * 198 * @param value The value validation is being performed on. 199 * @param locale The locale to use for the time format, system default if null. 200 * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid. 201 */ 202 public Calendar validate(final String value, final Locale locale) { 203 return (Calendar) parse(value, (String) null, locale, (TimeZone) null); 204 } 205 206 /** 207 * <p>Validate/convert a time using the specified <code>Locale</code> 208 * and <code>TimeZone</code>. 209 * 210 * @param value The value validation is being performed on. 211 * @param locale The locale to use for the time format, system default if null. 212 * @param timeZone The Time Zone used to parse the time, system default if null. 213 * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid. 214 */ 215 public Calendar validate(final String value, final Locale locale, final TimeZone timeZone) { 216 return (Calendar) parse(value, (String) null, locale, timeZone); 217 } 218 219 /** 220 * <p>Validate/convert a time using the specified <i>pattern</i> and 221 * default <code>TimeZone</code>. 222 * 223 * @param value The value validation is being performed on. 224 * @param pattern The pattern used to validate the value against. 225 * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid. 226 */ 227 public Calendar validate(final String value, final String pattern) { 228 return (Calendar) parse(value, pattern, (Locale) null, (TimeZone) null); 229 } 230 231 /** 232 * <p>Validate/convert a time using the specified pattern and <code>Locale</code> 233 * and the default <code>TimeZone</code>. 234 * 235 * @param value The value validation is being performed on. 236 * @param pattern The pattern used to validate the value against, or the 237 * default for the <code>Locale</code> if {@code null}. 238 * @param locale The locale to use for the date format, system default if null. 239 * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid. 240 */ 241 public Calendar validate(final String value, final String pattern, final Locale locale) { 242 return (Calendar) parse(value, pattern, locale, (TimeZone) null); 243 } 244 245 /** 246 * <p>Validate/convert a time using the specified pattern, <code>Locale</code> 247 * and <code>TimeZone</code>. 248 * 249 * @param value The value validation is being performed on. 250 * @param pattern The pattern used to validate the value against, or the 251 * default for the <code>Locale</code> if {@code null}. 252 * @param locale The locale to use for the date format, system default if null. 253 * @param timeZone The Time Zone used to parse the date, system default if null. 254 * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid. 255 */ 256 public Calendar validate(final String value, final String pattern, final Locale locale, final TimeZone timeZone) { 257 return (Calendar) parse(value, pattern, locale, timeZone); 258 } 259 260 /** 261 * <p>Validate/convert a time using the specified <i>pattern</i> 262 * and <code>TimeZone</code>. 263 * 264 * @param value The value validation is being performed on. 265 * @param pattern The pattern used to validate the value against. 266 * @param timeZone The Time Zone used to parse the time, system default if null. 267 * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid. 268 */ 269 public Calendar validate(final String value, final String pattern, final TimeZone timeZone) { 270 return (Calendar) parse(value, pattern, (Locale) null, timeZone); 271 } 272 273 /** 274 * <p>Validate/convert a time using the specified <code>TimeZone</code> 275 * and default <code>Locale</code>. 276 * 277 * @param value The value validation is being performed on. 278 * @param timeZone The Time Zone used to parse the time, system default if null. 279 * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid. 280 */ 281 public Calendar validate(final String value, final TimeZone timeZone) { 282 return (Calendar) parse(value, (String) null, (Locale) null, timeZone); 283 } 284 }