001    package org.fest.assertions.internal;
002    
003    import static org.fest.assertions.error.ShouldBeAfter.shouldBeAfter;
004    import static org.fest.assertions.error.ShouldBeAfterOrEqualsTo.shouldBeAfterOrEqualsTo;
005    import static org.fest.assertions.error.ShouldBeBefore.shouldBeBefore;
006    import static org.fest.assertions.error.ShouldBeBeforeOrEqualsTo.shouldBeBeforeOrEqualsTo;
007    import static org.fest.assertions.error.ShouldBeBetween.shouldBeBetween;
008    import static org.fest.assertions.error.ShouldBeCloseTo.shouldBeCloseTo;
009    import static org.fest.assertions.error.ShouldBeInSameDay.shouldBeInSameDay;
010    import static org.fest.assertions.error.ShouldBeInSameHour.shouldBeInSameHour;
011    import static org.fest.assertions.error.ShouldBeInSameMinute.shouldBeInSameMinute;
012    import static org.fest.assertions.error.ShouldBeInSameMonth.shouldBeInSameMonth;
013    import static org.fest.assertions.error.ShouldBeInSameSecond.shouldBeInSameSecond;
014    import static org.fest.assertions.error.ShouldBeInSameYear.shouldBeInSameYear;
015    import static org.fest.assertions.error.ShouldBeInTheFuture.shouldBeInTheFuture;
016    import static org.fest.assertions.error.ShouldBeInThePast.shouldBeInThePast;
017    import static org.fest.assertions.error.ShouldBeToday.shouldBeToday;
018    import static org.fest.assertions.error.ShouldBeWithin.shouldBeWithin;
019    import static org.fest.assertions.error.ShouldNotBeBetween.shouldNotBeBetween;
020    import static org.fest.util.Dates.*;
021    
022    import java.util.Calendar;
023    import java.util.Comparator;
024    import java.util.Date;
025    
026    import org.fest.assertions.core.AssertionInfo;
027    import org.fest.util.ComparatorBasedComparisonStrategy;
028    import org.fest.util.ComparisonStrategy;
029    import org.fest.util.StandardComparisonStrategy;
030    import org.fest.util.VisibleForTesting;
031    
032    /**
033     * Reusable assertions for <code>{@link Date}</code>s.
034     * 
035     * @author Joel Costigliola
036     */
037    public class Dates {
038    
039      private static final Dates INSTANCE = new Dates();
040    
041      /**
042       * Returns the singleton instance of this class.
043       * @return the singleton instance of this class.
044       */
045      public static Dates instance() {
046        return INSTANCE;
047      }
048    
049      @VisibleForTesting
050      Failures failures = Failures.instance();
051    
052      @VisibleForTesting
053      Dates() {
054        this(StandardComparisonStrategy.instance());
055      }
056    
057      private ComparisonStrategy comparisonStrategy;
058    
059      public Dates(ComparisonStrategy comparisonStrategy) {
060        this.comparisonStrategy = comparisonStrategy;
061      }
062    
063      @VisibleForTesting
064      public Comparator<?> getComparator() {
065        if (comparisonStrategy instanceof ComparatorBasedComparisonStrategy) {
066          return ((ComparatorBasedComparisonStrategy)comparisonStrategy).getComparator();
067        }
068        return null;
069      }
070    
071      /**
072       * Verifies that the actual {@code Date} is strictly before the given one.
073       * @param info contains information about the assertion.
074       * @param actual the "actual" {@code Date}.
075       * @param other the other date to compare actual with.
076       * @throws AssertionError if {@code actual} is {@code null}.
077       * @throws NullPointerException if other {@code Date} is {@code null}.
078       * @throws AssertionError if the actual {@code Date} is not strictly before the given one.
079       */
080      public void assertIsBefore(AssertionInfo info, Date actual, Date other) {
081        assertNotNull(info, actual);
082        dateParameterIsNotNull(other);
083        if (isBefore(actual, other)) return;
084        throw failures.failure(info, shouldBeBefore(actual, other, comparisonStrategy));
085      }
086    
087      /**
088       * Verifies that the actual {@code Date} is before or equal to the given one.
089       * @param info contains information about the assertion.
090       * @param actual the "actual" {@code Date}.
091       * @param other the other date to compare actual with.
092       * @throws AssertionError if {@code actual} is {@code null}.
093       * @throws NullPointerException if other {@code Date} is {@code null}.
094       * @throws AssertionError if the actual {@code Date} is not before or equal to the given one.
095       */
096      public void assertIsBeforeOrEqualsTo(AssertionInfo info, Date actual, Date other) {
097        assertNotNull(info, actual);
098        dateParameterIsNotNull(other);
099        if (isBeforeOrEqualTo(actual, other)) return;
100        throw failures.failure(info, shouldBeBeforeOrEqualsTo(actual, other, comparisonStrategy));
101      }
102    
103      /**
104       * Verifies that the actual {@code Date} is strictly after the given one.
105       * @param info contains information about the assertion.
106       * @param actual the "actual" {@code Date}.
107       * @param other the given Date.
108       * @throws AssertionError if {@code actual} is {@code null}.
109       * @throws NullPointerException if other {@code Date} is {@code null}.
110       * @throws AssertionError if the actual {@code Date} is not strictly after the given one.
111       */
112      public void assertIsAfter(AssertionInfo info, Date actual, Date other) {
113        assertNotNull(info, actual);
114        dateParameterIsNotNull(other);
115        if (isAfter(actual, other)) return;
116        throw failures.failure(info, shouldBeAfter(actual, other, comparisonStrategy));
117      }
118    
119      /**
120       * Verifies that the actual {@code Date} is after or equal to the given one.
121       * @param info contains information about the assertion.
122       * @param actual the "actual" {@code Date}.
123       * @param other the given Date.
124       * @throws AssertionError if {@code actual} is {@code null}.
125       * @throws NullPointerException if other {@code Date} is {@code null}.
126       * @throws AssertionError if the actual {@code Date} is not after or equal to the given one.
127       */
128      public void assertIsAfterOrEqualsTo(AssertionInfo info, Date actual, Date other) {
129        assertNotNull(info, actual);
130        dateParameterIsNotNull(other);
131        if (isAfterOrEqualTo(actual, other)) return;
132        throw failures.failure(info, shouldBeAfterOrEqualsTo(actual, other, comparisonStrategy));
133      }
134    
135      /**
136       * Verifies that the actual {@code Date} is in <i>start:end</i> period.<br>
137       * start date belongs to the period if inclusiveStart is true.<br>
138       * end date belongs to the period if inclusiveEnd is true.<br>
139       * @param info contains information about the assertion.
140       * @param actual the "actual" {@code Date}.
141       * @param start the period start, expected not to be null.
142       * @param end the period end, expected not to be null.
143       * @param inclusiveStart wether to include start date in period.
144       * @param inclusiveEnd wether to include end date in period.
145       * @throws AssertionError if {@code actual} is {@code null}.
146       * @throws NullPointerException if start {@code Date} is {@code null}.
147       * @throws NullPointerException if end {@code Date} is {@code null}.
148       * @throws AssertionError if the actual {@code Date} is not in <i>start:end</i> period.
149       */
150      public void assertIsBetween(AssertionInfo info, Date actual, Date start, Date end, boolean inclusiveStart,
151          boolean inclusiveEnd) {
152        assertNotNull(info, actual);
153        startDateParameterIsNotNull(start);
154        endDateParameterIsNotNull(end);
155        boolean checkLowerBoundaryPeriod = inclusiveStart ? isAfterOrEqualTo(actual, start) : isAfter(actual, start);
156        boolean checkUpperBoundaryPeriod = inclusiveEnd ? isBeforeOrEqualTo(actual, end) : isBefore(actual, end);
157        if (checkLowerBoundaryPeriod && checkUpperBoundaryPeriod) return;
158        throw failures.failure(info, shouldBeBetween(actual, start, end, inclusiveStart, inclusiveEnd, comparisonStrategy));
159      }
160    
161      /**
162       * Verifies that the actual {@code Date} is not in <i>start:end</i> period..<br>
163       * start date belongs to the period if inclusiveStart is true.<br>
164       * end date belongs to the period if inclusiveEnd is true.<br>
165       * @param info contains information about the assertion.
166       * @param actual the "actual" {@code Date}.
167       * @param start the period start, expected not to be null.
168       * @param end the period end, expected not to be null.
169       * @param inclusiveStart wether to include start date in period.
170       * @param inclusiveEnd wether to include end date in period.
171       * @throws AssertionError if {@code actual} is {@code null}.
172       * @throws NullPointerException if start {@code Date} is {@code null}.
173       * @throws NullPointerException if end {@code Date} is {@code null}.
174       * @throws AssertionError if the actual {@code Date} is in <i>start:end</i> period.
175       */
176      public void assertIsNotBetween(AssertionInfo info, Date actual, Date start, Date end, boolean inclusiveStart,
177          boolean inclusiveEnd) {
178        assertNotNull(info, actual);
179        startDateParameterIsNotNull(start);
180        endDateParameterIsNotNull(end);
181        // check is in given period and use the negation of this result
182        boolean checkLowerBoundaryPeriod = inclusiveStart ? isAfterOrEqualTo(actual, start) : isAfter(actual, start);
183        boolean checkUpperBoundaryPeriod = inclusiveEnd ? isBeforeOrEqualTo(actual, end) : isBefore(actual, end);
184        boolean isBetweenGivenPeriod = checkLowerBoundaryPeriod && checkUpperBoundaryPeriod;
185        if (!isBetweenGivenPeriod) return;
186        throw failures.failure(info, shouldNotBeBetween(actual, start, end, inclusiveStart, inclusiveEnd, comparisonStrategy));
187      }
188    
189      /**
190       * Verifies that the actual {@code Date} is strictly in the past.
191       * @param info contains information about the assertion.
192       * @param actual the "actual" {@code Date}.
193       * @throws AssertionError if {@code actual} is {@code null}.
194       * @throws AssertionError if the actual {@code Date} is not in the past.
195       */
196      public void assertIsInThePast(AssertionInfo info, Date actual) {
197        assertNotNull(info, actual);
198        if (isBefore(actual, today())) return;
199        throw failures.failure(info, shouldBeInThePast(actual, comparisonStrategy));
200      }
201    
202      /**
203       * Verifies that the actual {@code Date} is today, by comparing only year, month and day of actual to today (ie. we
204       * don't check hours).
205       * @param info contains information about the assertion.
206       * @param actual the "actual" {@code Date}.
207       * @throws AssertionError if {@code actual} is {@code null}.
208       * @throws AssertionError if the actual {@code Date} is not today.
209       */
210      public void assertIsToday(AssertionInfo info, Date actual) {
211        assertNotNull(info, actual);
212        Date todayWithoutTime = truncateTime(today());
213        Date actualWithoutTime = truncateTime(actual);
214        if (areEqual(actualWithoutTime, todayWithoutTime)) return;
215        throw failures.failure(info, shouldBeToday(actual, comparisonStrategy));
216      }
217    
218      /**
219       * Verifies that the actual {@code Date} is strictly in the future.
220       * @param info contains information about the assertion.
221       * @param actual the "actual" {@code Date}.
222       * @throws AssertionError if {@code actual} is {@code null}.
223       * @throws AssertionError if the actual {@code Date} is not in the future.
224       */
225      public void assertIsInTheFuture(AssertionInfo info, Date actual) {
226        assertNotNull(info, actual);
227        if (isAfter(actual, today())) return;
228        throw failures.failure(info, shouldBeInTheFuture(actual, comparisonStrategy));
229      }
230    
231      /**
232       * Verifies that the actual {@code Date} is strictly before the given year.
233       * @param info contains information about the assertion.
234       * @param actual the "actual" {@code Date}.
235       * @param year the year to compare actual year to
236       * @throws AssertionError if {@code actual} is {@code null}.
237       * @throws AssertionError if the actual {@code Date} year is after or equal to the given year.
238       */
239      public void assertIsBeforeYear(AssertionInfo info, Date actual, int year) {
240        assertNotNull(info, actual);
241        if (yearOf(actual) < year) return;
242        throw failures.failure(info, shouldBeBefore(actual, year));
243      }
244    
245      /**
246       * Verifies that the actual {@code Date} is strictly after the given year.
247       * @param info contains information about the assertion.
248       * @param actual the "actual" {@code Date}.
249       * @param year the year to compare actual year to
250       * @throws AssertionError if {@code actual} is {@code null}.
251       * @throws AssertionError if the actual {@code Date} year is before or equal to the given year.
252       */
253      public void assertIsAfterYear(AssertionInfo info, Date actual, int year) {
254        assertNotNull(info, actual);
255        if (yearOf(actual) > year) return;
256        throw failures.failure(info, shouldBeAfter(actual, year));
257      }
258    
259      /**
260       * Verifies that the actual {@code Date} year is equal to the given year.
261       * @param year the year to compare actual year to
262       * @param info contains information about the assertion.
263       * @param actual the "actual" {@code Date}.
264       * @throws AssertionError if {@code actual} is {@code null}.
265       * @throws AssertionError if the actual {@code Date} year is not equal to the given year.
266       */
267      public void assertIsWithinYear(AssertionInfo info, Date actual, int year) {
268        assertNotNull(info, actual);
269        if (yearOf(actual) == year) return;
270        throw failures.failure(info, shouldBeWithin(actual, "year", year));
271      }
272    
273      /**
274       * Verifies that the actual {@code Date} month is equal to the given month, <b>month value starting at 1</b>
275       * (January=1, February=2, ...).
276       * @param info contains information about the assertion.
277       * @param actual the "actual" {@code Date}.
278       * @param month the month to compare actual month to, see {@link Calendar#MONTH} for valid values
279       * @throws AssertionError if {@code actual} is {@code null}.
280       * @throws AssertionError if the actual {@code Date} month is not equal to the given month.
281       */
282      public void assertIsWithinMonth(AssertionInfo info, Date actual, int month) {
283        assertNotNull(info, actual);
284        if (monthOf(actual) == month) return;
285        throw failures.failure(info, shouldBeWithin(actual, "month", month));
286      }
287    
288      /**
289       * Verifies that the actual {@code Date} day of month is equal to the given day of month.
290       * @param info contains information about the assertion.
291       * @param actual the "actual" {@code Date}.
292       * @param dayOfMonth the day of month to compare actual day of month to
293       * @throws AssertionError if {@code actual} is {@code null}.
294       * @throws AssertionError if the actual {@code Date} month is not equal to the given day of month.
295       */
296      public void assertIsWithinDayOfMonth(AssertionInfo info, Date actual, int dayOfMonth) {
297        assertNotNull(info, actual);
298        if (dayOfMonthOf(actual) == dayOfMonth) return;
299        throw failures.failure(info, shouldBeWithin(actual, "day of month", dayOfMonth));
300      }
301    
302      /**
303       * Verifies that the actual {@code Date} day of week is equal to the given day of week.
304       * @param info contains information about the assertion.
305       * @param actual the "actual" {@code Date}.
306       * @param dayOfWeek the day of week to compare actual day of week to, see {@link Calendar#DAY_OF_WEEK} for valid
307       *          values
308       * @throws AssertionError if {@code actual} is {@code null}.
309       * @throws AssertionError if the actual {@code Date} week is not equal to the given day of week.
310       */
311      public void assertIsWithinDayOfWeek(AssertionInfo info, Date actual, int dayOfWeek) {
312        assertNotNull(info, actual);
313        if (dayOfWeekOf(actual) == dayOfWeek) return;
314        throw failures.failure(info, shouldBeWithin(actual, "day of week", dayOfWeek));
315      }
316    
317      /**
318       * Verifies that the actual {@code Date} hour od day is equal to the given hour of day (24-hour clock).
319       * @param info contains information about the assertion.
320       * @param actual the "actual" {@code Date}.
321       * @param hourOfDay the hour of day to compare actual hour of day to (24-hour clock)
322       * @throws AssertionError if {@code actual} is {@code null}.
323       * @throws AssertionError if the actual {@code Date} hour is not equal to the given hour.
324       */
325      public void assertIsWithinHourOfDay(AssertionInfo info, Date actual, int hourOfDay) {
326        assertNotNull(info, actual);
327        if (hourOfDay(actual) == hourOfDay) return;
328        throw failures.failure(info, shouldBeWithin(actual, "hour", hourOfDay));
329      }
330    
331      /**
332       * Verifies that the actual {@code Date} minute is equal to the given minute.
333       * @param info contains information about the assertion.
334       * @param actual the "actual" {@code Date}.
335       * @param minute the minute to compare actual minute to
336       * @throws AssertionError if {@code actual} is {@code null}.
337       * @throws AssertionError if the actual {@code Date} minute is not equal to the given minute.
338       */
339      public void assertIsWithinMinute(AssertionInfo info, Date actual, int minute) {
340        assertNotNull(info, actual);
341        if (minuteOf(actual) == minute) return;
342        throw failures.failure(info, shouldBeWithin(actual, "minute", minute));
343      }
344    
345      /**
346       * Verifies that the actual {@code Date} second is equal to the given second.
347       * @param info contains information about the assertion.
348       * @param actual the "actual" {@code Date}.
349       * @param second the second to compare actual second to
350       * @throws AssertionError if {@code actual} is {@code null}.
351       * @throws AssertionError if the actual {@code Date} second is not equal to the given second.
352       */
353      public void assertIsWithinSecond(AssertionInfo info, Date actual, int second) {
354        assertNotNull(info, actual);
355        if (secondOf(actual) == second) return;
356        throw failures.failure(info, shouldBeWithin(actual, "second", second));
357      }
358    
359      /**
360       * Verifies that the actual {@code Date} millisecond is equal to the given millisecond.
361       * @param info contains information about the assertion.
362       * @param actual the "actual" {@code Date}.
363       * @param millisecond the millisecond to compare actual millisecond to
364       * @throws AssertionError if {@code actual} is {@code null}.
365       * @throws AssertionError if the actual {@code Date} millisecond is not equal to the given millisecond.
366       */
367      public void assertIsWithinMillisecond(AssertionInfo info, Date actual, int millisecond) {
368        assertNotNull(info, actual);
369        if (millisecondOf(actual) == millisecond) return;
370        throw failures.failure(info, shouldBeWithin(actual, "millisecond", millisecond));
371      }
372    
373      /**
374       * Verifies that actual and given {@code Date} are in the same year.
375       * @param info contains information about the assertion.
376       * @param actual the "actual" {@code Date}.
377       * @param other the given {@code Date} to compare actual {@code Date} to.
378       * @throws AssertionError if {@code actual} is {@code null}.
379       * @throws NullPointerException if other {@code Date} is {@code null}.
380       * @throws AssertionError if actual and given {@code Date} are not in the same year.
381       */
382      public void assertIsInSameYearAs(AssertionInfo info, Date actual, Date other) {
383        assertNotNull(info, actual);
384        dateParameterIsNotNull(other);
385        if (areInSameYear(actual, other)) return;
386        throw failures.failure(info, shouldBeInSameYear(actual, other));
387      }
388    
389      /**
390       * Returns true if both date are in the same year, false otherwise.
391       * @param actual the actual date. expected not be null
392       * @param other the other date. expected not be null
393       * @return true if both date are in the same year, false otherwise
394       */
395      private static boolean areInSameYear(Date actual, Date other) {
396        return yearOf(actual) == yearOf(other);
397      }
398    
399      /**
400       * Verifies that actual and given {@code Date} are chronologically in the same month (and thus in the same year).
401       * @param info contains information about the assertion.
402       * @param actual the "actual" {@code Date}.
403       * @param other the given {@code Date} to compare actual {@code Date} to.
404       * @throws AssertionError if {@code actual} is {@code null}.
405       * @throws NullPointerException if other {@code Date} is {@code null}.
406       * @throws AssertionError if actual and given {@code Date} are not chronologically speaking in the same month.
407       */
408      public void assertIsInSameMonthAs(AssertionInfo info, Date actual, Date other) {
409        assertNotNull(info, actual);
410        dateParameterIsNotNull(other);
411        if (areInSameMonth(actual, other)) return;
412        throw failures.failure(info, shouldBeInSameMonth(actual, other));
413      }
414    
415      /**
416       * Returns true if both date are in the same year and month, false otherwise.
417       * @param actual the actual date. expected not be null
418       * @param other the other date. expected not be null
419       * @return true if both date are in the same year and month, false otherwise
420       */
421      private static boolean areInSameMonth(Date actual, Date other) {
422        return areInSameYear(actual, other) && monthOf(actual) == monthOf(other);
423      }
424    
425      /**
426       * Verifies that actual and given {@code Date} are chronologically in the same day of month (and thus in the same
427       * month and year).
428       * @param info contains information about the assertion.
429       * @param actual the "actual" {@code Date}.
430       * @param other the given {@code Date} to compare actual {@code Date} to.
431       * @throws AssertionError if {@code actual} is {@code null}.
432       * @throws NullPointerException if other {@code Date} is {@code null}.
433       * @throws AssertionError if actual and given {@code Date} are not chronologically speaking in the same day of month.
434       */
435      public void assertIsInSameDayAs(AssertionInfo info, Date actual, Date other) {
436        assertNotNull(info, actual);
437        dateParameterIsNotNull(other);
438        if (areInSameDayOfMonth(actual, other)) return;
439        throw failures.failure(info, shouldBeInSameDay(actual, other));
440      }
441    
442      /**
443       * Returns true if both date are in the same year, month and day of month, false otherwise.
444       * @param actual the actual date. expected not be null
445       * @param other the other date. expected not be null
446       * @return true if both date are in the same year, month and day of month, false otherwise
447       */
448      private static boolean areInSameDayOfMonth(Date actual, Date other) {
449        return areInSameMonth(actual, other) && dayOfMonthOf(actual) == dayOfMonthOf(other);
450      }
451    
452      /**
453       * Verifies that actual and given {@code Date} are chronologically in the same hour (and thus in the same day of
454       * month, month and year).
455       * @param info contains information about the assertion.
456       * @param actual the "actual" {@code Date}.
457       * @param other the given {@code Date} to compare actual {@code Date} to.
458       * @throws AssertionError if {@code actual} is {@code null}.
459       * @throws NullPointerException if other {@code Date} is {@code null}.
460       * @throws AssertionError if actual and given {@code Date} are not chronologically speaking in the same hour.
461       */
462      public void assertIsInSameHourAs(AssertionInfo info, Date actual, Date other) {
463        assertNotNull(info, actual);
464        dateParameterIsNotNull(other);
465        if (areInSameHour(actual, other)) return;
466        throw failures.failure(info, shouldBeInSameHour(actual, other));
467      }
468    
469      /**
470       * Returns true if both date are in the same year, month, day of month and hour, false otherwise.
471       * @param actual the actual date. expected not be null
472       * @param other the other date. expected not be null
473       * @return true if both date are in the same year, month, day of month and hour, false otherwise.
474       */
475      private static boolean areInSameHour(Date actual, Date other) {
476        return areInSameDayOfMonth(actual, other) && hourOfDay(actual) == hourOfDay(other);
477      }
478    
479      /**
480       * Verifies that actual and given {@code Date} are chronologically in the same minute (and thus in the same hour, day
481       * of month, month and year).
482       * @param info contains information about the assertion.
483       * @param actual the "actual" {@code Date}.
484       * @param other the given {@code Date} to compare actual {@code Date} to.
485       * @throws AssertionError if {@code actual} is {@code null}.
486       * @throws NullPointerException if other {@code Date} is {@code null}.
487       * @throws AssertionError if actual and given {@code Date} are not chronologically speaking in the same minute.
488       */
489      public void assertIsInSameMinuteAs(AssertionInfo info, Date actual, Date other) {
490        assertNotNull(info, actual);
491        dateParameterIsNotNull(other);
492        if (areInSameMinute(actual, other)) return;
493        throw failures.failure(info, shouldBeInSameMinute(actual, other));
494      }
495    
496      /**
497       * Returns true if both date are in the same year, month, day of month, hour and minute, false otherwise.
498       * @param actual the actual date. expected not be null
499       * @param other the other date. expected not be null
500       * @return true if both date are in the same year, month, day of month, hour and minute, false otherwise.
501       */
502      private static boolean areInSameMinute(Date actual, Date other) {
503        return areInSameHour(actual, other) && minuteOf(actual) == minuteOf(other);
504      }
505    
506      /**
507       * Verifies that actual and given {@code Date} are chronologically in the same second (and thus in the same minute,
508       * hour, day of month, month and year).
509       * @param info contains information about the assertion.
510       * @param actual the "actual" {@code Date}.
511       * @param other the given {@code Date} to compare actual {@code Date} to.
512       * @throws AssertionError if {@code actual} is {@code null}.
513       * @throws NullPointerException if other {@code Date} is {@code null}.
514       * @throws AssertionError if actual and given {@code Date} are not chronologically speaking in the same second.
515       */
516      public void assertIsInSameSecondAs(AssertionInfo info, Date actual, Date other) {
517        assertNotNull(info, actual);
518        dateParameterIsNotNull(other);
519        if (areInSameSecond(actual, other)) return;
520        throw failures.failure(info, shouldBeInSameSecond(actual, other));
521      }
522    
523      /**
524       * Returns true if both date are in the same year, month and day of month, hour, minute and second, false otherwise.
525       * @param actual the actual date. expected not be null
526       * @param other the other date. expected not be null
527       * @return true if both date are in the same year, month and day of month, hour, minute and second, false otherwise.
528       */
529      private static boolean areInSameSecond(Date actual, Date other) {
530        return areInSameMinute(actual, other) && secondOf(actual) == secondOf(other);
531      }
532    
533      /**
534       * Verifies that the actual {@code Date} is close to the other date by less than delta, if difference is equals to
535       * delta it is ok.<br>
536       * Note that delta expressed in milliseconds.<br>
537       * Use handy TimeUnit to convert a duration in milliseconds, for example you can express a delta of 5 seconds with
538       * <code>TimeUnit.SECONDS.toMillis(5)</code>.
539       * @param info contains information about the assertion.
540       * @param actual the "actual" {@code Date}.
541       * @param other the given {@code Date} to compare actual {@code Date} to.
542       * @param deltaInMilliseconds the delta used for date comparison, expressed in milliseconds
543       * @throws AssertionError if {@code actual} is {@code null}.
544       * @throws NullPointerException if other {@code Date} is {@code null}.
545       * @throws AssertionError if the actual {@code Date} week is not close to the given date by less than delta.
546       */
547      public void assertIsCloseTo(AssertionInfo info, Date actual, Date other, long deltaInMilliseconds) {
548        assertNotNull(info, actual);
549        dateParameterIsNotNull(other);
550        long difference = Math.abs(actual.getTime() - other.getTime());
551        if (difference <= deltaInMilliseconds) return;
552        throw failures.failure(info, shouldBeCloseTo(actual, other, deltaInMilliseconds, difference));
553      }
554    
555      /**
556       * used to check that the date to compare actual date to is not null, in that case throws a
557       * {@link NullPointerException} with an explicit message
558       * @param date the date to check
559       * @throws a {@link NullPointerException} with an explicit message if the given date is null
560       */
561      private static void dateParameterIsNotNull(Date date) {
562        if (date == null) throw new NullPointerException("The date to compare actual with should not be null");
563      }
564    
565      /**
566       * used to check that the start of period date to compare actual date to is not null, in that case throws a
567       * {@link NullPointerException} with an explicit message
568       * @param start the start date to check
569       * @throws a {@link NullPointerException} with an explicit message if the given start date is null
570       */
571      private static void startDateParameterIsNotNull(Date start) {
572        if (start == null)
573          throw new NullPointerException("The start date of period to compare actual with should not be null");
574      }
575    
576      /**
577       * used to check that the end of perdio date to compare actual date to is not null, in that case throws a
578       * {@link NullPointerException} with an explicit message
579       * @param end the end date to check
580       * @throws a {@link NullPointerException} with an explicit message if the given end date is null
581       */
582      private static void endDateParameterIsNotNull(Date end) {
583        if (end == null)
584          throw new NullPointerException("The end date of period to compare actual with should not be null");
585      }
586    
587      private void assertNotNull(AssertionInfo info, Date actual) {
588        Objects.instance().assertNotNull(info, actual);
589      }
590    
591      /**
592       * Returns <code>true</code> if the actual {@code Date} is before or equal to the given one according to underlying
593       * {@link #comparisonStrategy}, false otherwise.
594       * @param actual the actual date - must not be null.
595       * @param other the given Date.
596       * @return <code>true</code> if the actual {@code Date} is before or equal to the given one according to underlying
597       *         {@link #comparisonStrategy}, false otherwise.
598       * @throws NullPointerException if {@code actual} is {@code null}.
599       */
600      private boolean isBeforeOrEqualTo(Date actual, Date other) {
601        return comparisonStrategy.isLessThanOrEqualTo(actual, other);
602      }
603    
604      /**
605       * Returns true if the actual {@code Date} is equal to the given one according to underlying
606       * {@link #comparisonStrategy}, false otherwise.
607       * @param actual the actual date - must not be null.
608       * @param other the given Date.
609       * @return <code>true</code> if the actual {@code Date} is equal to the given one according to underlying
610       *         {@link #comparisonStrategy}, false otherwise.
611       */
612      private boolean areEqual(Date actual, Date other) {
613        return comparisonStrategy.areEqual(other, actual);
614      }
615    
616      /**
617       * Returns <code>true</code> if the actual {@code Date} is after or equal to the given one according to underlying
618       * {@link #comparisonStrategy}, false otherwise.
619       * @param actual the actual date - must not be null.
620       * @param other the given Date.
621       * @return <code>true</code> if the actual {@code Date} is after or equal to the given one according to underlying
622       *         {@link #comparisonStrategy}, false otherwise.
623       * @throws NullPointerException if {@code actual} is {@code null}.
624       */
625      private boolean isAfterOrEqualTo(Date actual, Date other) {
626        return comparisonStrategy.isGreaterThanOrEqualTo(actual, other);
627      }
628    
629      /**
630       * Returns true if actual is before other according to underlying {@link #comparisonStrategy}, false otherwise.
631       * @param actual the {@link Date} to compare to other
632       * @param other the {@link Date} to compare to actual
633       * @return true if actual is before other according to underlying {@link #comparisonStrategy}, false otherwise.
634       */
635      private boolean isBefore(Date actual, Date other) {
636        return comparisonStrategy.isLessThan(actual, other);
637      }
638    
639      /**
640       * Returns true if actual is after other according to underlying {@link #comparisonStrategy}, false otherwise.
641       * @param actual the {@link Date} to compare to other
642       * @param other the {@link Date} to compare to actual
643       * @return true if actual is after other according to underlying {@link #comparisonStrategy}, false otherwise.
644       */
645      private boolean isAfter(Date actual, Date other) {
646        return comparisonStrategy.isGreaterThan(actual, other);
647      }
648    
649    }