View Javadoc

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.lang3.time;
18  
19  import org.junit.Test;
20  import org.junit.Before;
21  import static org.junit.Assert.*;
22  import java.text.DateFormat;
23  import java.text.SimpleDateFormat;
24  import java.util.Calendar;
25  import java.util.Date;
26  import java.util.Locale;
27  
28  /**
29   * These Unit-tests will check all possible extremes when using some rounding-methods of DateUtils.
30   * The extremes are tested at the switch-point in milliseconds
31   * 
32   * According to the implementation SEMI_MONTH will either round/truncate to the 1st or 16th
33   * When rounding Calendar.MONTH it depends on the number of days within that month.
34   * A month with 28 days will be rounded up from the 15th
35   * A month with 29 or 30 days will be rounded up from the 16th
36   * A month with 31 days will be rounded up from the 17th
37   * 
38   * @since 3.0
39   * @version $Id: DateUtilsRoundingTest.java 1436770 2013-01-22 07:09:45Z ggregory $
40   */
41  public class DateUtilsRoundingTest {
42  
43      DateFormat dateTimeParser;
44      
45      Date januaryOneDate;
46      Date targetYearDate;
47      //No targetMonths, these must be tested for every type of month(28-31 days)
48      Date targetDateDate, targetDayOfMonthDate, targetAmDate, targetPmDate;
49      Date targetHourOfDayDate, targetHourDate;
50      Date targetMinuteDate;
51      Date targetSecondDate;
52      Date targetMilliSecondDate;
53  
54      Calendar januaryOneCalendar;
55      FastDateFormat fdf = DateFormatUtils.ISO_DATETIME_FORMAT;
56  
57  
58      @Before
59      public void setUp() throws Exception {
60  
61          dateTimeParser = new SimpleDateFormat("MMM dd, yyyy H:mm:ss.SSS", Locale.ENGLISH);
62          
63          targetYearDate = dateTimeParser.parse("January 1, 2007 0:00:00.000");
64          targetDateDate = targetDayOfMonthDate = dateTimeParser.parse("June 1, 2008 0:00:00.000");
65          targetAmDate =  dateTimeParser.parse("June 1, 2008 0:00:00.000");
66          targetPmDate = dateTimeParser.parse("June 1, 2008 12:00:00.000");
67          targetHourDate = dateTimeParser.parse("June 1, 2008 8:00:00.000");
68          targetHourOfDayDate = dateTimeParser.parse("June 1, 2008 8:00:00.000");
69          targetMinuteDate =  dateTimeParser.parse("June 1, 2008 8:15:00.000");
70          targetSecondDate =  dateTimeParser.parse("June 1, 2008 8:15:14.000");
71          targetMilliSecondDate =  dateTimeParser.parse("June 1, 2008 8:15:14.231");
72          
73          januaryOneDate = dateTimeParser.parse("January 1, 2008 0:00:00.000");
74          januaryOneCalendar = Calendar.getInstance();
75          januaryOneCalendar.setTime(januaryOneDate);
76      }
77  
78      /**
79       * Tests DateUtils.round()-method with Calendar.Year
80       * 
81       * @throws Exception
82       * @since 3.0
83       */
84      @Test
85      public void testRoundYear() throws Exception {
86          final int calendarField = Calendar.YEAR;
87          final Date roundedUpDate = dateTimeParser.parse("January 1, 2008 0:00:00.000");
88          final Date roundedDownDate = targetYearDate;
89          final Date lastRoundedDownDate = dateTimeParser.parse("June 30, 2007 23:59:59.999");
90          baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
91      }
92      
93      /**
94       * Tests DateUtils.round()-method with Calendar.MONTH
95       * Includes rounding months with 28, 29, 30 and 31 days
96       * Includes rounding to January 1
97       * 
98       * @throws Exception
99       * @since 3.0
100      */
101     @Test
102     public void testRoundMonth() throws Exception {
103         final int calendarField = Calendar.MONTH;
104         Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
105         Date minDate, maxDate;
106         
107         //month with 28 days
108         roundedUpDate = dateTimeParser.parse("March 1, 2007 0:00:00.000");
109         roundedDownDate = dateTimeParser.parse("February 1, 2007 0:00:00.000");
110         lastRoundedDownDate = dateTimeParser.parse("February 14, 2007 23:59:59.999");
111         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
112 
113         //month with 29 days
114         roundedUpDate = dateTimeParser.parse("March 1, 2008 0:00:00.000");
115         roundedDownDate = dateTimeParser.parse("February 1, 2008 0:00:00.000");
116         lastRoundedDownDate = dateTimeParser.parse("February 15, 2008 23:59:59.999");
117         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
118         
119         //month with 30 days
120         roundedUpDate = dateTimeParser.parse("May 1, 2008 0:00:00.000");
121         roundedDownDate = dateTimeParser.parse("April 1, 2008 0:00:00.000");
122         lastRoundedDownDate = dateTimeParser.parse("April 15, 2008 23:59:59.999");
123         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
124         
125         //month with 31 days
126         roundedUpDate = dateTimeParser.parse("June 1, 2008 0:00:00.000");
127         roundedDownDate = dateTimeParser.parse("May 1, 2008 0:00:00.000");
128         lastRoundedDownDate = dateTimeParser.parse("May 16, 2008 23:59:59.999");
129         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
130         
131         //round to January 1
132         minDate = dateTimeParser.parse("December 17, 2007 00:00:00.000");
133         maxDate = dateTimeParser.parse("January 16, 2008 23:59:59.999");
134         roundToJanuaryFirst(minDate, maxDate, calendarField);
135     }
136     
137     /**
138      * Tests DateUtils.round()-method with DateUtils.SEMI_MONTH
139      * Includes rounding months with 28, 29, 30 and 31 days, each with first and second half 
140      * Includes rounding to January 1
141      *      
142      * @throws Exception
143      * @since 3.0
144      */
145     @Test
146     public void testRoundSemiMonth() throws Exception {
147         final int calendarField = DateUtils.SEMI_MONTH;
148         Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
149         Date minDate, maxDate;
150         
151         //month with 28 days (1)
152         roundedUpDate = dateTimeParser.parse("February 16, 2007 0:00:00.000");
153         roundedDownDate = dateTimeParser.parse("February 1, 2007 0:00:00.000");
154         lastRoundedDownDate = dateTimeParser.parse("February 8, 2007 23:59:59.999");
155         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
156 
157         //month with 28 days (2)
158         roundedUpDate = dateTimeParser.parse("March 1, 2007 0:00:00.000");
159         roundedDownDate = dateTimeParser.parse("February 16, 2007 0:00:00.000");
160         lastRoundedDownDate = dateTimeParser.parse("February 23, 2007 23:59:59.999");
161         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
162 
163         //month with 29 days (1)
164         roundedUpDate = dateTimeParser.parse("February 16, 2008 0:00:00.000");
165         roundedDownDate = dateTimeParser.parse("February 1, 2008 0:00:00.000");
166         lastRoundedDownDate = dateTimeParser.parse("February 8, 2008 23:59:59.999");
167         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
168         
169         //month with 29 days (2)
170         roundedUpDate = dateTimeParser.parse("March 1, 2008 0:00:00.000");
171         roundedDownDate = dateTimeParser.parse("February 16, 2008 0:00:00.000");
172         lastRoundedDownDate = dateTimeParser.parse("February 23, 2008 23:59:59.999");
173         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
174 
175         //month with 30 days (1)
176         roundedUpDate = dateTimeParser.parse("April 16, 2008 0:00:00.000");
177         roundedDownDate = dateTimeParser.parse("April 1, 2008 0:00:00.000");
178         lastRoundedDownDate = dateTimeParser.parse("April 8, 2008 23:59:59.999");
179         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
180 
181         //month with 30 days (2)
182         roundedUpDate = dateTimeParser.parse("May 1, 2008 0:00:00.000");
183         roundedDownDate = dateTimeParser.parse("April 16, 2008 0:00:00.000");
184         lastRoundedDownDate = dateTimeParser.parse("April 23, 2008 23:59:59.999");
185         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
186         
187         //month with 31 days (1)
188         roundedUpDate = dateTimeParser.parse("May 16, 2008 0:00:00.000");
189         roundedDownDate = dateTimeParser.parse("May 1, 2008 0:00:00.000");
190         lastRoundedDownDate = dateTimeParser.parse("May 8, 2008 23:59:59.999");
191         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
192 
193         //month with 31 days (2)
194         roundedUpDate = dateTimeParser.parse("June 1, 2008 0:00:00.000");
195         roundedDownDate = dateTimeParser.parse("May 16, 2008 0:00:00.000");
196         lastRoundedDownDate = dateTimeParser.parse("May 23, 2008 23:59:59.999");
197         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
198         
199         //round to January 1
200         minDate = dateTimeParser.parse("December 24, 2007 00:00:00.000");
201         maxDate = dateTimeParser.parse("January 8, 2008 23:59:59.999");
202         roundToJanuaryFirst(minDate, maxDate, calendarField);
203     }
204     
205     /**
206      * Tests DateUtils.round()-method with Calendar.DATE
207      * Includes rounding the extremes of one day 
208      * Includes rounding to January 1
209      * 
210      * @throws Exception
211      * @since 3.0
212      */
213     @Test
214     public void testRoundDate() throws Exception {
215         final int calendarField = Calendar.DATE;
216         Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
217         Date minDate, maxDate;
218 
219         roundedUpDate = dateTimeParser.parse("June 2, 2008 0:00:00.000");
220         roundedDownDate = targetDateDate;
221         lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 11:59:59.999");
222         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
223         
224         //round to January 1
225         minDate = dateTimeParser.parse("December 31, 2007 12:00:00.000");
226         maxDate = dateTimeParser.parse("January 1, 2008 11:59:59.999");
227         roundToJanuaryFirst(minDate, maxDate, calendarField);
228     }
229     
230     /**
231      * Tests DateUtils.round()-method with Calendar.DAY_OF_MONTH
232      * Includes rounding the extremes of one day 
233      * Includes rounding to January 1
234      * 
235      * @throws Exception
236      * @since 3.0
237      */
238     @Test
239     public void testRoundDayOfMonth() throws Exception {
240         final int calendarField = Calendar.DAY_OF_MONTH;
241         Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
242         Date minDate, maxDate;
243 
244         roundedUpDate = dateTimeParser.parse("June 2, 2008 0:00:00.000");
245         roundedDownDate = targetDayOfMonthDate;
246         lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 11:59:59.999");
247         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
248         
249         //round to January 1
250         minDate = dateTimeParser.parse("December 31, 2007 12:00:00.000");
251         maxDate = dateTimeParser.parse("January 1, 2008 11:59:59.999");
252         roundToJanuaryFirst(minDate, maxDate, calendarField);
253     }
254     
255     /**
256      * Tests DateUtils.round()-method with Calendar.AM_PM
257      * Includes rounding the extremes of both AM and PM of one day 
258      * Includes rounding to January 1
259      * 
260      * @throws Exception
261      * @since 3.0
262      */
263     @Test
264     public void testRoundAmPm() throws Exception {
265         final int calendarField = Calendar.AM_PM;
266         Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
267         Date minDate, maxDate;
268 
269         //AM
270         roundedUpDate = dateTimeParser.parse("June 1, 2008 12:00:00.000");
271         roundedDownDate = targetAmDate;
272         lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 5:59:59.999");
273         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
274 
275         //PM
276         roundedUpDate = dateTimeParser.parse("June 2, 2008 0:00:00.000");
277         roundedDownDate = targetPmDate;
278         lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 17:59:59.999");
279         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
280 
281         //round to January 1
282         minDate = dateTimeParser.parse("December 31, 2007 18:00:00.000");
283         maxDate = dateTimeParser.parse("January 1, 2008 5:59:59.999");
284         roundToJanuaryFirst(minDate, maxDate, calendarField);
285     }
286     
287     /**
288      * Tests DateUtils.round()-method with Calendar.HOUR_OF_DAY
289      * Includes rounding the extremes of one hour 
290      * Includes rounding to January 1
291      * 
292      * @throws Exception
293      * @since 3.0
294      */
295     @Test
296     public void testRoundHourOfDay() throws Exception {
297         final int calendarField = Calendar.HOUR_OF_DAY;
298         Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
299         Date minDate, maxDate;
300 
301         roundedUpDate = dateTimeParser.parse("June 1, 2008 9:00:00.000");
302         roundedDownDate = targetHourOfDayDate;
303         lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 8:29:59.999");
304         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
305         
306         //round to January 1
307         minDate = dateTimeParser.parse("December 31, 2007 23:30:00.000");
308         maxDate = dateTimeParser.parse("January 1, 2008 0:29:59.999");
309         roundToJanuaryFirst(minDate, maxDate, calendarField);
310     }
311     
312     /**
313      * Tests DateUtils.round()-method with Calendar.HOUR
314      * Includes rounding the extremes of one hour 
315      * Includes rounding to January 1
316      * 
317      * @throws Exception
318      * @since 3.0
319      */
320     @Test
321     public void testRoundHour() throws Exception {
322         final int calendarField = Calendar.HOUR;
323         Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
324         Date minDate, maxDate;
325 
326         roundedUpDate = dateTimeParser.parse("June 1, 2008 9:00:00.000");
327         roundedDownDate = targetHourDate;
328         lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 8:29:59.999");
329         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
330         
331         //round to January 1
332         minDate = dateTimeParser.parse("December 31, 2007 23:30:00.000");
333         maxDate = dateTimeParser.parse("January 1, 2008 0:29:59.999");
334         roundToJanuaryFirst(minDate, maxDate, calendarField);
335     }
336     
337     /**
338      * Tests DateUtils.round()-method with Calendar.MINUTE
339      * Includes rounding the extremes of one minute 
340      * Includes rounding to January 1
341      * 
342      * @throws Exception
343      * @since 3.0
344      */
345     @Test
346     public void testRoundMinute() throws Exception {
347         final int calendarField = Calendar.MINUTE;
348         Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
349         Date minDate, maxDate;
350 
351         roundedUpDate = dateTimeParser.parse("June 1, 2008 8:16:00.000");
352         roundedDownDate = targetMinuteDate;
353         lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 8:15:29.999");
354         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
355         
356         //round to January 1
357         minDate = dateTimeParser.parse("December 31, 2007 23:59:30.000");
358         maxDate = dateTimeParser.parse("January 1, 2008 0:00:29.999");
359         roundToJanuaryFirst(minDate, maxDate, calendarField);
360     }
361     
362     /**
363      * Tests DateUtils.round()-method with Calendar.SECOND
364      * Includes rounding the extremes of one second 
365      * Includes rounding to January 1
366      * 
367      * @throws Exception
368      * @since 3.0
369      */
370     @Test
371     public void testRoundSecond() throws Exception {
372         final int calendarField = Calendar.SECOND;
373         Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
374         Date minDate, maxDate;
375 
376         roundedUpDate = dateTimeParser.parse("June 1, 2008 8:15:15.000");
377         roundedDownDate = targetSecondDate;
378         lastRoundedDownDate = dateTimeParser.parse("June 1, 2008 8:15:14.499");
379         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
380         
381         //round to January 1
382         minDate = dateTimeParser.parse("December 31, 2007 23:59:59.500");
383         maxDate = dateTimeParser.parse("January 1, 2008 0:00:00.499");
384         roundToJanuaryFirst(minDate, maxDate, calendarField);
385     }
386     
387     /**
388      * Tests DateUtils.round()-method with Calendar.MILLISECOND
389      * Includes rounding the extremes of one second 
390      * Includes rounding to January 1
391      * 
392      * @throws Exception
393      * @since 3.0
394      */
395     @Test
396     public void testRoundMilliSecond() throws Exception {
397         final int calendarField = Calendar.MILLISECOND;
398         Date roundedUpDate, roundedDownDate, lastRoundedDownDate;
399         Date minDate, maxDate;
400 
401         roundedDownDate = lastRoundedDownDate = targetMilliSecondDate;
402         roundedUpDate = dateTimeParser.parse("June 1, 2008 8:15:14.232");
403         baseRoundTest(roundedUpDate, roundedDownDate, lastRoundedDownDate,  calendarField);
404         
405         //round to January 1
406         minDate = maxDate = januaryOneDate;
407         roundToJanuaryFirst(minDate, maxDate, calendarField);
408     }
409     
410     /**
411      * Test DateUtils.truncate()-method with Calendar.YEAR
412      * 
413      * @throws Exception
414      * @since 3.0
415      */
416     @Test
417     public void testTruncateYear() throws Exception {
418         final int calendarField = Calendar.YEAR;
419         final Date lastTruncateDate = dateTimeParser.parse("December 31, 2007 23:59:59.999");
420         baseTruncateTest(targetYearDate, lastTruncateDate, calendarField);
421     }
422 
423     /**
424      * Test DateUtils.truncate()-method with Calendar.MONTH
425      * 
426      * @throws Exception
427      * @since 3.0
428      */
429     @Test
430     public void testTruncateMonth() throws Exception {
431         final int calendarField = Calendar.MONTH;
432         final Date truncatedDate = dateTimeParser.parse("March 1, 2008 0:00:00.000");
433         final Date lastTruncateDate = dateTimeParser.parse("March 31, 2008 23:59:59.999");
434         baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
435     }
436 
437     /**
438      * Test DateUtils.truncate()-method with DateUtils.SEMI_MONTH
439      * Includes truncating months with 28, 29, 30 and 31 days, each with first and second half
440      * 
441      * @throws Exception
442      * @since 3.0
443      */
444     @Test
445     public void testTruncateSemiMonth() throws Exception {
446         final int calendarField = DateUtils.SEMI_MONTH;
447         Date truncatedDate, lastTruncateDate;
448         
449         //month with 28 days (1)
450         truncatedDate = dateTimeParser.parse("February 1, 2007 0:00:00.000");
451         lastTruncateDate = dateTimeParser.parse("February 15, 2007 23:59:59.999");
452         baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
453 
454         //month with 28 days (2)
455         truncatedDate = dateTimeParser.parse("February 16, 2007 0:00:00.000");
456         lastTruncateDate = dateTimeParser.parse("February 28, 2007 23:59:59.999");
457         baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
458 
459         //month with 29 days (1)
460         truncatedDate = dateTimeParser.parse("February 1, 2008 0:00:00.000");
461         lastTruncateDate = dateTimeParser.parse("February 15, 2008 23:59:59.999");
462         baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
463 
464         //month with 29 days (2)
465         truncatedDate = dateTimeParser.parse("February 16, 2008 0:00:00.000");
466         lastTruncateDate = dateTimeParser.parse("February 29, 2008 23:59:59.999");
467         baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
468 
469         //month with 30 days (1)
470         truncatedDate = dateTimeParser.parse("April 1, 2008 0:00:00.000");
471         lastTruncateDate = dateTimeParser.parse("April 15, 2008 23:59:59.999");
472         baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
473 
474         //month with 30 days (2)
475         truncatedDate = dateTimeParser.parse("April 16, 2008 0:00:00.000");
476         lastTruncateDate = dateTimeParser.parse("April 30, 2008 23:59:59.999");
477         baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
478         
479         //month with 31 days (1)
480         truncatedDate = dateTimeParser.parse("March 1, 2008 0:00:00.000");
481         lastTruncateDate = dateTimeParser.parse("March 15, 2008 23:59:59.999");
482         baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
483 
484         //month with 31 days (2)
485         truncatedDate = dateTimeParser.parse("March 16, 2008 0:00:00.000");
486         lastTruncateDate = dateTimeParser.parse("March 31, 2008 23:59:59.999");
487         baseTruncateTest(truncatedDate, lastTruncateDate, calendarField);
488 
489     }
490 
491     /**
492      * Test DateUtils.truncate()-method with Calendar.DATE
493      * 
494      * @throws Exception
495      * @since 3.0
496      */
497     @Test
498     public void testTruncateDate() throws Exception {
499         final int calendarField = Calendar.DATE;
500         final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 23:59:59.999");
501         baseTruncateTest(targetDateDate, lastTruncateDate, calendarField);
502     }
503     
504     /**
505      * Test DateUtils.truncate()-method with Calendar.DAY_OF_MONTH
506      * 
507      * @throws Exception
508      * @since 3.0
509      */
510     @Test
511     public void testTruncateDayOfMonth() throws Exception {
512         final int calendarField = Calendar.DAY_OF_MONTH;
513         final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 23:59:59.999");
514         baseTruncateTest(targetDayOfMonthDate, lastTruncateDate, calendarField);
515     }
516     
517     /**
518      * Test DateUtils.truncate()-method with Calendar.AM_PM
519      * Includes truncating the extremes of both AM and PM of one day 
520      * 
521      * @throws Exception
522      * @since 3.0
523      */
524     @Test
525     public void testTruncateAmPm() throws Exception {
526         final int calendarField = Calendar.AM_PM;
527         
528         //AM
529         Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 11:59:59.999");
530         baseTruncateTest(targetAmDate, lastTruncateDate, calendarField);
531 
532         //PM
533         lastTruncateDate = dateTimeParser.parse("June 1, 2008 23:59:59.999");
534         baseTruncateTest(targetPmDate, lastTruncateDate, calendarField);
535     }
536     
537     /**
538      * Test DateUtils.truncate()-method with Calendar.HOUR
539      * 
540      * @throws Exception
541      * @since 3.0
542      */
543     @Test
544     public void testTruncateHour() throws Exception {
545         final int calendarField = Calendar.HOUR;
546         final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 8:59:59.999");
547         baseTruncateTest(targetHourDate, lastTruncateDate, calendarField);
548     }
549     
550     /**
551      * Test DateUtils.truncate()-method with Calendar.HOUR_OF_DAY
552      * 
553      * @throws Exception
554      * @since 3.0
555      */
556     @Test
557     public void testTruncateHourOfDay() throws Exception {
558         final int calendarField = Calendar.HOUR_OF_DAY;
559         final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 8:59:59.999");
560         baseTruncateTest(targetHourOfDayDate, lastTruncateDate, calendarField);
561     }
562     
563     /**
564      * Test DateUtils.truncate()-method with Calendar.MINUTE
565      * 
566      * @throws Exception
567      * @since 3.0
568      */
569     @Test
570     public void testTruncateMinute() throws Exception {
571         final int calendarField = Calendar.MINUTE;
572         final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 8:15:59.999");
573         baseTruncateTest(targetMinuteDate, lastTruncateDate, calendarField);
574     }
575     
576     /**
577      * Test DateUtils.truncate()-method with Calendar.SECOND
578      * 
579      * @throws Exception
580      * @since 3.0
581      */
582     @Test
583     public void testTruncateSecond() throws Exception {
584         final int calendarField = Calendar.SECOND;
585         final Date lastTruncateDate = dateTimeParser.parse("June 1, 2008 8:15:14.999");
586         baseTruncateTest(targetSecondDate, lastTruncateDate, calendarField);
587     }
588     
589     /**
590      * Test DateUtils.truncate()-method with Calendar.SECOND
591      * 
592      * @throws Exception
593      * @since 3.0
594      */
595     @Test
596     public void testTruncateMilliSecond() throws Exception {
597         final int calendarField = Calendar.MILLISECOND;
598         baseTruncateTest(targetMilliSecondDate, targetMilliSecondDate, calendarField);
599     }
600         
601     /**
602      * When using this basetest all extremes are tested.<br> 
603      * It will test the Date, Calendar and Object-implementation<br>
604      * lastRoundDownDate should round down to roundedDownDate<br>
605      * lastRoundDownDate + 1 millisecond should round up to roundedUpDate
606      * 
607      * @param roundedUpDate the next rounded date after <strong>roundedDownDate</strong> when using <strong>calendarField</strong>
608      * @param roundedDownDate the result if <strong>lastRoundDownDate</strong> was rounded with <strong>calendarField</strong>
609      * @param lastRoundDownDate rounding this value with <strong>calendarField</strong> will result in <strong>roundedDownDate</strong>
610      * @param calendarField
611      * @since 3.0
612      */
613     protected void baseRoundTest(final Date roundedUpDate, final Date roundedDownDate, final Date lastRoundDownDate, final int calendarField) {
614         final Date firstRoundUpDate = DateUtils.addMilliseconds(lastRoundDownDate, 1);
615         
616         //Date-comparison
617         assertEquals(roundedDownDate, DateUtils.round(roundedDownDate, calendarField));
618         assertEquals(roundedUpDate, DateUtils.round(roundedUpDate, calendarField));
619         assertEquals(roundedDownDate, DateUtils.round(lastRoundDownDate, calendarField));
620         assertEquals(roundedUpDate, DateUtils.round(firstRoundUpDate, calendarField));
621         
622         //Calendar-initiations
623         Calendar roundedUpCalendar, roundedDownCalendar, lastRoundDownCalendar, firstRoundUpCalendar; 
624         roundedDownCalendar = Calendar.getInstance();
625         roundedUpCalendar = Calendar.getInstance();
626         lastRoundDownCalendar = Calendar.getInstance();
627         firstRoundUpCalendar = Calendar.getInstance();
628         roundedDownCalendar.setTime(roundedDownDate);
629         roundedUpCalendar.setTime(roundedUpDate);
630         lastRoundDownCalendar.setTime(lastRoundDownDate);
631         firstRoundUpCalendar.setTime(firstRoundUpDate);
632 
633         //Calendar-comparison
634         assertEquals(roundedDownCalendar, DateUtils.round(roundedDownCalendar, calendarField));
635         assertEquals(roundedUpCalendar, DateUtils.round(roundedUpCalendar, calendarField));
636         assertEquals(roundedDownCalendar, DateUtils.round(lastRoundDownCalendar, calendarField));
637         assertEquals(roundedUpCalendar, DateUtils.round(firstRoundUpCalendar, calendarField));
638 
639         //Object-comparison
640         assertEquals(roundedDownDate, DateUtils.round((Object) roundedDownDate, calendarField));
641         assertEquals(roundedUpDate, DateUtils.round((Object) roundedUpDate, calendarField));
642         assertEquals(roundedDownDate, DateUtils.round((Object) lastRoundDownDate, calendarField));
643         assertEquals(roundedUpDate, DateUtils.round((Object) firstRoundUpDate, calendarField));
644         assertEquals(roundedDownDate, DateUtils.round((Object) roundedDownCalendar, calendarField));
645         assertEquals(roundedUpDate, DateUtils.round((Object) roundedUpCalendar, calendarField));
646         assertEquals(roundedDownDate, DateUtils.round((Object) lastRoundDownDate, calendarField));
647         assertEquals(roundedUpDate, DateUtils.round((Object) firstRoundUpDate, calendarField));
648     }
649     
650     /**
651      * When using this basetest all extremes are tested.<br> 
652      * It will test the Date, Calendar and Object-implementation<br>
653      * lastTruncateDate should round down to truncatedDate<br>
654      * lastTruncateDate + 1 millisecond should never round down to truncatedDate
655      * 
656      * @param truncatedDate expected Date when <strong>lastTruncateDate</strong> is truncated with <strong>calendarField</strong>
657      * @param lastTruncateDate the last possible Date which will truncate to <strong>truncatedDate</strong> with <strong>calendarField</strong>
658      * @param calendarField a Calendar.field value
659      * @since 3.0
660      */
661     protected void baseTruncateTest(final Date truncatedDate, final Date lastTruncateDate, final int calendarField) {
662         final Date nextTruncateDate = DateUtils.addMilliseconds(lastTruncateDate, 1);
663         
664         //Date-comparison
665         assertEquals("Truncating "+ fdf.format(truncatedDate) +" as Date with CalendarField-value "+ calendarField +" must return itself", truncatedDate, DateUtils.truncate(truncatedDate, calendarField));
666         assertEquals(truncatedDate, DateUtils.truncate(lastTruncateDate, calendarField));
667         assertFalse(fdf.format(lastTruncateDate) +" is not an extreme when truncating as Date with CalendarField-value "+ calendarField, truncatedDate.equals(DateUtils.truncate(nextTruncateDate, calendarField)));
668         
669         //Calendar-initiations
670         Calendar truncatedCalendar, lastTruncateCalendar, nextTruncateCalendar; 
671         truncatedCalendar = Calendar.getInstance();
672         lastTruncateCalendar = Calendar.getInstance();
673         nextTruncateCalendar = Calendar.getInstance();
674         truncatedCalendar.setTime(truncatedDate);
675         lastTruncateCalendar.setTime(lastTruncateDate);
676         nextTruncateCalendar.setTime(nextTruncateDate);
677 
678         //Calendar-comparison
679         assertEquals("Truncating "+ fdf.format(truncatedCalendar) +" as Calendar with CalendarField-value "+ calendarField +" must return itself", truncatedCalendar, DateUtils.truncate(truncatedCalendar, calendarField));
680         assertEquals(truncatedCalendar, DateUtils.truncate(lastTruncateCalendar, calendarField));
681         assertFalse(fdf.format(lastTruncateCalendar) +" is not an extreme when truncating as Calendar with CalendarField-value "+ calendarField, truncatedCalendar.equals(DateUtils.truncate(nextTruncateCalendar, calendarField)));
682 
683         //Object-comparison
684         assertEquals("Truncating "+ fdf.format(truncatedDate) +" as Date cast to Object with CalendarField-value "+ calendarField +" must return itself as Date", truncatedDate, DateUtils.truncate((Object) truncatedDate, calendarField));
685         assertEquals(truncatedDate, DateUtils.truncate((Object) lastTruncateDate, calendarField));
686         assertFalse(fdf.format(lastTruncateDate) +" is not an extreme when truncating as Date cast to Object with CalendarField-value "+ calendarField, truncatedDate.equals(DateUtils.truncate((Object) nextTruncateDate, calendarField)));
687         assertEquals("Truncating "+ fdf.format(truncatedCalendar) +" as Calendar cast to Object with CalendarField-value "+ calendarField +" must return itself as Date", truncatedDate, DateUtils.truncate((Object) truncatedCalendar, calendarField));
688         assertEquals(truncatedDate, DateUtils.truncate((Object) lastTruncateCalendar, calendarField));
689         assertFalse(fdf.format(lastTruncateCalendar) +" is not an extreme when truncating as Calendar cast to Object with CalendarField-value "+ calendarField, truncatedDate.equals(DateUtils.truncate((Object) nextTruncateCalendar, calendarField)));
690     }
691     
692     /**
693      * 
694      * Any January 1 could be considered as the ultimate extreme.
695      * Instead of comparing the results if the input has a difference of 1 millisecond we check the output to be exactly January first. 
696      * 
697      * @param minDate
698      * @param maxDate
699      * @param calendarField
700      * @since 3.0
701      */
702     protected void roundToJanuaryFirst(final Date minDate, final Date maxDate, final int calendarField) {
703         assertEquals("Rounding "+ fdf.format(januaryOneDate) +" as Date with CalendarField-value "+ calendarField +" must return itself", januaryOneDate, DateUtils.round(januaryOneDate, calendarField));
704         assertEquals(januaryOneDate, DateUtils.round(minDate, calendarField));
705         assertEquals(januaryOneDate, DateUtils.round(maxDate, calendarField));
706         
707         final Calendar minCalendar = Calendar.getInstance();
708         minCalendar.setTime(minDate);
709         final Calendar maxCalendar = Calendar.getInstance();
710         maxCalendar.setTime(maxDate);
711         assertEquals("Rounding "+ fdf.format(januaryOneCalendar) +" as Date with CalendarField-value "+ calendarField +" must return itself", januaryOneCalendar, DateUtils.round(januaryOneCalendar, calendarField));
712         assertEquals(januaryOneCalendar, DateUtils.round(minCalendar, calendarField));
713         assertEquals(januaryOneCalendar, DateUtils.round(maxCalendar, calendarField));
714 
715         final Date toPrevRoundDate = DateUtils.addMilliseconds(minDate, -1);
716         final Date toNextRoundDate = DateUtils.addMilliseconds(maxDate, 1);
717         assertFalse(fdf.format(minDate) +" is not an lower-extreme when rounding as Date with CalendarField-value "+ calendarField, januaryOneDate.equals(DateUtils.round(toPrevRoundDate, calendarField)));
718         assertFalse(fdf.format(maxDate) +" is not an upper-extreme when rounding as Date with CalendarField-value "+ calendarField, januaryOneDate.equals(DateUtils.round(toNextRoundDate, calendarField)));
719         
720         final Calendar toPrevRoundCalendar = Calendar.getInstance();
721         toPrevRoundCalendar.setTime(toPrevRoundDate);
722         final Calendar toNextRoundCalendar = Calendar.getInstance();
723         toNextRoundCalendar.setTime(toNextRoundDate);
724         assertFalse(fdf.format(minCalendar) +" is not an lower-extreme when rounding as Date with CalendarField-value "+ calendarField, januaryOneDate.equals(DateUtils.round(toPrevRoundDate, calendarField)));
725         assertFalse(fdf.format(maxCalendar) +" is not an upper-extreme when rounding as Date with CalendarField-value "+ calendarField, januaryOneDate.equals(DateUtils.round(toNextRoundDate, calendarField)));
726     }
727 }