001 package org.fest.assertions.api; 002 003 import static org.fest.util.Dates.ISO_DATE_FORMAT; 004 005 import java.text.DateFormat; 006 import java.text.ParseException; 007 import java.util.ArrayList; 008 import java.util.Calendar; 009 import java.util.Collection; 010 import java.util.Comparator; 011 import java.util.Date; 012 import java.util.concurrent.TimeUnit; 013 014 import org.fest.assertions.core.Assert; 015 import org.fest.assertions.internal.Dates; 016 import org.fest.assertions.internal.Failures; 017 import org.fest.util.ComparatorBasedComparisonStrategy; 018 import org.fest.util.VisibleForTesting; 019 020 /** 021 * 022 * Assertions for {@code Date}s. 023 * <p> 024 * To create a new instance of this class invoke <code>{@link Assertions#assertThat(Date)}</code>. 025 * </p> 026 * Note that assertions with date parameter comes with two flavor, one is obviously a {@link Date} and the other is a 027 * String representing a Date.<br> 028 * For the latter, the default format follows ISO 8901 : "yyyy-MM-dd", user can override it with a custom format by 029 * calling {@link #withDateFormat(DateFormat)}.<br> 030 * The user custom format will then be used for all next Date assertions (i.e not limited to the current assertion) in 031 * the test suite.<br> 032 * To turn back to default format, simply call {@link #withIsoDateFormat()}. 033 * 034 * @author Tomasz Nurkiewicz (thanks for giving assertions idea) 035 * @author Joel Costigliola 036 */ 037 public class DateAssert extends AbstractAssert<DateAssert, Date> { 038 039 @VisibleForTesting 040 Dates dates = Dates.instance(); 041 042 /** 043 * Used in String based Date assertions - like {@link #isAfter(String)} - to convert input date represented as string 044 * to Date.<br> 045 * The format used can be overriden by invoking {@link #withDateFormat(DateFormat)} 046 */ 047 @VisibleForTesting 048 static DateFormat dateFormat = ISO_DATE_FORMAT; 049 050 /** 051 * Creates a new </code>{@link DateAssert}</code>. 052 * @param actual the target to verify. 053 */ 054 protected DateAssert(Date actual) { 055 super(actual, DateAssert.class); 056 } 057 058 /** 059 * Same assertion as {@link AbstractAssert#isEqualTo(Object) isEqualTo(Date date)} but given Date is represented as String either with ISO date format 060 * (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 061 * @param dateAsString the given Date represented as String in default or custom date format. 062 * @return this assertion object. 063 * @throws AssertionError if actual and given Date represented as String are not equal. 064 * @throws AssertionError if the given date as String could not be converted to a Date. 065 */ 066 public DateAssert isEqualTo(String dateAsString) { 067 return isEqualTo(parse(dateAsString)); 068 } 069 070 /** 071 * Same assertion as {@link AbstractAssert#isNotEqualTo(Object) isNotEqualTo(Date date)} but given Date is represented as String either with ISO date format 072 * (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 073 * @param dateAsString the given Date represented as String in default or custom date format. 074 * @return this assertion object. 075 * @throws AssertionError if actual and given Date represented as String are equal. 076 * @throws AssertionError if the given date as String could not be converted to a Date. 077 */ 078 public DateAssert isNotEqualTo(String dateAsString) { 079 return isNotEqualTo(parse(dateAsString)); 080 } 081 082 /** 083 * Same assertion as {@link Assert#isIn(Object...)} but given Dates are represented as String either with ISO date format 084 * (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 085 * @param datesAsString the given Dates represented as String in default or custom date format. 086 * @return this assertion object. 087 * @throws AssertionError if actual is not in given Dates represented as String. 088 * @throws AssertionError if one of the given date as String could not be converted to a Date. 089 */ 090 public DateAssert isIn(String... datesAsString) { 091 Date[] dates = new Date[datesAsString.length]; 092 for (int i = 0; i < datesAsString.length; i++) { 093 dates[i] = parse(datesAsString[i]); 094 } 095 return isIn(dates); 096 } 097 098 /** 099 * Same assertion as {@link Assert#isIn(Iterable)} but given Dates are represented as String either with ISO date format 100 * (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}).<br> 101 * Method signature could not be <code>isIn(Collection<String>)</code> because it would be same signature as 102 * <code>isIn(Collection<Date>)</code> since java collection type are erased at runtime. 103 * @param datesAsString the given Dates represented as String in default or custom date format. 104 * @return this assertion object. 105 * @throws AssertionError if actual is not in given Dates represented as String. 106 * @throws AssertionError if one of the given date as String could not be converted to a Date. 107 */ 108 public DateAssert isInWithStringDateCollection(Collection<String> datesAsString) { 109 Collection<Date> dates = new ArrayList<Date>(datesAsString.size()); 110 for (String dateAsString : datesAsString) { 111 dates.add(parse(dateAsString)); 112 } 113 return isIn(dates); 114 } 115 116 /** 117 * Same assertion as {@link Assert#isNotIn(Object...)} but given Dates are represented as String either with ISO date 118 * format (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 119 * @param datesAsString the given Dates represented as String in default or custom date format. 120 * @return this assertion object. 121 * @throws AssertionError if actual is in given Dates represented as String. 122 * @throws AssertionError if one of the given date as String could not be converted to a Date. 123 */ 124 public DateAssert isNotIn(String... datesAsString) { 125 Date[] dates = new Date[datesAsString.length]; 126 for (int i = 0; i < datesAsString.length; i++) { 127 dates[i] = parse(datesAsString[i]); 128 } 129 return isNotIn(dates); 130 } 131 132 /** 133 * Same assertion as {@link Assert#isNotIn(Iterable)} but given Dates are represented as String either with ISO date 134 * format (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}).<br> 135 * Method signature could not be <code>isNotIn(Collection<String>)</code> because it would be same signature as 136 * <code>isNotIn(Collection<Date>)</code> since java collection type are erased at runtime. 137 * @param datesAsString the given Dates represented as String in default or custom date format. 138 * @return this assertion object. 139 * @throws AssertionError if actual is in given Dates represented as String. 140 * @throws AssertionError if one of the given date as String could not be converted to a Date. 141 */ 142 public DateAssert isNotInWithStringDateCollection(Collection<String> datesAsString) { 143 Collection<Date> dates = new ArrayList<Date>(datesAsString.size()); 144 for (String dateAsString : datesAsString) { 145 dates.add(parse(dateAsString)); 146 } 147 return isNotIn(dates); 148 } 149 150 /** 151 * Verifies that the actual {@code Date} is <b>strictly</b> before the given one. 152 * @param other the given Date. 153 * @return this assertion object. 154 * @throws AssertionError if the actual {@code Date} is {@code null}. 155 * @throws NullPointerException if other {@code Date} is {@code null}. 156 * @throws AssertionError if the actual {@code Date} is not strictly before the given one. 157 */ 158 public DateAssert isBefore(Date other) { 159 dates.assertIsBefore(info, actual, other); 160 return this; 161 } 162 163 /** 164 * Same assertion as {@link #isBefore(Date)} but given Date is represented as String either with ISO date format 165 * (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 166 * @param dateAsString the given Date represented as String in default or custom date format. 167 * @return this assertion object. 168 * @throws AssertionError if the actual {@code Date} is {@code null}. 169 * @throws NullPointerException if given date as String is {@code null}. 170 * @throws AssertionError if the actual {@code Date} is not strictly before the given Date represented as String. 171 * @throws AssertionError if the given date as String could not be converted to a Date. 172 */ 173 public DateAssert isBefore(String dateAsString) { 174 return isBefore(parse(dateAsString)); 175 } 176 177 /** 178 * Verifies that the actual {@code Date} is before or equals to the given one. 179 * @param other the given Date. 180 * @return this assertion object. 181 * @throws AssertionError if the actual {@code Date} is {@code null}. 182 * @throws NullPointerException if other {@code Date} is {@code null}. 183 * @throws AssertionError if the actual {@code Date} is not before or equals to the given one. 184 */ 185 public DateAssert isBeforeOrEqualsTo(Date other) { 186 dates.assertIsBeforeOrEqualsTo(info, actual, other); 187 return this; 188 } 189 190 /** 191 * Same assertion as {@link #isBeforeOrEqualsTo(Date)} but given Date is represented as String either with ISO date 192 * format (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 193 * @param dateAsString the given Date represented as String in default or custom date format. 194 * @return this assertion object. 195 * @throws AssertionError if the actual {@code Date} is {@code null}. 196 * @throws NullPointerException if given date as String is {@code null}. 197 * @throws AssertionError if the actual {@code Date} is not before or equals to the given Date represented as String. 198 * @throws AssertionError if the given date as String could not be converted to a Date. 199 */ 200 public DateAssert isBeforeOrEqualsTo(String dateAsString) { 201 return isBeforeOrEqualsTo(parse(dateAsString)); 202 } 203 204 /** 205 * Verifies that the actual {@code Date} is <b>strictly</b> after the given one. 206 * @param other the given Date. 207 * @return this assertion object. 208 * @throws AssertionError if the actual {@code Date} is {@code null}. 209 * @throws NullPointerException if other {@code Date} is {@code null}. 210 * @throws AssertionError if the actual {@code Date} is not strictly after the given one. 211 */ 212 public DateAssert isAfter(Date other) { 213 dates.assertIsAfter(info, actual, other); 214 return this; 215 } 216 217 /** 218 * Same assertion as {@link #isAfter(Date)} but given Date is represented as String either with ISO date format 219 * (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 220 * @param dateAsString the given Date represented as String in default or custom date format. 221 * @return this assertion object. 222 * @throws AssertionError if the actual {@code Date} is {@code null}. 223 * @throws NullPointerException if given date as String is {@code null}. 224 * @throws AssertionError if the actual {@code Date} is not strictly after the given Date represented as String. 225 * @throws AssertionError if the given date as String could not be converted to a Date. 226 */ 227 public DateAssert isAfter(String dateAsString) { 228 return isAfter(parse(dateAsString)); 229 } 230 231 /** 232 * Verifies that the actual {@code Date} is after or equals to the given one. 233 * @param other the given Date. 234 * @return this assertion object. 235 * @throws AssertionError if the actual {@code Date} is {@code null}. 236 * @throws NullPointerException if other {@code Date} is {@code null}. 237 * @throws AssertionError if the actual {@code Date} is not after or equals to the given one. 238 */ 239 public DateAssert isAfterOrEqualsTo(Date other) { 240 dates.assertIsAfterOrEqualsTo(info, actual, other); 241 return this; 242 } 243 244 /** 245 * Same assertion as {@link #isAfterOrEqualsTo(Date)} but given Date is represented as String either with ISO date 246 * format (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 247 * @param dateAsString the given Date represented as String in default or custom date format. 248 * @return this assertion object. 249 * @throws AssertionError if the actual {@code Date} is {@code null}. 250 * @throws NullPointerException if given date as String is {@code null}. 251 * @throws AssertionError if the actual {@code Date} is not after or equals to the given Date represented as String. 252 * @throws AssertionError if the given date as String could not be converted to a Date. 253 */ 254 public DateAssert isAfterOrEqualsTo(String dateAsString) { 255 return isAfterOrEqualsTo(parse(dateAsString)); 256 } 257 258 /** 259 * Verifies that the actual {@code Date} is in [start, end[ period (start included, end excluded). 260 * @param start the period start (inclusive), expected not to be null. 261 * @param end the period end (exclusive), expected not to be null. 262 * @return this assertion object. 263 * @throws AssertionError if the actual {@code Date} is {@code null}. 264 * @throws NullPointerException if start {@code Date} is {@code null}. 265 * @throws NullPointerException if end {@code Date} is {@code null}. 266 * @throws AssertionError if the actual {@code Date} is not in [start, end[ period. 267 */ 268 public DateAssert isBetween(Date start, Date end) { 269 return isBetween(start, end, true, false); 270 } 271 272 /** 273 * Same assertion as {@link #isBetween(Date, Date)} but given Dates are represented as String either with ISO date 274 * format (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 275 * @param start the period start (inclusive), expected not to be null. 276 * @param end the period end (exclusive), expected not to be null. 277 * @return this assertion object. 278 * @throws AssertionError if the actual {@code Date} is {@code null}. 279 * @throws NullPointerException if start Date as String is {@code null}. 280 * @throws NullPointerException if end Date as String is {@code null}. 281 * @throws AssertionError if the actual {@code Date} is not in [start, end[ period. 282 * @throws AssertionError if one of the given date as String could not be converted to a Date. 283 */ 284 public DateAssert isBetween(String start, String end) { 285 return isBetween(parse(start), parse(end)); 286 } 287 288 /** 289 * Verifies that the actual {@code Date} is in the given period defined by start and end dates.<br> 290 * To include start in the period set inclusiveStart parameter to <code>true</code>.<br> 291 * To include end in the period set inclusiveEnd parameter to <code>true</code>.<br> 292 * @param start the period start, expected not to be null. 293 * @param end the period end, expected not to be null. 294 * @param inclusiveStart wether to include start date in period. 295 * @param inclusiveEnd wether to include end date in period. 296 * @return this assertion object. 297 * @throws AssertionError if {@code actual} is {@code null}. 298 * @throws NullPointerException if start {@code Date} is {@code null}. 299 * @throws NullPointerException if end {@code Date} is {@code null}. 300 * @throws AssertionError if the actual {@code Date} is not in (start, end) period. 301 */ 302 public DateAssert isBetween(Date start, Date end, boolean inclusiveStart, boolean inclusiveEnd) { 303 dates.assertIsBetween(info, actual, start, end, inclusiveStart, inclusiveEnd); 304 return this; 305 } 306 307 /** 308 * Same assertion as {@link #isBetween(Date, Date, boolean, boolean)} but given Dates are represented as String either 309 * with ISO date format (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 310 * @param start the period start, expected not to be null. 311 * @param end the period end, expected not to be null. 312 * @param inclusiveStart wether to include start date in period. 313 * @param inclusiveEnd wether to include end date in period. 314 * @return this assertion object. 315 * @throws AssertionError if {@code actual} is {@code null}. 316 * @throws NullPointerException if start Date as String is {@code null}. 317 * @throws NullPointerException if end Date as String is {@code null}. 318 * @throws AssertionError if the actual {@code Date} is not in (start, end) period. 319 * @throws AssertionError if one of the given date as String could not be converted to a Date. 320 */ 321 public DateAssert isBetween(String start, String end, boolean inclusiveStart, boolean inclusiveEnd) { 322 dates.assertIsBetween(info, actual, parse(start), parse(end), inclusiveStart, inclusiveEnd); 323 return this; 324 } 325 326 /** 327 * Verifies that the actual {@code Date} is not in the given period defined by start and end dates.<br> 328 * To include start in the period set inclusiveStart parameter to <code>true</code>.<br> 329 * To include end in the period set inclusiveEnd parameter to <code>true</code>.<br> 330 * @param start the period start (inclusive), expected not to be null. 331 * @param end the period end (exclusive), expected not to be null. 332 * @param inclusiveStart wether to include start date in period. 333 * @param inclusiveEnd wether to include end date in period. 334 * @return this assertion object. 335 * @throws AssertionError if {@code actual} is {@code null}. 336 * @throws NullPointerException if start {@code Date} is {@code null}. 337 * @throws NullPointerException if end {@code Date} is {@code null}. 338 * @throws AssertionError if the actual {@code Date} is not in (start, end) period. 339 */ 340 public DateAssert isNotBetween(Date start, Date end, boolean inclusiveStart, boolean inclusiveEnd) { 341 dates.assertIsNotBetween(info, actual, start, end, inclusiveStart, inclusiveEnd); 342 return this; 343 } 344 345 /** 346 * Same assertion as {@link #isNotBetween(Date, Date, boolean, boolean)} but given Dates are represented as String 347 * either with ISO date format (yyyy-MM-dd) or user custom date format (set with method 348 * {@link #withDateFormat(DateFormat)}). 349 * @param start the period start (inclusive), expected not to be null. 350 * @param end the period end (exclusive), expected not to be null. 351 * @param inclusiveStart wether to include start date in period. 352 * @param inclusiveEnd wether to include end date in period. 353 * @return this assertion object. 354 * @throws AssertionError if {@code actual} is {@code null}. 355 * @throws NullPointerException if start Date as String is {@code null}. 356 * @throws NullPointerException if end Date as String is {@code null}. 357 * @throws AssertionError if the actual {@code Date} is not in (start, end) period. 358 * @throws AssertionError if one of the given date as String could not be converted to a Date. 359 */ 360 public DateAssert isNotBetween(String start, String end, boolean inclusiveStart, boolean inclusiveEnd) { 361 return isNotBetween(parse(start), parse(end), inclusiveStart, inclusiveEnd); 362 } 363 364 /** 365 * Verifies that the actual {@code Date} is not in [start, end[ period 366 * @param start the period start (inclusive), expected not to be null. 367 * @param end the period end (exclusive), expected not to be null. 368 * @return this assertion object. 369 * @throws AssertionError if the actual {@code Date} is {@code null}. 370 * @throws NullPointerException if start {@code Date} is {@code null}. 371 * @throws NullPointerException if end {@code Date} is {@code null}. 372 * @throws AssertionError if the actual {@code Date} is in [start, end[ period. 373 * @throws AssertionError if one of the given date as String could not be converted to a Date. 374 */ 375 public DateAssert isNotBetween(Date start, Date end) { 376 return isNotBetween(start, end, true, false); 377 } 378 379 /** 380 * Same assertion as {@link #isNotBetween(Date, Date)} but given Dates are represented as String either with ISO date 381 * format (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 382 * @param start the period start (inclusive), expected not to be null. 383 * @param end the period end (exclusive), expected not to be null. 384 * @return this assertion object. 385 * @throws AssertionError if the actual {@code Date} is {@code null}. 386 * @throws NullPointerException if start Date as String is {@code null}. 387 * @throws NullPointerException if end Date as String is {@code null}. 388 * @throws AssertionError if the actual {@code Date} is in [start, end[ period. 389 * @throws AssertionError if one of the given date as String could not be converted to a Date. 390 */ 391 public DateAssert isNotBetween(String start, String end) { 392 return isNotBetween(parse(start), parse(end), true, false); 393 } 394 395 /** 396 * Verifies that the actual {@code Date} is strictly in the past. 397 * @return this assertion object. 398 * @throws AssertionError if the actual {@code Date} is {@code null}. 399 * @throws AssertionError if the actual {@code Date} is not in the past. 400 */ 401 public DateAssert isInThePast() { 402 dates.assertIsInThePast(info, actual); 403 return this; 404 } 405 406 /** 407 * Verifies that the actual {@code Date} is today, that is matching current year, month and day (no check on hour, 408 * minute, second, milliseconds). 409 * @return this assertion object. 410 * @throws AssertionError if the actual {@code Date} is {@code null}. 411 * @throws AssertionError if the actual {@code Date} is not today. 412 */ 413 public DateAssert isToday() { 414 dates.assertIsToday(info, actual); 415 return this; 416 } 417 418 /** 419 * Verifies that the actual {@code Date} is strictly in the future. 420 * @return this assertion object. 421 * @throws AssertionError if the actual {@code Date} is {@code null}. 422 * @throws AssertionError if the actual {@code Date} is not in the future. 423 */ 424 public DateAssert isInTheFuture() { 425 dates.assertIsInTheFuture(info, actual); 426 return this; 427 } 428 429 /** 430 * Verifies that the actual {@code Date} is <b>strictly</b> before the given year. 431 * @param year the year to compare actual year to 432 * @return this assertion object. 433 * @throws AssertionError if the actual {@code Date} is {@code null}. 434 * @throws AssertionError if the actual {@code Date} year is after or equals to the given year. 435 */ 436 public DateAssert isBeforeYear(int year) { 437 dates.assertIsBeforeYear(info, actual, year); 438 return this; 439 } 440 441 /** 442 * Verifies that the actual {@code Date} is <b>strictly</b> after the given year. 443 * @param year the year to compare actual year to 444 * @return this assertion object. 445 * @throws AssertionError if the actual {@code Date} is {@code null}. 446 * @throws AssertionError if the actual {@code Date} year is before or equals to the given year. 447 */ 448 public DateAssert isAfterYear(int year) { 449 dates.assertIsAfterYear(info, actual, year); 450 return this; 451 } 452 453 /** 454 * Verifies that the actual {@code Date} year is equal to the given year. 455 * <p> 456 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 457 * 458 * @param year the year to compare actual year to 459 * @return this assertion object. 460 * @throws AssertionError if the actual {@code Date} is {@code null}. 461 * @throws AssertionError if the actual {@code Date} year is not equal to the given year. 462 */ 463 public DateAssert isWithinYear(int year) { 464 dates.assertIsWithinYear(info, actual, year); 465 return this; 466 } 467 468 /** 469 * Verifies that the actual {@code Date} month is equal to the given month, <b>month value starting at 1</b> 470 * (January=1, February=2, ...). 471 * <p> 472 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 473 * 474 * @param month the month to compare actual month to, <b>month value starting at 1</b> (January=1, February=2, ...). 475 * @return this assertion object. 476 * @throws AssertionError if the actual {@code Date} is {@code null}. 477 * @throws AssertionError if the actual {@code Date} month is not equal to the given month. 478 */ 479 public DateAssert isWithinMonth(int month) { 480 dates.assertIsWithinMonth(info, actual, month); 481 return this; 482 } 483 484 /** 485 * Verifies that the actual {@code Date} day of month is equal to the given day of month. 486 * <p> 487 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 488 * 489 * @param dayOfMonth the day of month to compare actual day of month to 490 * @return this assertion object. 491 * @throws AssertionError if the actual {@code Date} is {@code null}. 492 * @throws AssertionError if the actual {@code Date} month is not equal to the given day of month. 493 */ 494 public DateAssert isWithinDayOfMonth(int dayOfMonth) { 495 dates.assertIsWithinDayOfMonth(info, actual, dayOfMonth); 496 return this; 497 } 498 499 /** 500 * Verifies that the actual {@code Date} day of week is equal to the given day of week (see 501 * {@link Calendar#DAY_OF_WEEK} for valid values). 502 * <p> 503 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 504 * 505 * @param dayOfWeek the day of week to compare actual day of week to, see {@link Calendar#DAY_OF_WEEK} for valid 506 * values 507 * @return this assertion object. 508 * @throws AssertionError if the actual {@code Date} is {@code null}. 509 * @throws AssertionError if the actual {@code Date} week is not equal to the given day of week. 510 */ 511 public DateAssert isWithinDayOfWeek(int dayOfWeek) { 512 dates.assertIsWithinDayOfWeek(info, actual, dayOfWeek); 513 return this; 514 } 515 516 /** 517 * Verifies that the actual {@code Date} hour od day is equal to the given hour of day (24-hour clock). 518 * <p> 519 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 520 * 521 * @param hourOfDay the hour of day to compare actual hour of day to (24-hour clock) 522 * @return this assertion object. 523 * @throws AssertionError if the actual {@code Date} is {@code null}. 524 * @throws AssertionError if the actual {@code Date} hour is not equal to the given hour. 525 */ 526 public DateAssert isWithinHourOfDay(int hourOfDay) { 527 dates.assertIsWithinHourOfDay(info, actual, hourOfDay); 528 return this; 529 } 530 531 /** 532 * Verifies that the actual {@code Date} minute is equal to the given minute. 533 * <p> 534 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 535 * 536 * @param minute the minute to compare actual minute to 537 * @return this assertion object. 538 * @throws AssertionError if the actual {@code Date} is {@code null}. 539 * @throws AssertionError if the actual {@code Date} minute is not equal to the given minute. 540 */ 541 public DateAssert isWithinMinute(int minute) { 542 dates.assertIsWithinMinute(info, actual, minute); 543 return this; 544 } 545 546 /** 547 * Verifies that the actual {@code Date} second is equal to the given second. 548 * <p> 549 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 550 * 551 * @param second the second to compare actual second to 552 * @return this assertion object. 553 * @throws AssertionError if the actual {@code Date} is {@code null}. 554 * @throws AssertionError if the actual {@code Date} second is not equal to the given second. 555 */ 556 public DateAssert isWithinSecond(int second) { 557 dates.assertIsWithinSecond(info, actual, second); 558 return this; 559 } 560 561 /** 562 * Verifies that the actual {@code Date} millisecond is equal to the given millisecond. 563 * <p> 564 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 565 * 566 * @param millisecond the millisecond to compare actual millisecond to 567 * @return this assertion object. 568 * @throws AssertionError if the actual {@code Date} is {@code null}. 569 * @throws AssertionError if the actual {@code Date} millisecond is not equal to the given millisecond. 570 */ 571 public DateAssert isWithinMillisecond(int millisecond) { 572 dates.assertIsWithinMillisecond(info, actual, millisecond); 573 return this; 574 } 575 576 /** 577 * Verifies that actual and given {@code Date} are in the same year. 578 * <p> 579 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 580 * 581 * @param other the given {@code Date} to compare actual {@code Date} to. 582 * @return this assertion object. 583 * @throws NullPointerException if {@code Date} parameter is {@code null}. 584 * @throws AssertionError if the actual {@code Date} is {@code null}. 585 * @throws AssertionError if actual and given {@code Date} are not in the same year. 586 */ 587 public DateAssert isInSameYearAs(Date other) { 588 dates.assertIsInSameYearAs(info, actual, other); 589 return this; 590 } 591 592 /** 593 * Same assertion as {@link #isInSameYearAs(Date)} but given Date is represented as String either with ISO date format 594 * (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 595 * @param dateAsString the given Date represented as String in default or custom date format. 596 * @return this assertion object. 597 * @throws NullPointerException if dateAsString parameter is {@code null}. 598 * @throws AssertionError if the actual {@code Date} is {@code null}. 599 * @throws AssertionError if actual and given Date represented as String are not in the same year. 600 * @throws AssertionError if the given date as String could not be converted to a Date. 601 */ 602 public DateAssert isInSameYearAs(String dateAsString) { 603 return isInSameYearAs(parse(dateAsString)); 604 } 605 606 /** 607 * Verifies that actual and given {@code Date} are chronologically in the same month (and thus in the same year). 608 * <p> 609 * If you want to compare month only (without year), use : 610 * <code>assertThat(myDate).isWithinMonth(monthOf(otherDate))</code><br> 611 * See {@link org.fest.util.Dates#monthOf(Date)} to get the month of a given Date. 612 * <p> 613 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 614 * 615 * @param other the given {@code Date} to compare actual {@code Date} to. 616 * @return this assertion object. 617 * @throws NullPointerException if {@code Date} parameter is {@code null}. 618 * @throws AssertionError if the actual {@code Date} is {@code null}. 619 * @throws AssertionError if actual and given {@code Date} are not in the same month. 620 */ 621 public DateAssert isInSameMonthAs(Date other) { 622 dates.assertIsInSameMonthAs(info, actual, other); 623 return this; 624 } 625 626 /** 627 * Same assertion as {@link #isInSameMonthAs(Date)} but given Date is represented as String either with ISO date 628 * format (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 629 * @param dateAsString the given Date represented as String in default or custom date format. 630 * @return this assertion object. 631 * @throws NullPointerException if dateAsString parameter is {@code null}. 632 * @throws AssertionError if the actual {@code Date} is {@code null}. 633 * @throws AssertionError if actual and given {@code Date} are not in the same month. 634 */ 635 public DateAssert isInSameMonthAs(String dateAsString) { 636 return isInSameMonthAs(parse(dateAsString)); 637 } 638 639 /** 640 * Verifies that actual and given {@code Date} are chronologically in the same day of month (and thus in the same 641 * month and year). 642 * <p> 643 * If you want to compare day of month only (without month and year), you could write : 644 * <code>assertThat(myDate).isWithinDayOfMonth(dayOfMonthOf(otherDate))</code><br> 645 * see {@link org.fest.util.Dates#dayOfMonthOf(Date)} to get the day of month of a given Date. 646 * <p> 647 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 648 * 649 * @param other the given {@code Date} to compare actual {@code Date} to. 650 * @return this assertion object. 651 * @throws NullPointerException if {@code Date} parameter is {@code null}. 652 * @throws AssertionError if the actual {@code Date} is {@code null}. 653 * @throws AssertionError if actual and given {@code Date} are not in the same day of month. 654 */ 655 public DateAssert isInSameDayAs(Date other) { 656 dates.assertIsInSameDayAs(info, actual, other); 657 return this; 658 } 659 660 /** 661 * Same assertion as {@link #isInSameDayAs(Date)} but given Date is represented as String either with ISO date format 662 * (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 663 * @param dateAsString the given Date represented as String in default or custom date format. 664 * @return this assertion object. 665 * @throws NullPointerException if dateAsString parameter is {@code null}. 666 * @throws AssertionError if the actual {@code Date} is {@code null}. 667 * @throws AssertionError if actual and given {@code Date} are not in the same day of month. 668 */ 669 public DateAssert isInSameDayAs(String dateAsString) { 670 return isInSameDayAs(parse(dateAsString)); 671 } 672 673 /** 674 * Verifies that actual and given {@code Date} are chronologically in the same hour (and thus in the same day, month 675 * and year). 676 * <p> 677 * If you want to compare hour only (without day, month and year), you could write : 678 * <code>assertThat(myDate).isWithinHour(hourOfDayOf(otherDate))</code><br> 679 * see {@link org.fest.util.Dates#hourOfDay(Date)} to get the hour of a given Date. 680 * <p> 681 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 682 * 683 * @param other the given {@code Date} to compare actual {@code Date} to. 684 * @return this assertion object. 685 * @throws NullPointerException if {@code Date} parameter is {@code null}. 686 * @throws AssertionError if the actual {@code Date} is {@code null}. 687 * @throws AssertionError if actual and given {@code Date} are not in the same hour. 688 */ 689 public DateAssert isInSameHourAs(Date other) { 690 dates.assertIsInSameHourAs(info, actual, other); 691 return this; 692 } 693 694 /** 695 * Same assertion as {@link #isInSameHourAs(Date)} but given Date is represented as String either with ISO date format 696 * (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 697 * @param dateAsString the given Date represented as String in default or custom date format. 698 * @return this assertion object. 699 * @throws NullPointerException if dateAsString parameter is {@code null}. 700 * @throws AssertionError if the actual {@code Date} is {@code null}. 701 * @throws AssertionError if actual and given {@code Date} are not in the same hour. 702 */ 703 public DateAssert isInSameHourAs(String dateAsString) { 704 return isInSameHourAs(parse(dateAsString)); 705 } 706 707 /** 708 * Verifies that actual and given {@code Date} are chronologically in the same minute (and thus in the same hour, day, 709 * month and year). 710 * <p> 711 * If you want to compare minute only (without hour, day, month and year), you could write : 712 * <code>assertThat(myDate).isWithinMinute(minuteOf(otherDate))</code><br> 713 * see {@link org.fest.util.Dates#minuteOf(Date)} to get the minute of a given Date. 714 * <p> 715 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 716 * 717 * @param other the given {@code Date} to compare actual {@code Date} to. 718 * @return this assertion object. 719 * @throws NullPointerException if {@code Date} parameter is {@code null}. 720 * @throws AssertionError if the actual {@code Date} is {@code null}. 721 * @throws AssertionError if actual and given {@code Date} are not in the same minute. 722 */ 723 public DateAssert isInSameMinuteAs(Date other) { 724 dates.assertIsInSameMinuteAs(info, actual, other); 725 return this; 726 } 727 728 /** 729 * Same assertion as {@link #isInSameMinuteAs(Date)} but given Date is represented as String either with ISO date 730 * format (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 731 * @param dateAsString the given Date represented as String in default or custom date format. 732 * @return this assertion object. 733 * @throws NullPointerException if dateAsString parameter is {@code null}. 734 * @throws AssertionError if the actual {@code Date} is {@code null}. 735 * @throws AssertionError if actual and given {@code Date} are not in the same minute. 736 */ 737 public DateAssert isInSameMinuteAs(String dateAsString) { 738 return isInSameMinuteAs(parse(dateAsString)); 739 } 740 741 /** 742 * Verifies that actual and given {@code Date} are chronologically in the same second (and thus in the same minute, 743 * hour, day, month and year). 744 * <p> 745 * If you want to compare second only (without minute, hour, day, month and year), you could write : 746 * <code>assertThat(myDate).isWithinSecond(secondOf(otherDate))</code><br> 747 * see {@link org.fest.util.Dates#secondOf(Date)} to get the second of a given Date. 748 * <p> 749 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 750 * 751 * @param other the given {@code Date} to compare actual {@code Date} to. 752 * @return this assertion object. 753 * @throws NullPointerException if {@code Date} parameter is {@code null}. 754 * @throws AssertionError if the actual {@code Date} is {@code null}. 755 * @throws AssertionError if actual and given {@code Date} are not in the same second. 756 */ 757 public DateAssert isInSameSecondAs(Date other) { 758 dates.assertIsInSameSecondAs(info, actual, other); 759 return this; 760 } 761 762 /** 763 * Same assertion as {@link #isInSameSecondAs(Date)} but given Date is represented as String either with ISO date 764 * format (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 765 * @param dateAsString the given Date represented as String in default or custom date format. 766 * @return this assertion object. 767 * @throws NullPointerException if dateAsString parameter is {@code null}. 768 * @throws AssertionError if the actual {@code Date} is {@code null}. 769 * @throws AssertionError if actual and given {@code Date} are not in the same second. 770 */ 771 public DateAssert isInSameSecondAs(String dateAsString) { 772 return isInSameSecondAs(parse(dateAsString)); 773 } 774 775 /** 776 * Verifies that the actual {@code Date} is close to the other date by less than delta (expressed in milliseconds), if 777 * difference is equals to delta it's ok. 778 * <p> 779 * One can use handy {@link TimeUnit} to convert a duration in milliseconds, for example you can express a delta of 5 seconds with 780 * <code>TimeUnit.SECONDS.toMillis(5)</code>. 781 * <p> 782 * Note that using a custom comparator has no effect on this assertion (see {@link #usingComparator(Comparator)}. 783 * @param other the date to compare actual to 784 * @param deltaInMilliseconds the delta used for date comparison, expressed in milliseconds 785 * @return this assertion object. 786 * @throws NullPointerException if {@code Date} parameter is {@code null}. 787 * @throws AssertionError if the actual {@code Date} is {@code null}. 788 * @throws AssertionError if the actual {@code Date} week is not close to the given date by less than delta. 789 */ 790 public DateAssert isCloseTo(Date other, long deltaInMilliseconds) { 791 dates.assertIsCloseTo(info, actual, other, deltaInMilliseconds); 792 return this; 793 } 794 795 /** 796 * Same assertion as {@link #isCloseTo(Date, long)} but given Date is represented as String either with ISO date 797 * format (yyyy-MM-dd) or user custom date format (set with method {@link #withDateFormat(DateFormat)}). 798 * @param dateAsString the given Date represented as String in default or custom date format. 799 * @param deltaInMilliseconds the delta used for date comparison, expressed in milliseconds 800 * @return this assertion object. 801 * @throws NullPointerException if dateAsString parameter is {@code null}. 802 * @throws AssertionError if the actual {@code Date} is {@code null}. 803 * @throws AssertionError if the actual {@code Date} week is not close to the given date by less than delta. 804 */ 805 public DateAssert isCloseTo(String dateAsString, long deltaInMilliseconds) { 806 return isCloseTo(parse(dateAsString), deltaInMilliseconds); 807 } 808 809 /** 810 * For String based Date assertions like {@link #isBefore(String)}, given String is expected to follow the default 811 * Date format, that is ISO 8601 format : "yyyy-MM-dd". 812 * <p> 813 * With this method, user can specify its own date format, replacing the current date format for all future Date 814 * assertions in the test suite (i.e. not only the current assertions) since custom DateFormat is stored in a static 815 * field. 816 * <p> 817 * To revert to default format simply call {@link #withIsoDateFormat()}. 818 * 819 * @param userCustomDateFormat the new Date format used for String based Date assertions. 820 * @return this assertion object. 821 */ 822 public DateAssert withDateFormat(DateFormat userCustomDateFormat) { 823 useDateFormat(userCustomDateFormat); 824 return this; 825 } 826 827 /** 828 * For String based Date assertions like {@link #isBefore(String)}, given String is expected to follow the default 829 * Date format, that is ISO 8601 format : "yyyy-MM-dd". 830 * <p> 831 * With this method, user can specify its own date format, replacing the current date format for all future Date 832 * assertions in the test suite (i.e. not only the current assertions) since custom DateFormat is stored in a static 833 * field. 834 * <p> 835 * To revert to default format simply call {@link #useIsoDateFormat()} (static method) or {@link #withIsoDateFormat()}. 836 * 837 * @param userCustomDateFormat the new Date format used for String based Date assertions. 838 */ 839 public static void useDateFormat(DateFormat userCustomDateFormat) { 840 if (userCustomDateFormat == null) throw new NullPointerException("The given date format should not be null"); 841 dateFormat = userCustomDateFormat; 842 } 843 844 /** 845 * Use ISO 8601 date format ("yyyy-MM-dd") for String based Date assertions. 846 * @return this assertion object. 847 */ 848 public DateAssert withIsoDateFormat() { 849 useIsoDateFormat(); 850 return this; 851 } 852 853 /** 854 * Use ISO 8601 date format ("yyyy-MM-dd") for String based Date assertions. 855 */ 856 public static void useIsoDateFormat() { 857 dateFormat = ISO_DATE_FORMAT; 858 } 859 860 /** 861 * Utillity method to parse a Date with {@link #dateFormat}, note that it is thread safe.<br> 862 * Returns <code>null</code> if dateAsString parameter is <code>null</code>. 863 * @param dateAsString the string to parse as a Date with {@link #dateFormat} 864 * @return the corrresponding Date, null if dateAsString parameter is null. 865 * @throws AssertionError if the string can't be parsed as a Date 866 */ 867 private static Date parse(String dateAsString) { 868 if (dateAsString == null) { return null; } 869 try { 870 // synchronized is used because SimpleDateFormat which is not thread safe (sigh). 871 synchronized (dateFormat) { 872 return dateFormat.parse(dateAsString); 873 } 874 } catch (ParseException e) { 875 throw Failures.instance().failure("Failed to parse " + dateAsString + " with date format " + dateFormat); 876 } 877 } 878 879 @Override 880 public DateAssert usingComparator(Comparator<?> customComparator) { 881 super.usingComparator(customComparator); 882 this.dates = new Dates(new ComparatorBasedComparisonStrategy(customComparator)); 883 return myself; 884 } 885 886 @Override 887 public DateAssert usingDefaultComparator() { 888 super.usingDefaultComparator(); 889 this.dates = Dates.instance(); 890 return myself; 891 } 892 }