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 junit.framework.TestCase;
20  
21  import java.util.Date;
22  import java.util.Calendar;
23  import java.util.Locale;
24  import java.util.TimeZone;
25  
26  /***
27   * Test Case for TimeValidator.
28   * 
29   * @version $Revision: 478334 $ $Date: 2006-11-22 21:31:54 +0000 (Wed, 22 Nov 2006) $
30   */
31  public class TimeValidatorTest extends TestCase {
32  
33      protected static final TimeZone GMT = TimeZone.getTimeZone("GMT"); // 0 offset
34      protected static final TimeZone EST = TimeZone.getTimeZone("EST"); // - 5 hours
35  
36      protected TimeValidator validator;
37  
38      protected String[] patternValid = new String[] {
39                         "23-59-59" 
40                        ,"00-00-00"
41                        ,"00-00-01"
42                        ,"0-0-0" 
43                        ,"1-12-1"
44                        ,"10-49-18"
45                        ,"16-23-46"};
46      protected Date[] patternExpect = new Date[] {
47                         createDate(null, 235959, 0)
48                        ,createDate(null, 0, 0)
49                        ,createDate(null, 1, 0)
50                        ,createDate(null, 0, 0)
51                        ,createDate(null, 11201, 0)
52                        ,createDate(null, 104918, 0)
53                        ,createDate(null, 162346, 0)};
54      protected String[] localeValid = new String[] {
55                        "23:59" 
56                       ,"00:00"
57                       ,"00:01"
58                       ,"0:0" 
59                       ,"1:12"
60                       ,"10:49"
61                       ,"16:23"};
62      protected Date[] localeExpect = new Date[] {
63                        createDate(null, 235900, 0)
64                       ,createDate(null, 0, 0)
65                       ,createDate(null, 100, 0)
66                       ,createDate(null, 0, 0)
67                       ,createDate(null, 11200, 0)
68                       ,createDate(null, 104900, 0)
69                       ,createDate(null, 162300, 0)};
70      protected String[] patternInvalid = new String[] {
71                           "24-00-00"  // midnight
72                          ,"24-00-01"  // past midnight
73                          ,"25-02-03"  // invalid hour 
74                          ,"10-61-31"  // invalid minute
75                          ,"10-01-61"  // invalid second
76                          ,"05:02-29"  // invalid sep 
77                          ,"0X-01:01"  // invalid sep
78                          ,"05-0X-01"  // invalid char
79                          ,"10-01-0X"  // invalid char
80                          ,"01:01:05"  // invalid pattern
81                          ,"10-10"     // invalid pattern
82                          ,"10--10"    // invalid pattern
83                          ,"10-10-"};  // invalid pattern
84      protected String[] localeInvalid = new String[] {
85                           "24:00"  // midnight
86                          ,"24:00"  // past midnight
87                          ,"25:02"  // invalid hour 
88                          ,"10:61"  // invalid minute
89                          ,"05-02"  // invalid sep 
90                          ,"0X:01"  // invalid sep
91                          ,"05:0X"  // invalid char
92                          ,"01-01"  // invalid pattern
93                          ,"10:"     // invalid pattern
94                          ,"10::1"    // invalid pattern
95                          ,"10:1:"};  // invalid pattern
96  
97      /***
98       * Main
99       * @param args arguments
100      */
101     public static void main(String[] args) {
102         junit.textui.TestRunner.run(TimeValidatorTest.class);
103     }
104 
105     /***
106      * Constructor
107      * @param name test name
108      */
109     public TimeValidatorTest(String name) {
110         super(name);
111     }
112 
113     protected void setUp() throws Exception {
114         super.setUp();
115         validator = new TimeValidator();
116     }
117 
118     /***
119      * Tear down
120      * @throws Exception
121      */
122     protected void tearDown() throws Exception {
123         super.tearDown();
124         validator = null;
125     }
126 
127     /***
128      * Test Valid Dates with "pattern" validation
129      */
130     public void testPatternValid() {
131         for (int i = 0; i < patternValid.length; i++) {
132             String text = i + " value=[" +patternValid[i]+"] failed ";
133             Calendar calendar = validator.validate(patternValid[i], "HH-mm-ss");
134             assertNotNull("validateObj() " + text,  calendar);
135             Date date = calendar.getTime();
136             assertTrue("isValid() " + text,  validator.isValid(patternValid[i], "HH-mm-ss"));
137             assertEquals("compare " + text, patternExpect[i], date);
138         }
139     }
140 
141     /***
142      * Test Invalid Dates with "pattern" validation
143      */
144     public void testPatternInvalid() {
145         for (int i = 0; i < patternInvalid.length; i++) {
146             String text = i + " value=[" +patternInvalid[i]+"] passed ";
147             Object date = validator.validate(patternInvalid[i], "HH-mm-ss");
148             assertNull("validate() " + text + date,  date);
149             assertFalse("isValid() " + text,  validator.isValid(patternInvalid[i], "HH-mm-ss"));
150         }
151     }
152 
153     /***
154      * Test Valid Dates with "locale" validation
155      */
156     public void testLocaleValid() {
157         for (int i = 0; i < localeValid.length; i++) {
158             String text = i + " value=[" +localeValid[i]+"] failed ";
159             Calendar calendar = validator.validate(localeValid[i], Locale.UK);
160             assertNotNull("validate() " + text,  calendar);
161             Date date = calendar.getTime();
162             assertTrue("isValid() " + text,  validator.isValid(localeValid[i], Locale.UK));
163             assertEquals("compare " + text, localeExpect[i], date);
164         }
165     }
166 
167     /***
168      * Test Invalid Dates with "locale" validation
169      */
170     public void testLocaleInvalid() {
171         for (int i = 0; i < localeInvalid.length; i++) {
172             String text = i + " value=[" +localeInvalid[i]+"] passed ";
173             Object date = validator.validate(localeInvalid[i], Locale.US);
174             assertNull("validate() " + text + date,  date);
175             assertFalse("isValid() " + text,  validator.isValid(localeInvalid[i], Locale.UK));
176         }
177     }
178 
179     /***
180      * Test time zone methods.
181      */
182     public void testTimeZone() {
183         // Set the default Locale & TimeZone
184         Locale origDefault = Locale.getDefault();
185         Locale.setDefault(Locale.UK);
186         TimeZone defaultZone = TimeZone.getDefault();
187         TimeZone.setDefault(GMT);
188 
189         Calendar result = null;
190 
191         // Default Locale, Default TimeZone
192         result = validator.validate("18:01");
193         assertNotNull("default result", result);
194         assertEquals("default zone",  GMT, result.getTimeZone());
195         assertEquals("default hour",   18, result.get(Calendar.HOUR_OF_DAY));
196         assertEquals("default minute", 01, result.get(Calendar.MINUTE));
197         result = null;
198 
199         // Default Locale, diff TimeZone
200         result = validator.validate("16:49", EST);
201         assertNotNull("zone result", result);
202         assertEquals("zone zone",  EST, result.getTimeZone());
203         assertEquals("zone hour",   16, result.get(Calendar.HOUR_OF_DAY));
204         assertEquals("zone minute", 49, result.get(Calendar.MINUTE));
205         result = null;
206 
207         // Pattern, diff TimeZone
208         result = validator.validate("14-34", "HH-mm", EST);
209         assertNotNull("pattern result", result);
210         assertEquals("pattern zone",  EST, result.getTimeZone());
211         assertEquals("pattern hour",   14, result.get(Calendar.HOUR_OF_DAY));
212         assertEquals("pattern minute", 34, result.get(Calendar.MINUTE));
213         result = null;
214 
215         // Locale, diff TimeZone
216         result = validator.validate("7:18 PM", Locale.US, EST);
217         assertNotNull("locale result", result);
218         assertEquals("locale zone",  EST, result.getTimeZone());
219         assertEquals("locale hour",   19, result.get(Calendar.HOUR_OF_DAY));
220         assertEquals("locale minute", 18, result.get(Calendar.MINUTE));
221         result = null;
222 
223         // Locale & Pattern, diff TimeZone
224         result = validator.validate("31/Dez/05 21-05", "dd/MMM/yy HH-mm", Locale.GERMAN, EST);
225         assertNotNull("pattern result", result);
226         assertEquals("pattern zone",  EST, result.getTimeZone());
227         assertEquals("pattern day",  2005, result.get(Calendar.YEAR));
228         assertEquals("pattern day",    11, result.get(Calendar.MONTH)); // months are 0-11
229         assertEquals("pattern day",    31, result.get(Calendar.DATE));
230         assertEquals("pattern hour",   21, result.get(Calendar.HOUR_OF_DAY));
231         assertEquals("pattern minute", 05, result.get(Calendar.MINUTE));
232         result = null;
233 
234         // Locale & Pattern, default TimeZone
235         result = validator.validate("31/Dez/05 21-05", "dd/MMM/yy HH-mm", Locale.GERMAN);
236         assertNotNull("pattern result", result);
237         assertEquals("pattern zone",  GMT, result.getTimeZone());
238         assertEquals("pattern day",  2005, result.get(Calendar.YEAR));
239         assertEquals("pattern day",    11, result.get(Calendar.MONTH)); // months are 0-11
240         assertEquals("pattern day",    31, result.get(Calendar.DATE));
241         assertEquals("pattern hour",   21, result.get(Calendar.HOUR_OF_DAY));
242         assertEquals("pattern minute", 05, result.get(Calendar.MINUTE));
243         result = null;
244 
245         // Restore the original default
246         Locale.setDefault(origDefault);
247         TimeZone.setDefault(defaultZone);
248     }
249 
250     /***
251      * Test Invalid Dates with "locale" validation
252      */
253     public void testFormat() {
254         // Set the default Locale
255         Locale origDefault = Locale.getDefault();
256         Locale.setDefault(Locale.UK);
257 
258         Object test = TimeValidator.getInstance().validate("16:49:23", "HH:mm:ss");
259         assertNotNull("Test Date ", test);
260         assertEquals("Format pattern", "16-49-23", validator.format(test, "HH-mm-ss"));
261         assertEquals("Format locale",  "4:49 PM",  validator.format(test, Locale.US));
262         assertEquals("Format default", "16:49",  validator.format(test));
263 
264         // Restore the original default
265         Locale.setDefault(origDefault);
266     }
267 
268     /***
269      * Test compare date methods
270      */
271     public void testCompare() {
272         int testTime = 154523;
273         int min = 100;
274         int hour = 10000;
275 
276         Calendar milliGreater = createTime(GMT, testTime, 500); // > milli sec
277         Calendar value        = createTime(GMT, testTime, 400); // test value
278         Calendar milliLess    = createTime(GMT, testTime, 300); // < milli sec
279 
280         Calendar secGreater   = createTime(GMT, testTime + 1, 100);   // +1 sec
281         Calendar secLess      = createTime(GMT, testTime - 1, 100);   // -1 sec
282 
283         Calendar minGreater   = createTime(GMT, testTime + min, 100);   // +1 min
284         Calendar minLess      = createTime(GMT, testTime - min, 100);   // -1 min
285 
286         Calendar hourGreater  = createTime(GMT, testTime + hour, 100);   // +1 hour
287         Calendar hourLess     = createTime(GMT, testTime - hour, 100);   // -1 hour
288 
289         assertEquals("mili LT", -1, validator.compareTime(value, milliGreater)); // > milli
290         assertEquals("mili EQ", 0,  validator.compareTime(value, value));        // same time
291         assertEquals("mili GT", 1,  validator.compareTime(value, milliLess));    // < milli
292 
293         assertEquals("secs LT", -1, validator.compareSeconds(value, secGreater));   // +1 sec
294         assertEquals("secs =1", 0,  validator.compareSeconds(value, milliGreater)); // > milli
295         assertEquals("secs =2", 0,  validator.compareSeconds(value, value));        // same time
296         assertEquals("secs =3", 0,  validator.compareSeconds(value, milliLess));    // < milli
297         assertEquals("secs GT", 1,  validator.compareSeconds(value, secLess));      // -1 sec
298 
299         assertEquals("mins LT", -1, validator.compareMinutes(value, minGreater));   // +1 min
300         assertEquals("mins =1", 0,  validator.compareMinutes(value, secGreater));   // +1 sec
301         assertEquals("mins =2", 0,  validator.compareMinutes(value, value));        // same time
302         assertEquals("mins =3", 0,  validator.compareMinutes(value, secLess));      // -1 sec
303         assertEquals("mins GT", 1,  validator.compareMinutes(value, minLess));      // -1 min
304 
305         assertEquals("hour LT", -1, validator.compareHours(value, hourGreater));   // +1 hour
306         assertEquals("hour =1", 0,  validator.compareHours(value, minGreater));   // +1 min
307         assertEquals("hour =2", 0,  validator.compareHours(value, value));        // same time
308         assertEquals("hour =3", 0,  validator.compareHours(value, minLess));      // -1 min
309         assertEquals("hour GT", 1,  validator.compareHours(value, hourLess));      // -1 hour
310 
311     }
312 
313     /***
314      * Create a calendar instance for a specified time zone, date and time.
315      * 
316      * @param zone The time zone
317      * @param time the time in HH:mm:ss format
318      * @param millisecond the milliseconds
319      * @return the new Calendar instance.
320      */
321     protected static Calendar createTime(TimeZone zone, int time, int millisecond) {
322         Calendar calendar = zone == null ? Calendar.getInstance()
323                                          : Calendar.getInstance(zone);
324         int hour = ((time / 10000) * 10000);
325         int min  = ((time / 100) * 100) - hour;
326         int sec  = time - (hour + min);
327         calendar.set(Calendar.YEAR,  1970);
328         calendar.set(Calendar.MONTH, 0);
329         calendar.set(Calendar.DATE,  1);
330         calendar.set(Calendar.HOUR_OF_DAY,  (hour / 10000));
331         calendar.set(Calendar.MINUTE, (min / 100));
332         calendar.set(Calendar.SECOND,  sec);
333         calendar.set(Calendar.MILLISECOND,  millisecond);
334         return calendar;
335     }
336 
337     /***
338      * Create a date instance for a specified time zone, date and time.
339      * 
340      * @param zone The time zone
341      * @param time the time in HH:mm:ss format
342      * @param millisecond the milliseconds
343      * @return the new Date instance.
344      */
345     protected static Date createDate(TimeZone zone, int time, int millisecond) {
346         Calendar calendar = createTime(zone, time, millisecond);
347         return calendar.getTime();
348     }
349 }