1 // Written in the D programming language 2 3 /++ 4 License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 5 Authors: Jonathan M Davis 6 Source: $(PHOBOSSRC std/datetime/_interval.d) 7 +/ 8 module std.datetime.interval; 9 10 import core.time : Duration, dur; 11 import std.datetime.date : AllowDayOverflow, DateTimeException, daysToDayOfWeek, 12 DayOfWeek, isTimePoint, Month; 13 import std.exception : enforce; 14 import std.traits : isIntegral, Unqual; 15 import std.typecons : Flag; 16 17 version (unittest) import std.exception : assertThrown; 18 19 20 /++ 21 Indicates a direction in time. One example of its use is $(LREF Interval)'s 22 $(LREF expand) function which uses it to indicate whether the interval 23 should be expanded backwards (into the past), forwards (into the future), or 24 both. 25 +/ 26 enum Direction 27 { 28 /// Backward. 29 bwd, 30 31 /// Forward. 32 fwd, 33 34 /// Both backward and forward. 35 both 36 } 37 38 39 /++ 40 Used to indicate whether $(D popFront) should be called immediately upon 41 creating a range. The idea is that for some functions used to generate a 42 range for an interval, $(D front) is not necessarily a time point which 43 would ever be generated by the range (e.g. if the range were every Sunday 44 within an interval, but the interval started on a Monday), so there needs 45 to be a way to deal with that. To get the first time point in the range to 46 match what the function generates, then use $(D PopFirst.yes) to indicate 47 that the range should have $(D popFront) called on it before the range is 48 returned so that $(D front) is a time point which the function would 49 generate. To let the first time point not match the generator function, 50 use $(D PopFront.no). 51 52 For instance, if the function used to generate a range of time points 53 generated successive Easters (i.e. you're iterating over all of the Easters 54 within the interval), the initial date probably isn't an Easter. Using 55 $(D PopFirst.yes) would tell the function which returned the range that 56 $(D popFront) was to be called so that front would then be an Easter - the 57 next one generated by the function (which when iterating forward would be 58 the Easter following the original $(D front), while when iterating backward, 59 it would be the Easter prior to the original $(D front)). If 60 $(D PopFirst.no) were used, then $(D front) would remain the original time 61 point and it would not necessarily be a time point which would be generated 62 by the range-generating function (which in many cases is exactly what is 63 desired - e.g. if iterating over every day starting at the beginning of the 64 interval). 65 66 If set to $(D PopFirst.no), then popFront is not called before returning 67 the range. 68 69 Otherwise, if set to $(D PopFirst.yes), then popFront is called before 70 returning the range. 71 +/ 72 alias PopFirst = Flag!"popFirst"; 73 74 75 /++ 76 Represents an interval of time. 77 78 An $(D Interval) has a starting point and an end point. The interval of time 79 is therefore the time starting at the starting point up to, but not 80 including, the end point. e.g. 81 82 $(BOOKTABLE, 83 $(TR $(TD [January 5th, 2010 - March 10th, 2010$(RPAREN))) 84 $(TR $(TD [05:00:30 - 12:00:00$(RPAREN))) 85 $(TR $(TD [1982-01-04T08:59:00 - 2010-07-04T12:00:00$(RPAREN))) 86 ) 87 88 A range can be obtained from an $(D Interval), allowing iteration over 89 that interval, with the exact time points which are iterated over depending 90 on the function which generates the range. 91 +/ 92 struct Interval(TP) 93 { 94 public: 95 96 /++ 97 Params: 98 begin = The time point which begins the interval. 99 end = The time point which ends (but is not included in) the 100 interval. 101 102 Throws: 103 $(REF DateTimeException,std,datetime,date) if $(D_PARAM end) is 104 before $(D_PARAM begin). 105 106 Example: 107 -------------------- 108 Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 109 -------------------- 110 +/ 111 this(U)(in TP begin, in U end) pure 112 if (is(Unqual!TP == Unqual!U)) 113 { 114 if (!_valid(begin, end)) 115 throw new DateTimeException("Arguments would result in an invalid Interval."); 116 _begin = cast(TP) begin; 117 _end = cast(TP) end; 118 } 119 120 121 /++ 122 Params: 123 begin = The time point which begins the interval. 124 duration = The duration from the starting point to the end point. 125 126 Throws: 127 $(REF DateTimeException,std,datetime,date) if the resulting 128 $(D end) is before $(D begin). 129 130 Example: 131 -------------------- 132 assert(Interval!Date(Date(1996, 1, 2), dur!"days"(3)) == 133 Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5))); 134 -------------------- 135 +/ 136 this(D)(in TP begin, in D duration) pure 137 if (__traits(compiles, begin + duration)) 138 { 139 _begin = cast(TP) begin; 140 _end = begin + duration; 141 if (!_valid(_begin, _end)) 142 throw new DateTimeException("Arguments would result in an invalid Interval."); 143 } 144 145 146 /++ 147 Params: 148 rhs = The $(LREF Interval) to assign to this one. 149 +/ 150 ref Interval opAssign(const ref Interval rhs) pure nothrow 151 { 152 _begin = cast(TP) rhs._begin; 153 _end = cast(TP) rhs._end; 154 return this; 155 } 156 157 158 /++ 159 Params: 160 rhs = The $(LREF Interval) to assign to this one. 161 +/ 162 ref Interval opAssign(Interval rhs) pure nothrow 163 { 164 _begin = cast(TP) rhs._begin; 165 _end = cast(TP) rhs._end; 166 return this; 167 } 168 169 170 /++ 171 The starting point of the interval. It is included in the interval. 172 173 Example: 174 -------------------- 175 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == 176 Date(1996, 1, 2)); 177 -------------------- 178 +/ 179 @property TP begin() const pure nothrow 180 { 181 return cast(TP) _begin; 182 } 183 184 185 /++ 186 The starting point of the interval. It is included in the interval. 187 188 Params: 189 timePoint = The time point to set $(D begin) to. 190 191 Throws: 192 $(REF DateTimeException,std,datetime,date) if the resulting 193 interval would be invalid. 194 +/ 195 @property void begin(TP timePoint) pure 196 { 197 if (!_valid(timePoint, _end)) 198 throw new DateTimeException("Arguments would result in an invalid Interval."); 199 _begin = timePoint; 200 } 201 202 203 /++ 204 The end point of the interval. It is excluded from the interval. 205 206 Example: 207 -------------------- 208 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == 209 Date(2012, 3, 1)); 210 -------------------- 211 +/ 212 @property TP end() const pure nothrow 213 { 214 return cast(TP) _end; 215 } 216 217 218 /++ 219 The end point of the interval. It is excluded from the interval. 220 221 Params: 222 timePoint = The time point to set end to. 223 224 Throws: 225 $(REF DateTimeException,std,datetime,date) if the resulting 226 interval would be invalid. 227 +/ 228 @property void end(TP timePoint) pure 229 { 230 if (!_valid(_begin, timePoint)) 231 throw new DateTimeException("Arguments would result in an invalid Interval."); 232 _end = timePoint; 233 } 234 235 236 /++ 237 Returns the duration between $(D begin) and $(D end). 238 239 Example: 240 -------------------- 241 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == 242 dur!"days"(5903)); 243 -------------------- 244 +/ 245 @property auto length() const pure nothrow 246 { 247 return _end - _begin; 248 } 249 250 251 /++ 252 Whether the interval's length is 0, that is, whether $(D begin == end). 253 254 Example: 255 -------------------- 256 assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty); 257 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty); 258 -------------------- 259 +/ 260 @property bool empty() const pure nothrow 261 { 262 return _begin == _end; 263 } 264 265 266 /++ 267 Whether the given time point is within this interval. 268 269 Params: 270 timePoint = The time point to check for inclusion in this interval. 271 272 Throws: 273 $(REF DateTimeException,std,datetime,date) if this interval is 274 empty. 275 276 Example: 277 -------------------- 278 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 279 Date(1994, 12, 24))); 280 281 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 282 Date(2000, 1, 5))); 283 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 284 Date(2012, 3, 1))); 285 -------------------- 286 +/ 287 bool contains(in TP timePoint) const pure 288 { 289 _enforceNotEmpty(); 290 return timePoint >= _begin && timePoint < _end; 291 } 292 293 294 /++ 295 Whether the given interval is completely within this interval. 296 297 Params: 298 interval = The interval to check for inclusion in this interval. 299 300 Throws: 301 $(REF DateTimeException,std,datetime,date) if either interval is 302 empty. 303 304 Example: 305 -------------------- 306 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 307 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 308 309 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 310 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 311 312 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 313 Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); 314 -------------------- 315 +/ 316 bool contains(in Interval interval) const pure 317 { 318 _enforceNotEmpty(); 319 interval._enforceNotEmpty(); 320 return interval._begin >= _begin && 321 interval._begin < _end && 322 interval._end <= _end; 323 } 324 325 326 /++ 327 Whether the given interval is completely within this interval. 328 329 Always returns false (unless this interval is empty), because an 330 interval going to positive infinity can never be contained in a finite 331 interval. 332 333 Params: 334 interval = The interval to check for inclusion in this interval. 335 336 Throws: 337 $(REF DateTimeException,std,datetime,date) if this interval is 338 empty. 339 340 Example: 341 -------------------- 342 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 343 PosInfInterval!Date(Date(1999, 5, 4)))); 344 -------------------- 345 +/ 346 bool contains(in PosInfInterval!TP interval) const pure 347 { 348 _enforceNotEmpty(); 349 return false; 350 } 351 352 353 /++ 354 Whether the given interval is completely within this interval. 355 356 Always returns false (unless this interval is empty), because an 357 interval beginning at negative infinity can never be contained in a 358 finite interval. 359 360 Params: 361 interval = The interval to check for inclusion in this interval. 362 363 Throws: 364 $(REF DateTimeException,std,datetime,date) if this interval is 365 empty. 366 367 Example: 368 -------------------- 369 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 370 NegInfInterval!Date(Date(1996, 5, 4)))); 371 -------------------- 372 +/ 373 bool contains(in NegInfInterval!TP interval) const pure 374 { 375 _enforceNotEmpty(); 376 return false; 377 } 378 379 380 /++ 381 Whether this interval is before the given time point. 382 383 Params: 384 timePoint = The time point to check whether this interval is before 385 it. 386 387 Throws: 388 $(REF DateTimeException,std,datetime,date) if this interval is 389 empty. 390 391 Example: 392 -------------------- 393 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 394 Date(1994, 12, 24))); 395 396 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 397 Date(2000, 1, 5))); 398 399 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 400 Date(2012, 3, 1))); 401 -------------------- 402 +/ 403 bool isBefore(in TP timePoint) const pure 404 { 405 _enforceNotEmpty(); 406 return _end <= timePoint; 407 } 408 409 410 /++ 411 Whether this interval is before the given interval and does not 412 intersect with it. 413 414 Params: 415 interval = The interval to check for against this interval. 416 417 Throws: 418 $(REF DateTimeException,std,datetime,date) if either interval is 419 empty. 420 421 Example: 422 -------------------- 423 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 424 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 425 426 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 427 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 428 429 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 430 Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1)))); 431 -------------------- 432 +/ 433 bool isBefore(in Interval interval) const pure 434 { 435 _enforceNotEmpty(); 436 interval._enforceNotEmpty(); 437 return _end <= interval._begin; 438 } 439 440 441 /++ 442 Whether this interval is before the given interval and does not 443 intersect with it. 444 445 Params: 446 interval = The interval to check for against this interval. 447 448 Throws: 449 $(REF DateTimeException,std,datetime,date) if this interval is 450 empty. 451 452 Example: 453 -------------------- 454 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 455 PosInfInterval!Date(Date(1999, 5, 4)))); 456 457 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 458 PosInfInterval!Date(Date(2013, 3, 7)))); 459 -------------------- 460 +/ 461 bool isBefore(in PosInfInterval!TP interval) const pure 462 { 463 _enforceNotEmpty(); 464 return _end <= interval._begin; 465 } 466 467 468 /++ 469 Whether this interval is before the given interval and does not 470 intersect with it. 471 472 Always returns false (unless this interval is empty) because a finite 473 interval can never be before an interval beginning at negative infinity. 474 475 Params: 476 interval = The interval to check for against this interval. 477 478 Throws: 479 $(REF DateTimeException,std,datetime,date) if this interval is 480 empty. 481 482 Example: 483 -------------------- 484 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 485 NegInfInterval!Date(Date(1996, 5, 4)))); 486 -------------------- 487 +/ 488 bool isBefore(in NegInfInterval!TP interval) const pure 489 { 490 _enforceNotEmpty(); 491 return false; 492 } 493 494 495 /++ 496 Whether this interval is after the given time point. 497 498 Params: 499 timePoint = The time point to check whether this interval is after 500 it. 501 502 Throws: 503 $(REF DateTimeException,std,datetime,date) if this interval is 504 empty. 505 506 Example: 507 -------------------- 508 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 509 Date(1994, 12, 24))); 510 511 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 512 Date(2000, 1, 5))); 513 514 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 515 Date(2012, 3, 1))); 516 -------------------- 517 +/ 518 bool isAfter(in TP timePoint) const pure 519 { 520 _enforceNotEmpty(); 521 return timePoint < _begin; 522 } 523 524 525 /++ 526 Whether this interval is after the given interval and does not intersect 527 it. 528 529 Params: 530 interval = The interval to check against this interval. 531 532 Throws: 533 $(REF DateTimeException,std,datetime,date) if either interval is 534 empty. 535 536 Example: 537 -------------------- 538 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 539 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 540 541 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 542 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 543 544 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 545 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 546 -------------------- 547 +/ 548 bool isAfter(in Interval interval) const pure 549 { 550 _enforceNotEmpty(); 551 interval._enforceNotEmpty(); 552 return _begin >= interval._end; 553 } 554 555 556 /++ 557 Whether this interval is after the given interval and does not intersect 558 it. 559 560 Always returns false (unless this interval is empty) because a finite 561 interval can never be after an interval going to positive infinity. 562 563 Params: 564 interval = The interval to check against this interval. 565 566 Throws: 567 $(REF DateTimeException,std,datetime,date) if this interval is 568 empty. 569 570 Example: 571 -------------------- 572 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 573 PosInfInterval!Date(Date(1999, 5, 4)))); 574 -------------------- 575 +/ 576 bool isAfter(in PosInfInterval!TP interval) const pure 577 { 578 _enforceNotEmpty(); 579 return false; 580 } 581 582 583 /++ 584 Whether this interval is after the given interval and does not intersect 585 it. 586 587 Params: 588 interval = The interval to check against this interval. 589 590 Throws: 591 $(REF DateTimeException,std,datetime,date) if this interval is 592 empty. 593 594 Example: 595 -------------------- 596 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 597 NegInfInterval!Date(Date(1996, 1, 2)))); 598 -------------------- 599 +/ 600 bool isAfter(in NegInfInterval!TP interval) const pure 601 { 602 _enforceNotEmpty(); 603 return _begin >= interval._end; 604 } 605 606 607 /++ 608 Whether the given interval overlaps this interval. 609 610 Params: 611 interval = The interval to check for intersection with this interval. 612 613 Throws: 614 $(REF DateTimeException,std,datetime,date) if either interval is 615 empty. 616 617 Example: 618 -------------------- 619 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 620 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 621 622 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 623 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 624 625 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 626 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 627 -------------------- 628 +/ 629 bool intersects(in Interval interval) const pure 630 { 631 _enforceNotEmpty(); 632 interval._enforceNotEmpty(); 633 return interval._begin < _end && interval._end > _begin; 634 } 635 636 637 /++ 638 Whether the given interval overlaps this interval. 639 640 Params: 641 interval = The interval to check for intersection with this interval. 642 643 Throws: 644 $(REF DateTimeException,std,datetime,date) if this interval is 645 empty. 646 647 Example: 648 -------------------- 649 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 650 PosInfInterval!Date(Date(1999, 5, 4)))); 651 652 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 653 PosInfInterval!Date(Date(2012, 3, 1)))); 654 -------------------- 655 +/ 656 bool intersects(in PosInfInterval!TP interval) const pure 657 { 658 _enforceNotEmpty(); 659 return _end > interval._begin; 660 } 661 662 663 /++ 664 Whether the given interval overlaps this interval. 665 666 Params: 667 interval = The interval to check for intersection with this interval. 668 669 Throws: 670 $(REF DateTimeException,std,datetime,date) if this interval is 671 empty. 672 673 Example: 674 -------------------- 675 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 676 NegInfInterval!Date(Date(1996, 1, 2)))); 677 678 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 679 NegInfInterval!Date(Date(2000, 1, 2)))); 680 -------------------- 681 +/ 682 bool intersects(in NegInfInterval!TP interval) const pure 683 { 684 _enforceNotEmpty(); 685 return _begin < interval._end; 686 } 687 688 689 /++ 690 Returns the intersection of two intervals 691 692 Params: 693 interval = The interval to intersect with this interval. 694 695 Throws: 696 $(REF DateTimeException,std,datetime,date) if the two intervals do 697 not intersect or if either interval is empty. 698 699 Example: 700 -------------------- 701 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 702 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 703 Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); 704 705 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 706 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 707 Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); 708 -------------------- 709 +/ 710 Interval intersection(in Interval interval) const 711 { 712 import std.format : format; 713 714 enforce(this.intersects(interval), 715 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 716 717 auto begin = _begin > interval._begin ? _begin : interval._begin; 718 auto end = _end < interval._end ? _end : interval._end; 719 720 return Interval(begin, end); 721 } 722 723 724 /++ 725 Returns the intersection of two intervals 726 727 Params: 728 interval = The interval to intersect with this interval. 729 730 Throws: 731 $(REF DateTimeException,std,datetime,date) if the two intervals do 732 not intersect or if this interval is empty. 733 734 Example: 735 -------------------- 736 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 737 PosInfInterval!Date(Date(1990, 7, 6))) == 738 Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); 739 740 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 741 PosInfInterval!Date(Date(1999, 1, 12))) == 742 Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); 743 -------------------- 744 +/ 745 Interval intersection(in PosInfInterval!TP interval) const 746 { 747 import std.format : format; 748 749 enforce(this.intersects(interval), 750 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 751 752 return Interval(_begin > interval._begin ? _begin : interval._begin, _end); 753 } 754 755 756 /++ 757 Returns the intersection of two intervals 758 759 Params: 760 interval = The interval to intersect with this interval. 761 762 Throws: 763 $(REF DateTimeException,std,datetime,date) if the two intervals do 764 not intersect or if this interval is empty. 765 766 Example: 767 -------------------- 768 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 769 NegInfInterval!Date(Date(1999, 7, 6))) == 770 Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); 771 772 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 773 NegInfInterval!Date(Date(2013, 1, 12))) == 774 Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); 775 -------------------- 776 +/ 777 Interval intersection(in NegInfInterval!TP interval) const 778 { 779 import std.format : format; 780 781 enforce(this.intersects(interval), 782 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 783 784 return Interval(_begin, _end < interval._end ? _end : interval._end); 785 } 786 787 788 /++ 789 Whether the given interval is adjacent to this interval. 790 791 Params: 792 interval = The interval to check whether its adjecent to this 793 interval. 794 795 Throws: 796 $(REF DateTimeException,std,datetime,date) if either interval is 797 empty. 798 799 Example: 800 -------------------- 801 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 802 Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2)))); 803 804 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 805 Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17)))); 806 807 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 808 Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1)))); 809 -------------------- 810 +/ 811 bool isAdjacent(in Interval interval) const pure 812 { 813 _enforceNotEmpty(); 814 interval._enforceNotEmpty(); 815 return _begin == interval._end || _end == interval._begin; 816 } 817 818 819 /++ 820 Whether the given interval is adjacent to this interval. 821 822 Params: 823 interval = The interval to check whether its adjecent to this 824 interval. 825 826 Throws: 827 $(REF DateTimeException,std,datetime,date) if this interval is 828 empty. 829 830 Example: 831 -------------------- 832 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 833 PosInfInterval!Date(Date(1999, 5, 4)))); 834 835 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 836 PosInfInterval!Date(Date(2012, 3, 1)))); 837 -------------------- 838 +/ 839 bool isAdjacent(in PosInfInterval!TP interval) const pure 840 { 841 _enforceNotEmpty(); 842 return _end == interval._begin; 843 } 844 845 846 /++ 847 Whether the given interval is adjacent to this interval. 848 849 Params: 850 interval = The interval to check whether its adjecent to this 851 interval. 852 853 Throws: 854 $(REF DateTimeException,std,datetime,date) if this interval is 855 empty. 856 857 Example: 858 -------------------- 859 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 860 NegInfInterval!Date(Date(1996, 1, 2)))); 861 862 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 863 NegInfInterval!Date(Date(2000, 1, 2)))); 864 -------------------- 865 +/ 866 bool isAdjacent(in NegInfInterval!TP interval) const pure 867 { 868 _enforceNotEmpty(); 869 return _begin == interval._end; 870 } 871 872 873 /++ 874 Returns the union of two intervals 875 876 Params: 877 interval = The interval to merge with this interval. 878 879 Throws: 880 $(REF DateTimeException,std,datetime,date) if the two intervals do 881 not intersect and are not adjacent or if either interval is empty. 882 883 Example: 884 -------------------- 885 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( 886 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 887 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); 888 889 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( 890 Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == 891 Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); 892 -------------------- 893 +/ 894 Interval merge(in Interval interval) const 895 { 896 import std.format : format; 897 898 enforce(this.isAdjacent(interval) || this.intersects(interval), 899 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); 900 901 auto begin = _begin < interval._begin ? _begin : interval._begin; 902 auto end = _end > interval._end ? _end : interval._end; 903 904 return Interval(begin, end); 905 } 906 907 908 /++ 909 Returns the union of two intervals 910 911 Params: 912 interval = The interval to merge with this interval. 913 914 Throws: 915 $(REF DateTimeException,std,datetime,date) if the two intervals do 916 not intersect and are not adjacent or if this interval is empty. 917 918 Example: 919 -------------------- 920 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( 921 PosInfInterval!Date(Date(1990, 7, 6))) == 922 PosInfInterval!Date(Date(1990, 7 , 6))); 923 924 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( 925 PosInfInterval!Date(Date(2012, 3, 1))) == 926 PosInfInterval!Date(Date(1996, 1 , 2))); 927 -------------------- 928 +/ 929 PosInfInterval!TP merge(in PosInfInterval!TP interval) const 930 { 931 import std.format : format; 932 933 enforce(this.isAdjacent(interval) || this.intersects(interval), 934 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); 935 936 return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin); 937 } 938 939 940 /++ 941 Returns the union of two intervals 942 943 Params: 944 interval = The interval to merge with this interval. 945 946 Throws: 947 $(REF DateTimeException,std,datetime,date) if the two intervals do 948 not intersect and are not adjacent or if this interval is empty. 949 950 Example: 951 -------------------- 952 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( 953 NegInfInterval!Date(Date(1996, 1, 2))) == 954 NegInfInterval!Date(Date(2012, 3 , 1))); 955 956 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( 957 NegInfInterval!Date(Date(2013, 1, 12))) == 958 NegInfInterval!Date(Date(2013, 1 , 12))); 959 -------------------- 960 +/ 961 NegInfInterval!TP merge(in NegInfInterval!TP interval) const 962 { 963 import std.format : format; 964 965 enforce(this.isAdjacent(interval) || this.intersects(interval), 966 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); 967 968 return NegInfInterval!TP(_end > interval._end ? _end : interval._end); 969 } 970 971 972 /++ 973 Returns an interval that covers from the earliest time point of two 974 intervals up to (but not including) the latest time point of two 975 intervals. 976 977 Params: 978 interval = The interval to create a span together with this interval. 979 980 Throws: 981 $(REF DateTimeException,std,datetime,date) if either interval is 982 empty. 983 984 Example: 985 -------------------- 986 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( 987 Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) == 988 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); 989 990 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( 991 Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == 992 Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); 993 -------------------- 994 +/ 995 Interval span(in Interval interval) const pure 996 { 997 _enforceNotEmpty(); 998 interval._enforceNotEmpty(); 999 1000 auto begin = _begin < interval._begin ? _begin : interval._begin; 1001 auto end = _end > interval._end ? _end : interval._end; 1002 1003 return Interval(begin, end); 1004 } 1005 1006 1007 /++ 1008 Returns an interval that covers from the earliest time point of two 1009 intervals up to (but not including) the latest time point of two 1010 intervals. 1011 1012 Params: 1013 interval = The interval to create a span together with this interval. 1014 1015 Throws: 1016 $(REF DateTimeException,std,datetime,date) if this interval is 1017 empty. 1018 1019 Example: 1020 -------------------- 1021 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( 1022 PosInfInterval!Date(Date(1990, 7, 6))) == 1023 PosInfInterval!Date(Date(1990, 7 , 6))); 1024 1025 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( 1026 PosInfInterval!Date(Date(2050, 1, 1))) == 1027 PosInfInterval!Date(Date(1996, 1 , 2))); 1028 -------------------- 1029 +/ 1030 PosInfInterval!TP span(in PosInfInterval!TP interval) const pure 1031 { 1032 _enforceNotEmpty(); 1033 return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin); 1034 } 1035 1036 1037 /++ 1038 Returns an interval that covers from the earliest time point of two 1039 intervals up to (but not including) the latest time point of two 1040 intervals. 1041 1042 Params: 1043 interval = The interval to create a span together with this interval. 1044 1045 Throws: 1046 $(REF DateTimeException,std,datetime,date) if this interval is 1047 empty. 1048 1049 Example: 1050 -------------------- 1051 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( 1052 NegInfInterval!Date(Date(1602, 5, 21))) == 1053 NegInfInterval!Date(Date(2012, 3 , 1))); 1054 1055 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( 1056 NegInfInterval!Date(Date(2013, 1, 12))) == 1057 NegInfInterval!Date(Date(2013, 1 , 12))); 1058 -------------------- 1059 +/ 1060 NegInfInterval!TP span(in NegInfInterval!TP interval) const pure 1061 { 1062 _enforceNotEmpty(); 1063 return NegInfInterval!TP(_end > interval._end ? _end : interval._end); 1064 } 1065 1066 1067 /++ 1068 Shifts the interval forward or backwards in time by the given duration 1069 (a positive duration shifts the interval forward; a negative duration 1070 shifts it backward). Effectively, it does $(D begin += duration) and 1071 $(D end += duration). 1072 1073 Params: 1074 duration = The duration to shift the interval by. 1075 1076 Throws: 1077 $(REF DateTimeException,std,datetime,date) this interval is empty 1078 or if the resulting interval would be invalid. 1079 1080 Example: 1081 -------------------- 1082 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); 1083 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); 1084 1085 interval1.shift(dur!"days"(50)); 1086 assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25))); 1087 1088 interval2.shift(dur!"days"(-50)); 1089 assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15))); 1090 -------------------- 1091 +/ 1092 void shift(D)(D duration) pure 1093 if (__traits(compiles, begin + duration)) 1094 { 1095 _enforceNotEmpty(); 1096 1097 auto begin = _begin + duration; 1098 auto end = _end + duration; 1099 1100 if (!_valid(begin, end)) 1101 throw new DateTimeException("Argument would result in an invalid Interval."); 1102 1103 _begin = begin; 1104 _end = end; 1105 } 1106 1107 1108 static if (__traits(compiles, begin.add!"months"(1)) && 1109 __traits(compiles, begin.add!"years"(1))) 1110 { 1111 /++ 1112 Shifts the interval forward or backwards in time by the given number 1113 of years and/or months (a positive number of years and months shifts 1114 the interval forward; a negative number shifts it backward). 1115 It adds the years the given years and months to both begin and end. 1116 It effectively calls $(D add!"years"()) and then $(D add!"months"()) 1117 on begin and end with the given number of years and months. 1118 1119 Params: 1120 years = The number of years to shift the interval by. 1121 months = The number of months to shift the interval by. 1122 allowOverflow = Whether the days should be allowed to overflow 1123 on $(D begin) and $(D end), causing their month 1124 to increment. 1125 1126 Throws: 1127 $(REF DateTimeException,std,datetime,date) if this interval is 1128 empty or if the resulting interval would be invalid. 1129 1130 Example: 1131 -------------------- 1132 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1133 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1134 1135 interval1.shift(2); 1136 assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1))); 1137 1138 interval2.shift(-2); 1139 assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1))); 1140 -------------------- 1141 +/ 1142 void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) 1143 if (isIntegral!T) 1144 { 1145 _enforceNotEmpty(); 1146 1147 auto begin = _begin; 1148 auto end = _end; 1149 1150 begin.add!"years"(years, allowOverflow); 1151 begin.add!"months"(months, allowOverflow); 1152 end.add!"years"(years, allowOverflow); 1153 end.add!"months"(months, allowOverflow); 1154 1155 enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval.")); 1156 1157 _begin = begin; 1158 _end = end; 1159 } 1160 } 1161 1162 1163 /++ 1164 Expands the interval forwards and/or backwards in time. Effectively, 1165 it does $(D begin -= duration) and/or $(D end += duration). Whether 1166 it expands forwards and/or backwards in time is determined by 1167 $(D_PARAM dir). 1168 1169 Params: 1170 duration = The duration to expand the interval by. 1171 dir = The direction in time to expand the interval. 1172 1173 Throws: 1174 $(REF DateTimeException,std,datetime,date) this interval is empty 1175 or if the resulting interval would be invalid. 1176 1177 Example: 1178 -------------------- 1179 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1180 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1181 1182 interval1.expand(2); 1183 assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); 1184 1185 interval2.expand(-2); 1186 assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); 1187 -------------------- 1188 +/ 1189 void expand(D)(D duration, Direction dir = Direction.both) pure 1190 if (__traits(compiles, begin + duration)) 1191 { 1192 _enforceNotEmpty(); 1193 1194 switch (dir) 1195 { 1196 case Direction.both: 1197 { 1198 auto begin = _begin - duration; 1199 auto end = _end + duration; 1200 1201 if (!_valid(begin, end)) 1202 throw new DateTimeException("Argument would result in an invalid Interval."); 1203 1204 _begin = begin; 1205 _end = end; 1206 1207 return; 1208 } 1209 case Direction.fwd: 1210 { 1211 auto end = _end + duration; 1212 1213 if (!_valid(_begin, end)) 1214 throw new DateTimeException("Argument would result in an invalid Interval."); 1215 _end = end; 1216 1217 return; 1218 } 1219 case Direction.bwd: 1220 { 1221 auto begin = _begin - duration; 1222 1223 if (!_valid(begin, _end)) 1224 throw new DateTimeException("Argument would result in an invalid Interval."); 1225 _begin = begin; 1226 1227 return; 1228 } 1229 default: 1230 assert(0, "Invalid Direction."); 1231 } 1232 } 1233 1234 static if (__traits(compiles, begin.add!"months"(1)) && 1235 __traits(compiles, begin.add!"years"(1))) 1236 { 1237 /++ 1238 Expands the interval forwards and/or backwards in time. Effectively, 1239 it subtracts the given number of months/years from $(D begin) and 1240 adds them to $(D end). Whether it expands forwards and/or backwards 1241 in time is determined by $(D_PARAM dir). 1242 1243 Params: 1244 years = The number of years to expand the interval by. 1245 months = The number of months to expand the interval by. 1246 allowOverflow = Whether the days should be allowed to overflow 1247 on $(D begin) and $(D end), causing their month 1248 to increment. 1249 dir = The direction in time to expand the interval. 1250 1251 Throws: 1252 $(REF DateTimeException,std,datetime,date) if this interval is 1253 empty or if the resulting interval would be invalid. 1254 1255 Example: 1256 -------------------- 1257 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1258 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1259 1260 interval1.expand(2); 1261 assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); 1262 1263 interval2.expand(-2); 1264 assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); 1265 -------------------- 1266 +/ 1267 void expand(T)(T years, 1268 T months = 0, 1269 AllowDayOverflow allowOverflow = AllowDayOverflow.yes, 1270 Direction dir = Direction.both) 1271 if (isIntegral!T) 1272 { 1273 _enforceNotEmpty(); 1274 1275 switch (dir) 1276 { 1277 case Direction.both: 1278 { 1279 auto begin = _begin; 1280 auto end = _end; 1281 1282 begin.add!"years"(-years, allowOverflow); 1283 begin.add!"months"(-months, allowOverflow); 1284 end.add!"years"(years, allowOverflow); 1285 end.add!"months"(months, allowOverflow); 1286 1287 enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval.")); 1288 _begin = begin; 1289 _end = end; 1290 1291 return; 1292 } 1293 case Direction.fwd: 1294 { 1295 auto end = _end; 1296 1297 end.add!"years"(years, allowOverflow); 1298 end.add!"months"(months, allowOverflow); 1299 1300 enforce(_valid(_begin, end), 1301 new DateTimeException("Argument would result in an invalid Interval.")); 1302 _end = end; 1303 1304 return; 1305 } 1306 case Direction.bwd: 1307 { 1308 auto begin = _begin; 1309 1310 begin.add!"years"(-years, allowOverflow); 1311 begin.add!"months"(-months, allowOverflow); 1312 1313 enforce(_valid(begin, _end), 1314 new DateTimeException("Argument would result in an invalid Interval.")); 1315 _begin = begin; 1316 1317 return; 1318 } 1319 default: 1320 assert(0, "Invalid Direction."); 1321 } 1322 } 1323 } 1324 1325 1326 /++ 1327 Returns a range which iterates forward over the interval, starting 1328 at $(D begin), using $(D_PARAM func) to generate each successive time 1329 point. 1330 1331 The range's $(D front) is the interval's $(D begin). $(D_PARAM func) is 1332 used to generate the next $(D front) when $(D popFront) is called. If 1333 $(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called 1334 before the range is returned (so that $(D front) is a time point which 1335 $(D_PARAM func) would generate). 1336 1337 If $(D_PARAM func) ever generates a time point less than or equal to the 1338 current $(D front) of the range, then a 1339 $(REF DateTimeException,std,datetime,date) will be thrown. The range 1340 will be empty and iteration complete when $(D_PARAM func) generates a 1341 time point equal to or beyond the $(D end) of the interval. 1342 1343 There are helper functions in this module which generate common 1344 delegates to pass to $(D fwdRange). Their documentation starts with 1345 "Range-generating function," making them easily searchable. 1346 1347 Params: 1348 func = The function used to generate the time points of the 1349 range over the interval. 1350 popFirst = Whether $(D popFront) should be called on the range 1351 before returning it. 1352 1353 Throws: 1354 $(REF DateTimeException,std,datetime,date) if this interval is 1355 empty. 1356 1357 Warning: 1358 $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) 1359 would be a function pointer to a pure function, but forcing 1360 $(D_PARAM func) to be pure is far too restrictive to be useful, and 1361 in order to have the ease of use of having functions which generate 1362 functions to pass to $(D fwdRange), $(D_PARAM func) must be a 1363 delegate. 1364 1365 If $(D_PARAM func) retains state which changes as it is called, then 1366 some algorithms will not work correctly, because the range's 1367 $(D save) will have failed to have really saved the range's state. 1368 To avoid such bugs, don't pass a delegate which is 1369 not logically pure to $(D fwdRange). If $(D_PARAM func) is given the 1370 same time point with two different calls, it must return the same 1371 result both times. 1372 1373 Of course, none of the functions in this module have this problem, 1374 so it's only relevant if when creating a custom delegate. 1375 1376 Example: 1377 -------------------- 1378 auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); 1379 auto func = delegate (in Date date) // For iterating over even-numbered days. 1380 { 1381 if ((date.day & 1) == 0) 1382 return date + dur!"days"(2); 1383 1384 return date + dur!"days"(1); 1385 }; 1386 auto range = interval.fwdRange(func); 1387 1388 // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). 1389 assert(range.front == Date(2010, 9, 1)); 1390 1391 range.popFront(); 1392 assert(range.front == Date(2010, 9, 2)); 1393 1394 range.popFront(); 1395 assert(range.front == Date(2010, 9, 4)); 1396 1397 range.popFront(); 1398 assert(range.front == Date(2010, 9, 6)); 1399 1400 range.popFront(); 1401 assert(range.front == Date(2010, 9, 8)); 1402 1403 range.popFront(); 1404 assert(range.empty); 1405 -------------------- 1406 +/ 1407 IntervalRange!(TP, Direction.fwd) fwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const 1408 { 1409 _enforceNotEmpty(); 1410 1411 auto range = IntervalRange!(TP, Direction.fwd)(this, func); 1412 1413 if (popFirst == PopFirst.yes) 1414 range.popFront(); 1415 1416 return range; 1417 } 1418 1419 1420 /++ 1421 Returns a range which iterates backwards over the interval, starting 1422 at $(D end), using $(D_PARAM func) to generate each successive time 1423 point. 1424 1425 The range's $(D front) is the interval's $(D end). $(D_PARAM func) is 1426 used to generate the next $(D front) when $(D popFront) is called. If 1427 $(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called 1428 before the range is returned (so that $(D front) is a time point which 1429 $(D_PARAM func) would generate). 1430 1431 If $(D_PARAM func) ever generates a time point greater than or equal to 1432 the current $(D front) of the range, then a 1433 $(REF DateTimeException,std,datetime,date) will be thrown. The range 1434 will be empty and iteration complete when $(D_PARAM func) generates a 1435 time point equal to or less than the $(D begin) of the interval. 1436 1437 There are helper functions in this module which generate common 1438 delegates to pass to $(D bwdRange). Their documentation starts with 1439 "Range-generating function," making them easily searchable. 1440 1441 Params: 1442 func = The function used to generate the time points of the 1443 range over the interval. 1444 popFirst = Whether $(D popFront) should be called on the range 1445 before returning it. 1446 1447 Throws: 1448 $(REF DateTimeException,std,datetime,date) if this interval is 1449 empty. 1450 1451 Warning: 1452 $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) 1453 would be a function pointer to a pure function, but forcing 1454 $(D_PARAM func) to be pure is far too restrictive to be useful, and 1455 in order to have the ease of use of having functions which generate 1456 functions to pass to $(D fwdRange), $(D_PARAM func) must be a 1457 delegate. 1458 1459 If $(D_PARAM func) retains state which changes as it is called, then 1460 some algorithms will not work correctly, because the range's 1461 $(D save) will have failed to have really saved the range's state. 1462 To avoid such bugs, don't pass a delegate which is 1463 not logically pure to $(D fwdRange). If $(D_PARAM func) is given the 1464 same time point with two different calls, it must return the same 1465 result both times. 1466 1467 Of course, none of the functions in this module have this problem, 1468 so it's only relevant for custom delegates. 1469 1470 Example: 1471 -------------------- 1472 auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); 1473 auto func = delegate (in Date date) // For iterating over even-numbered days. 1474 { 1475 if ((date.day & 1) == 0) 1476 return date - dur!"days"(2); 1477 1478 return date - dur!"days"(1); 1479 }; 1480 auto range = interval.bwdRange(func); 1481 1482 // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). 1483 assert(range.front == Date(2010, 9, 9)); 1484 1485 range.popFront(); 1486 assert(range.front == Date(2010, 9, 8)); 1487 1488 range.popFront(); 1489 assert(range.front == Date(2010, 9, 6)); 1490 1491 range.popFront(); 1492 assert(range.front == Date(2010, 9, 4)); 1493 1494 range.popFront(); 1495 assert(range.front == Date(2010, 9, 2)); 1496 1497 range.popFront(); 1498 assert(range.empty); 1499 -------------------- 1500 +/ 1501 IntervalRange!(TP, Direction.bwd) bwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const 1502 { 1503 _enforceNotEmpty(); 1504 1505 auto range = IntervalRange!(TP, Direction.bwd)(this, func); 1506 1507 if (popFirst == PopFirst.yes) 1508 range.popFront(); 1509 1510 return range; 1511 } 1512 1513 1514 /+ 1515 Converts this interval to a string. 1516 +/ 1517 // Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't 1518 // have versions of toString() with extra modifiers, so we define one version 1519 // with modifiers and one without. 1520 string toString() 1521 { 1522 return _toStringImpl(); 1523 } 1524 1525 1526 /++ 1527 Converts this interval to a string. 1528 +/ 1529 // Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't 1530 // have versions of toString() with extra modifiers, so we define one version 1531 // with modifiers and one without. 1532 string toString() const nothrow 1533 { 1534 return _toStringImpl(); 1535 } 1536 1537 1538 private: 1539 1540 /+ 1541 Since we have two versions of toString, we have _toStringImpl 1542 so that they can share implementations. 1543 +/ 1544 string _toStringImpl() const nothrow 1545 { 1546 import std.format : format; 1547 try 1548 return format("[%s - %s)", _begin, _end); 1549 catch (Exception e) 1550 assert(0, "format() threw."); 1551 } 1552 1553 1554 /+ 1555 Throws: 1556 $(REF DateTimeException,std,datetime,date) if this interval is 1557 empty. 1558 +/ 1559 void _enforceNotEmpty(size_t line = __LINE__) const pure 1560 { 1561 if (empty) 1562 throw new DateTimeException("Invalid operation for an empty Interval.", __FILE__, line); 1563 } 1564 1565 1566 /+ 1567 Whether the given values form a valid time interval. 1568 1569 Params: 1570 begin = The starting point of the interval. 1571 end = The end point of the interval. 1572 +/ 1573 static bool _valid(in TP begin, in TP end) pure nothrow 1574 { 1575 return begin <= end; 1576 } 1577 1578 1579 pure invariant() 1580 { 1581 assert(_valid(_begin, _end), "Invariant Failure: begin is not before or equal to end."); 1582 } 1583 1584 1585 TP _begin; 1586 TP _end; 1587 } 1588 1589 // Test Interval's constructors. 1590 @safe unittest 1591 { 1592 import std.datetime.date; 1593 import std.datetime.systime; 1594 1595 assertThrown!DateTimeException(Interval!Date(Date(2010, 1, 1), Date(1, 1, 1))); 1596 1597 Interval!Date(Date.init, Date.init); 1598 Interval!TimeOfDay(TimeOfDay.init, TimeOfDay.init); 1599 Interval!DateTime(DateTime.init, DateTime.init); 1600 Interval!SysTime(SysTime(0), SysTime(0)); 1601 1602 Interval!DateTime(DateTime.init, dur!"days"(7)); 1603 1604 // Verify Examples. 1605 Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1606 assert(Interval!Date(Date(1996, 1, 2), dur!"weeks"(3)) == Interval!Date(Date(1996, 1, 2), Date(1996, 1, 23))); 1607 assert(Interval!Date(Date(1996, 1, 2), dur!"days"(3)) == Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5))); 1608 assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"hours"(3)) == 1609 Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 15, 0, 0))); 1610 assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"minutes"(3)) == 1611 Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 3, 0))); 1612 assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"seconds"(3)) == 1613 Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3))); 1614 assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"msecs"(3000)) == 1615 Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3))); 1616 } 1617 1618 // Test Interval's begin. 1619 @safe unittest 1620 { 1621 import std.datetime.date; 1622 1623 assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).begin == Date(1, 1, 1)); 1624 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).begin == Date(2010, 1, 1)); 1625 assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).begin == Date(1997, 12, 31)); 1626 1627 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1628 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1629 assert(cInterval.begin == Date(2010, 7, 4)); 1630 assert(iInterval.begin == Date(2010, 7, 4)); 1631 1632 // Verify Examples. 1633 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == Date(1996, 1, 2)); 1634 } 1635 1636 // Test Interval's end. 1637 @safe unittest 1638 { 1639 import std.datetime.date; 1640 1641 assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1)); 1642 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1)); 1643 assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).end == Date(1998, 1, 1)); 1644 1645 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1646 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1647 assert(cInterval.end == Date(2012, 1, 7)); 1648 assert(iInterval.end == Date(2012, 1, 7)); 1649 1650 // Verify Examples. 1651 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == Date(2012, 3, 1)); 1652 } 1653 1654 // Test Interval's length. 1655 @safe unittest 1656 { 1657 import std.datetime.date; 1658 import std.datetime.systime; 1659 1660 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).length == dur!"days"(0)); 1661 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).length == dur!"days"(90)); 1662 assert(Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).length == dur!"seconds"(42_727)); 1663 assert(Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).length == 1664 dur!"seconds"(129_127)); 1665 assert(Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)),SysTime(DateTime(2010, 1, 2, 12, 22, 7))).length == 1666 dur!"seconds"(129_127)); 1667 1668 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1669 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1670 assert(cInterval.length != Duration.zero); 1671 assert(iInterval.length != Duration.zero); 1672 1673 // Verify Examples. 1674 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == dur!"days"(5903)); 1675 } 1676 1677 // Test Interval's empty. 1678 @safe unittest 1679 { 1680 import std.datetime.date; 1681 import std.datetime.systime; 1682 1683 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).empty); 1684 assert(!Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).empty); 1685 assert(!Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).empty); 1686 assert(!Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).empty); 1687 assert(!Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)), SysTime(DateTime(2010, 1, 2, 12, 22, 7))).empty); 1688 1689 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1690 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1691 assert(!cInterval.empty); 1692 assert(!iInterval.empty); 1693 1694 // Verify Examples. 1695 assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty); 1696 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty); 1697 } 1698 1699 // Test Interval's contains(time point). 1700 @safe unittest 1701 { 1702 import std.datetime.date; 1703 1704 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1705 1706 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(Date(2010, 7, 4))); 1707 1708 assert(!interval.contains(Date(2009, 7, 4))); 1709 assert(!interval.contains(Date(2010, 7, 3))); 1710 assert(interval.contains(Date(2010, 7, 4))); 1711 assert(interval.contains(Date(2010, 7, 5))); 1712 assert(interval.contains(Date(2011, 7, 1))); 1713 assert(interval.contains(Date(2012, 1, 6))); 1714 assert(!interval.contains(Date(2012, 1, 7))); 1715 assert(!interval.contains(Date(2012, 1, 8))); 1716 assert(!interval.contains(Date(2013, 1, 7))); 1717 1718 const cdate = Date(2010, 7, 6); 1719 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1720 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1721 assert(interval.contains(cdate)); 1722 assert(cInterval.contains(cdate)); 1723 assert(iInterval.contains(cdate)); 1724 1725 // Verify Examples. 1726 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(1994, 12, 24))); 1727 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2000, 1, 5))); 1728 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2012, 3, 1))); 1729 } 1730 1731 // Test Interval's contains(Interval). 1732 @safe unittest 1733 { 1734 import std.datetime.date; 1735 1736 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1737 1738 assertThrown!DateTimeException(interval.contains(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 1739 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(interval)); 1740 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4),dur!"days"(0)).contains( 1741 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 1742 1743 assert(interval.contains(interval)); 1744 assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 1745 assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 1746 assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 1747 assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 1748 assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 1749 assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 1750 assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 1751 assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 1752 assert(interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 1753 assert(!interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 1754 assert(!interval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 1755 assert(!interval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 1756 1757 assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).contains(interval)); 1758 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).contains(interval)); 1759 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).contains(interval)); 1760 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).contains(interval)); 1761 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).contains(interval)); 1762 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).contains(interval)); 1763 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).contains(interval)); 1764 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).contains(interval)); 1765 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).contains(interval)); 1766 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).contains(interval)); 1767 assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).contains(interval)); 1768 assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).contains(interval)); 1769 1770 assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 3)))); 1771 assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 4)))); 1772 assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 5)))); 1773 assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 6)))); 1774 assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 7)))); 1775 assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 8)))); 1776 1777 assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 3)))); 1778 assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 4)))); 1779 assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 5)))); 1780 assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 6)))); 1781 assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 7)))); 1782 assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 8)))); 1783 1784 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1785 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1786 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 1787 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 1788 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 1789 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 1790 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 1791 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 1792 assert(interval.contains(interval)); 1793 assert(interval.contains(cInterval)); 1794 assert(interval.contains(iInterval)); 1795 assert(!interval.contains(posInfInterval)); 1796 assert(!interval.contains(cPosInfInterval)); 1797 assert(!interval.contains(iPosInfInterval)); 1798 assert(!interval.contains(negInfInterval)); 1799 assert(!interval.contains(cNegInfInterval)); 1800 assert(!interval.contains(iNegInfInterval)); 1801 assert(cInterval.contains(interval)); 1802 assert(cInterval.contains(cInterval)); 1803 assert(cInterval.contains(iInterval)); 1804 assert(!cInterval.contains(posInfInterval)); 1805 assert(!cInterval.contains(cPosInfInterval)); 1806 assert(!cInterval.contains(iPosInfInterval)); 1807 assert(!cInterval.contains(negInfInterval)); 1808 assert(!cInterval.contains(cNegInfInterval)); 1809 assert(!cInterval.contains(iNegInfInterval)); 1810 assert(iInterval.contains(interval)); 1811 assert(iInterval.contains(cInterval)); 1812 assert(iInterval.contains(iInterval)); 1813 assert(!iInterval.contains(posInfInterval)); 1814 assert(!iInterval.contains(cPosInfInterval)); 1815 assert(!iInterval.contains(iPosInfInterval)); 1816 assert(!iInterval.contains(negInfInterval)); 1817 assert(!iInterval.contains(cNegInfInterval)); 1818 assert(!iInterval.contains(iNegInfInterval)); 1819 1820 // Verify Examples. 1821 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 1822 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 1823 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 1824 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 1825 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 1826 Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); 1827 1828 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4)))); 1829 1830 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4)))); 1831 } 1832 1833 // Test Interval's isBefore(time point). 1834 @safe unittest 1835 { 1836 import std.datetime.date; 1837 1838 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1839 1840 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(Date(2010, 7, 4))); 1841 1842 assert(!interval.isBefore(Date(2009, 7, 3))); 1843 assert(!interval.isBefore(Date(2010, 7, 3))); 1844 assert(!interval.isBefore(Date(2010, 7, 4))); 1845 assert(!interval.isBefore(Date(2010, 7, 5))); 1846 assert(!interval.isBefore(Date(2011, 7, 1))); 1847 assert(!interval.isBefore(Date(2012, 1, 6))); 1848 assert(interval.isBefore(Date(2012, 1, 7))); 1849 assert(interval.isBefore(Date(2012, 1, 8))); 1850 assert(interval.isBefore(Date(2013, 1, 7))); 1851 1852 const cdate = Date(2010, 7, 6); 1853 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1854 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1855 assert(!interval.isBefore(cdate)); 1856 assert(!cInterval.isBefore(cdate)); 1857 assert(!iInterval.isBefore(cdate)); 1858 1859 // Verify Examples. 1860 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(1994, 12, 24))); 1861 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2000, 1, 5))); 1862 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2012, 3, 1))); 1863 } 1864 1865 // Test Interval's isBefore(Interval). 1866 @safe unittest 1867 { 1868 import std.datetime.date; 1869 1870 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1871 1872 assertThrown!DateTimeException(interval.isBefore(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 1873 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(interval)); 1874 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore( 1875 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 1876 1877 assert(!interval.isBefore(interval)); 1878 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 1879 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 1880 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 1881 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 1882 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 1883 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 1884 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 1885 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 1886 assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 1887 assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 1888 assert(interval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 1889 assert(interval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 1890 1891 assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isBefore(interval)); 1892 assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isBefore(interval)); 1893 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isBefore(interval)); 1894 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isBefore(interval)); 1895 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isBefore(interval)); 1896 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isBefore(interval)); 1897 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isBefore(interval)); 1898 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isBefore(interval)); 1899 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isBefore(interval)); 1900 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isBefore(interval)); 1901 assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isBefore(interval)); 1902 assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isBefore(interval)); 1903 1904 assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 3)))); 1905 assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 4)))); 1906 assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 5)))); 1907 assert(!interval.isBefore(PosInfInterval!Date(Date(2012, 1, 6)))); 1908 assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 7)))); 1909 assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 8)))); 1910 1911 assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 3)))); 1912 assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 4)))); 1913 assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 5)))); 1914 assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 6)))); 1915 assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 7)))); 1916 assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 8)))); 1917 1918 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1919 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1920 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 1921 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 1922 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 1923 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 1924 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 1925 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 1926 assert(!interval.isBefore(interval)); 1927 assert(!interval.isBefore(cInterval)); 1928 assert(!interval.isBefore(iInterval)); 1929 assert(!interval.isBefore(posInfInterval)); 1930 assert(!interval.isBefore(cPosInfInterval)); 1931 assert(!interval.isBefore(iPosInfInterval)); 1932 assert(!interval.isBefore(negInfInterval)); 1933 assert(!interval.isBefore(cNegInfInterval)); 1934 assert(!interval.isBefore(iNegInfInterval)); 1935 assert(!cInterval.isBefore(interval)); 1936 assert(!cInterval.isBefore(cInterval)); 1937 assert(!cInterval.isBefore(iInterval)); 1938 assert(!cInterval.isBefore(posInfInterval)); 1939 assert(!cInterval.isBefore(cPosInfInterval)); 1940 assert(!cInterval.isBefore(iPosInfInterval)); 1941 assert(!cInterval.isBefore(negInfInterval)); 1942 assert(!cInterval.isBefore(cNegInfInterval)); 1943 assert(!cInterval.isBefore(iNegInfInterval)); 1944 assert(!iInterval.isBefore(interval)); 1945 assert(!iInterval.isBefore(cInterval)); 1946 assert(!iInterval.isBefore(iInterval)); 1947 assert(!iInterval.isBefore(posInfInterval)); 1948 assert(!iInterval.isBefore(cPosInfInterval)); 1949 assert(!iInterval.isBefore(iPosInfInterval)); 1950 assert(!iInterval.isBefore(negInfInterval)); 1951 assert(!iInterval.isBefore(cNegInfInterval)); 1952 assert(!iInterval.isBefore(iNegInfInterval)); 1953 1954 // Verify Examples. 1955 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 1956 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 1957 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 1958 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 1959 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 1960 Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1)))); 1961 1962 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4)))); 1963 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2013, 3, 7)))); 1964 1965 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4)))); 1966 } 1967 1968 // Test Interval's isAfter(time point). 1969 @safe unittest 1970 { 1971 import std.datetime.date; 1972 1973 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1974 1975 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(Date(2010, 7, 4))); 1976 1977 assert(interval.isAfter(Date(2009, 7, 4))); 1978 assert(interval.isAfter(Date(2010, 7, 3))); 1979 assert(!interval.isAfter(Date(2010, 7, 4))); 1980 assert(!interval.isAfter(Date(2010, 7, 5))); 1981 assert(!interval.isAfter(Date(2011, 7, 1))); 1982 assert(!interval.isAfter(Date(2012, 1, 6))); 1983 assert(!interval.isAfter(Date(2012, 1, 7))); 1984 assert(!interval.isAfter(Date(2012, 1, 8))); 1985 assert(!interval.isAfter(Date(2013, 1, 7))); 1986 1987 const cdate = Date(2010, 7, 6); 1988 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1989 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1990 assert(!interval.isAfter(cdate)); 1991 assert(!cInterval.isAfter(cdate)); 1992 assert(!iInterval.isAfter(cdate)); 1993 1994 // Verify Examples. 1995 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(1994, 12, 24))); 1996 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2000, 1, 5))); 1997 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2012, 3, 1))); 1998 } 1999 2000 // Test Interval's isAfter(Interval). 2001 @safe unittest 2002 { 2003 import std.datetime.date; 2004 2005 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2006 2007 assertThrown!DateTimeException(interval.isAfter(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2008 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(interval)); 2009 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter( 2010 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2011 2012 assert(!interval.isAfter(interval)); 2013 assert(interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 2014 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 2015 assert(interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 2016 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 2017 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 2018 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 2019 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 2020 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 2021 assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 2022 assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 2023 assert(!interval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 2024 assert(!interval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 2025 2026 assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAfter(interval)); 2027 assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAfter(interval)); 2028 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAfter(interval)); 2029 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAfter(interval)); 2030 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAfter(interval)); 2031 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAfter(interval)); 2032 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAfter(interval)); 2033 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAfter(interval)); 2034 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAfter(interval)); 2035 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAfter(interval)); 2036 assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAfter(interval)); 2037 assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAfter(interval)); 2038 2039 assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 3)))); 2040 assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 4)))); 2041 assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 5)))); 2042 assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 6)))); 2043 assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 7)))); 2044 assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 8)))); 2045 2046 assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 3)))); 2047 assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 4)))); 2048 assert(!interval.isAfter(NegInfInterval!Date(Date(2010, 7, 5)))); 2049 assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 6)))); 2050 assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 7)))); 2051 assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 8)))); 2052 2053 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2054 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2055 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2056 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2057 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2058 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2059 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2060 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2061 assert(!interval.isAfter(interval)); 2062 assert(!interval.isAfter(cInterval)); 2063 assert(!interval.isAfter(iInterval)); 2064 assert(!interval.isAfter(posInfInterval)); 2065 assert(!interval.isAfter(cPosInfInterval)); 2066 assert(!interval.isAfter(iPosInfInterval)); 2067 assert(!interval.isAfter(negInfInterval)); 2068 assert(!interval.isAfter(cNegInfInterval)); 2069 assert(!interval.isAfter(iNegInfInterval)); 2070 assert(!cInterval.isAfter(interval)); 2071 assert(!cInterval.isAfter(cInterval)); 2072 assert(!cInterval.isAfter(iInterval)); 2073 assert(!cInterval.isAfter(posInfInterval)); 2074 assert(!cInterval.isAfter(cPosInfInterval)); 2075 assert(!cInterval.isAfter(iPosInfInterval)); 2076 assert(!cInterval.isAfter(negInfInterval)); 2077 assert(!cInterval.isAfter(cNegInfInterval)); 2078 assert(!cInterval.isAfter(iNegInfInterval)); 2079 assert(!iInterval.isAfter(interval)); 2080 assert(!iInterval.isAfter(cInterval)); 2081 assert(!iInterval.isAfter(iInterval)); 2082 assert(!iInterval.isAfter(posInfInterval)); 2083 assert(!iInterval.isAfter(cPosInfInterval)); 2084 assert(!iInterval.isAfter(iPosInfInterval)); 2085 assert(!iInterval.isAfter(negInfInterval)); 2086 assert(!iInterval.isAfter(cNegInfInterval)); 2087 assert(!iInterval.isAfter(iNegInfInterval)); 2088 2089 // Verify Examples. 2090 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 2091 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 2092 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 2093 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 2094 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 2095 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 2096 2097 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4)))); 2098 2099 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 1, 2)))); 2100 } 2101 2102 // Test Interval's intersects(). 2103 @safe unittest 2104 { 2105 import std.datetime.date; 2106 2107 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2108 2109 assertThrown!DateTimeException(interval.intersects(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2110 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects(interval)); 2111 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects( 2112 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2113 2114 assert(interval.intersects(interval)); 2115 assert(!interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 2116 assert(interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 2117 assert(!interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 2118 assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 2119 assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 2120 assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 2121 assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 2122 assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 2123 assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 2124 assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 2125 assert(!interval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 2126 assert(!interval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 2127 2128 assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersects(interval)); 2129 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersects(interval)); 2130 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersects(interval)); 2131 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersects(interval)); 2132 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersects(interval)); 2133 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersects(interval)); 2134 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersects(interval)); 2135 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersects(interval)); 2136 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersects(interval)); 2137 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersects(interval)); 2138 assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersects(interval)); 2139 assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersects(interval)); 2140 2141 assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 3)))); 2142 assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 4)))); 2143 assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 5)))); 2144 assert(interval.intersects(PosInfInterval!Date(Date(2012, 1, 6)))); 2145 assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 7)))); 2146 assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 8)))); 2147 2148 assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 3)))); 2149 assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 4)))); 2150 assert(interval.intersects(NegInfInterval!Date(Date(2010, 7, 5)))); 2151 assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 6)))); 2152 assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 7)))); 2153 assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 8)))); 2154 2155 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2156 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2157 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2158 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2159 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2160 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2161 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2162 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2163 assert(interval.intersects(interval)); 2164 assert(interval.intersects(cInterval)); 2165 assert(interval.intersects(iInterval)); 2166 assert(interval.intersects(posInfInterval)); 2167 assert(interval.intersects(cPosInfInterval)); 2168 assert(interval.intersects(iPosInfInterval)); 2169 assert(interval.intersects(negInfInterval)); 2170 assert(interval.intersects(cNegInfInterval)); 2171 assert(interval.intersects(iNegInfInterval)); 2172 assert(cInterval.intersects(interval)); 2173 assert(cInterval.intersects(cInterval)); 2174 assert(cInterval.intersects(iInterval)); 2175 assert(cInterval.intersects(posInfInterval)); 2176 assert(cInterval.intersects(cPosInfInterval)); 2177 assert(cInterval.intersects(iPosInfInterval)); 2178 assert(cInterval.intersects(negInfInterval)); 2179 assert(cInterval.intersects(cNegInfInterval)); 2180 assert(cInterval.intersects(iNegInfInterval)); 2181 assert(iInterval.intersects(interval)); 2182 assert(iInterval.intersects(cInterval)); 2183 assert(iInterval.intersects(iInterval)); 2184 assert(iInterval.intersects(posInfInterval)); 2185 assert(iInterval.intersects(cPosInfInterval)); 2186 assert(iInterval.intersects(iPosInfInterval)); 2187 assert(iInterval.intersects(negInfInterval)); 2188 assert(iInterval.intersects(cNegInfInterval)); 2189 assert(iInterval.intersects(iNegInfInterval)); 2190 2191 // Verify Examples. 2192 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 2193 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 2194 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 2195 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 2196 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 2197 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 2198 2199 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4)))); 2200 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1)))); 2201 2202 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 1, 2)))); 2203 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2000, 1, 2)))); 2204 } 2205 2206 // Test Interval's intersection(). 2207 @safe unittest 2208 { 2209 import std.datetime.date; 2210 2211 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2212 2213 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2214 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection(interval)); 2215 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection( 2216 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2217 2218 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 2219 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 2220 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 2221 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 2222 2223 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersection(interval)); 2224 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersection(interval)); 2225 assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersection(interval)); 2226 assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersection(interval)); 2227 2228 assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 7)))); 2229 assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 8)))); 2230 2231 assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 3)))); 2232 assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 4)))); 2233 2234 assert(interval.intersection(interval) == interval); 2235 assert(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 2236 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2237 assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 2238 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); 2239 assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 2240 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2241 assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 2242 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2243 assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 2244 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); 2245 assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 2246 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); 2247 assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 2248 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 2249 assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 2250 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 2251 2252 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersection(interval) == 2253 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2254 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersection(interval) == 2255 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); 2256 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersection(interval) == 2257 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2258 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersection(interval) == 2259 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2260 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersection(interval) == 2261 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); 2262 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersection(interval) == 2263 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); 2264 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersection(interval) == 2265 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 2266 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersection(interval) == 2267 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 2268 2269 assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == 2270 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2271 assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == 2272 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2273 assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == 2274 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); 2275 assert(interval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == 2276 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 2277 2278 assert(interval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == 2279 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); 2280 assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == 2281 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6))); 2282 assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == 2283 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2284 assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == 2285 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2286 2287 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2288 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2289 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2290 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2291 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2292 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2293 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2294 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2295 assert(!interval.intersection(interval).empty); 2296 assert(!interval.intersection(cInterval).empty); 2297 assert(!interval.intersection(iInterval).empty); 2298 assert(!interval.intersection(posInfInterval).empty); 2299 assert(!interval.intersection(cPosInfInterval).empty); 2300 assert(!interval.intersection(iPosInfInterval).empty); 2301 assert(!interval.intersection(negInfInterval).empty); 2302 assert(!interval.intersection(cNegInfInterval).empty); 2303 assert(!interval.intersection(iNegInfInterval).empty); 2304 assert(!cInterval.intersection(interval).empty); 2305 assert(!cInterval.intersection(cInterval).empty); 2306 assert(!cInterval.intersection(iInterval).empty); 2307 assert(!cInterval.intersection(posInfInterval).empty); 2308 assert(!cInterval.intersection(cPosInfInterval).empty); 2309 assert(!cInterval.intersection(iPosInfInterval).empty); 2310 assert(!cInterval.intersection(negInfInterval).empty); 2311 assert(!cInterval.intersection(cNegInfInterval).empty); 2312 assert(!cInterval.intersection(iNegInfInterval).empty); 2313 assert(!iInterval.intersection(interval).empty); 2314 assert(!iInterval.intersection(cInterval).empty); 2315 assert(!iInterval.intersection(iInterval).empty); 2316 assert(!iInterval.intersection(posInfInterval).empty); 2317 assert(!iInterval.intersection(cPosInfInterval).empty); 2318 assert(!iInterval.intersection(iPosInfInterval).empty); 2319 assert(!iInterval.intersection(negInfInterval).empty); 2320 assert(!iInterval.intersection(cNegInfInterval).empty); 2321 assert(!iInterval.intersection(iNegInfInterval).empty); 2322 2323 // Verify Examples. 2324 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 2325 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 2326 Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); 2327 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 2328 Interval!Date(Date(1999, 1, 12),Date(2011, 9, 17))) == 2329 Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); 2330 2331 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 2332 PosInfInterval!Date(Date(1990, 7, 6))) == 2333 Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); 2334 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 2335 PosInfInterval!Date(Date(1999, 1, 12))) == 2336 Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); 2337 2338 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 2339 NegInfInterval!Date(Date(1999, 7, 6))) == 2340 Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); 2341 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 2342 NegInfInterval!Date(Date(2013, 1, 12))) == 2343 Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); 2344 } 2345 2346 // Test Interval's isAdjacent(). 2347 @safe unittest 2348 { 2349 import std.datetime.date; 2350 2351 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2352 2353 static void testInterval(in Interval!Date interval1, in Interval!Date interval2) 2354 { 2355 interval1.isAdjacent(interval2); 2356 } 2357 2358 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2359 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval)); 2360 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 2361 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2362 2363 assert(!interval.isAdjacent(interval)); 2364 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 2365 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 2366 assert(interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 2367 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 2368 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 2369 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 2370 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 2371 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 2372 assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 2373 assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 2374 assert(interval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 2375 assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 2376 2377 assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAdjacent(interval)); 2378 assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAdjacent(interval)); 2379 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAdjacent(interval)); 2380 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAdjacent(interval)); 2381 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAdjacent(interval)); 2382 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAdjacent(interval)); 2383 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAdjacent(interval)); 2384 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAdjacent(interval)); 2385 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAdjacent(interval)); 2386 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAdjacent(interval)); 2387 assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAdjacent(interval)); 2388 assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAdjacent(interval)); 2389 2390 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3)))); 2391 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4)))); 2392 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5)))); 2393 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6)))); 2394 assert(interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7)))); 2395 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8)))); 2396 2397 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3)))); 2398 assert(interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4)))); 2399 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5)))); 2400 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6)))); 2401 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7)))); 2402 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8)))); 2403 2404 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2405 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2406 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2407 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2408 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2409 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2410 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2411 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2412 assert(!interval.isAdjacent(interval)); 2413 assert(!interval.isAdjacent(cInterval)); 2414 assert(!interval.isAdjacent(iInterval)); 2415 assert(!interval.isAdjacent(posInfInterval)); 2416 assert(!interval.isAdjacent(cPosInfInterval)); 2417 assert(!interval.isAdjacent(iPosInfInterval)); 2418 assert(!interval.isAdjacent(negInfInterval)); 2419 assert(!interval.isAdjacent(cNegInfInterval)); 2420 assert(!interval.isAdjacent(iNegInfInterval)); 2421 assert(!cInterval.isAdjacent(interval)); 2422 assert(!cInterval.isAdjacent(cInterval)); 2423 assert(!cInterval.isAdjacent(iInterval)); 2424 assert(!cInterval.isAdjacent(posInfInterval)); 2425 assert(!cInterval.isAdjacent(cPosInfInterval)); 2426 assert(!cInterval.isAdjacent(iPosInfInterval)); 2427 assert(!cInterval.isAdjacent(negInfInterval)); 2428 assert(!cInterval.isAdjacent(cNegInfInterval)); 2429 assert(!cInterval.isAdjacent(iNegInfInterval)); 2430 assert(!iInterval.isAdjacent(interval)); 2431 assert(!iInterval.isAdjacent(cInterval)); 2432 assert(!iInterval.isAdjacent(iInterval)); 2433 assert(!iInterval.isAdjacent(posInfInterval)); 2434 assert(!iInterval.isAdjacent(cPosInfInterval)); 2435 assert(!iInterval.isAdjacent(iPosInfInterval)); 2436 assert(!iInterval.isAdjacent(negInfInterval)); 2437 assert(!iInterval.isAdjacent(cNegInfInterval)); 2438 assert(!iInterval.isAdjacent(iNegInfInterval)); 2439 2440 // Verify Examples. 2441 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 2442 Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2)))); 2443 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 2444 Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17)))); 2445 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 2446 Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1)))); 2447 2448 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4)))); 2449 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1)))); 2450 2451 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2)))); 2452 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)) .isAdjacent(NegInfInterval!Date(Date(2000, 1, 2)))); 2453 } 2454 2455 // Test Interval's merge(). 2456 @safe unittest 2457 { 2458 import std.datetime.date; 2459 2460 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2461 2462 static void testInterval(I)(in Interval!Date interval1, in I interval2) 2463 { 2464 interval1.merge(interval2); 2465 } 2466 2467 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2468 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval)); 2469 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 2470 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2471 2472 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 2473 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 2474 2475 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)), interval)); 2476 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)), interval)); 2477 2478 assertThrown!DateTimeException(testInterval(interval, PosInfInterval!Date(Date(2012, 1, 8)))); 2479 2480 assertThrown!DateTimeException(testInterval(interval, NegInfInterval!Date(Date(2010, 7, 3)))); 2481 2482 assert(interval.merge(interval) == interval); 2483 assert(interval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 2484 Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); 2485 assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 2486 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2487 assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 2488 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2489 assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 2490 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2491 assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 2492 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); 2493 assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 2494 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2495 assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 2496 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2497 assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 2498 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2499 assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 2500 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2501 assert(interval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 2502 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2503 2504 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).merge(interval) == 2505 Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); 2506 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).merge(interval) == 2507 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2508 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).merge(interval) == 2509 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2510 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).merge(interval) == 2511 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2512 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).merge(interval) == 2513 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); 2514 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).merge(interval) == 2515 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2516 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).merge(interval) == 2517 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2518 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).merge(interval) == 2519 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2520 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).merge(interval) == 2521 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2522 assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).merge(interval) == 2523 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2524 2525 assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 3))) == 2526 PosInfInterval!Date(Date(2010, 7, 3))); 2527 assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 4))) == 2528 PosInfInterval!Date(Date(2010, 7, 4))); 2529 assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 5))) == 2530 PosInfInterval!Date(Date(2010, 7, 4))); 2531 assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 6))) == 2532 PosInfInterval!Date(Date(2010, 7, 4))); 2533 assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 7))) == 2534 PosInfInterval!Date(Date(2010, 7, 4))); 2535 2536 assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 4))) == 2537 NegInfInterval!Date(Date(2012, 1, 7))); 2538 assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 5))) == 2539 NegInfInterval!Date(Date(2012, 1, 7))); 2540 assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 6))) == 2541 NegInfInterval!Date(Date(2012, 1, 7))); 2542 assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 7))) == 2543 NegInfInterval!Date(Date(2012, 1, 7))); 2544 assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 8))) == 2545 NegInfInterval!Date(Date(2012, 1, 8))); 2546 2547 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2548 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2549 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2550 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2551 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2552 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2553 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2554 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2555 assert(!interval.merge(interval).empty); 2556 assert(!interval.merge(cInterval).empty); 2557 assert(!interval.merge(iInterval).empty); 2558 assert(!interval.merge(posInfInterval).empty); 2559 assert(!interval.merge(cPosInfInterval).empty); 2560 assert(!interval.merge(iPosInfInterval).empty); 2561 assert(!interval.merge(negInfInterval).empty); 2562 assert(!interval.merge(cNegInfInterval).empty); 2563 assert(!interval.merge(iNegInfInterval).empty); 2564 assert(!cInterval.merge(interval).empty); 2565 assert(!cInterval.merge(cInterval).empty); 2566 assert(!cInterval.merge(iInterval).empty); 2567 assert(!cInterval.merge(posInfInterval).empty); 2568 assert(!cInterval.merge(cPosInfInterval).empty); 2569 assert(!cInterval.merge(iPosInfInterval).empty); 2570 assert(!cInterval.merge(negInfInterval).empty); 2571 assert(!cInterval.merge(cNegInfInterval).empty); 2572 assert(!cInterval.merge(iNegInfInterval).empty); 2573 assert(!iInterval.merge(interval).empty); 2574 assert(!iInterval.merge(cInterval).empty); 2575 assert(!iInterval.merge(iInterval).empty); 2576 assert(!iInterval.merge(posInfInterval).empty); 2577 assert(!iInterval.merge(cPosInfInterval).empty); 2578 assert(!iInterval.merge(iPosInfInterval).empty); 2579 assert(!iInterval.merge(negInfInterval).empty); 2580 assert(!iInterval.merge(cNegInfInterval).empty); 2581 assert(!iInterval.merge(iNegInfInterval).empty); 2582 2583 // Verify Examples. 2584 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 2585 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); 2586 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == 2587 Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); 2588 2589 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(1990, 7, 6))) == 2590 PosInfInterval!Date(Date(1990, 7 , 6))); 2591 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(2012, 3, 1))) == 2592 PosInfInterval!Date(Date(1996, 1 , 2))); 2593 2594 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1996, 1, 2))) == 2595 NegInfInterval!Date(Date(2012, 3 , 1))); 2596 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) == 2597 NegInfInterval!Date(Date(2013, 1 , 12))); 2598 } 2599 2600 // Test Interval's span(). 2601 @safe unittest 2602 { 2603 import std.datetime.date; 2604 2605 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2606 2607 static void testInterval(in Interval!Date interval1, in Interval!Date interval2) 2608 { 2609 interval1.span(interval2); 2610 } 2611 2612 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2613 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)),interval)); 2614 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 2615 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2616 2617 assert(interval.span(interval) == interval); 2618 assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == 2619 Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); 2620 assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 2621 Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); 2622 assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 2623 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2624 assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 2625 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2626 assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 2627 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2628 assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 2629 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); 2630 assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 2631 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2632 assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 2633 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2634 assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 2635 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2636 assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 2637 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2638 assert(interval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 2639 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2640 assert(interval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == 2641 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9))); 2642 2643 assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).span(interval) == 2644 Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); 2645 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).span(interval) == 2646 Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); 2647 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).span(interval) == 2648 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2649 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).span(interval) == 2650 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2651 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).span(interval) == 2652 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2653 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).span(interval) == 2654 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); 2655 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).span(interval) == 2656 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2657 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).span(interval) == 2658 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2659 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).span(interval) == 2660 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2661 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).span(interval) == 2662 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2663 assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).span(interval) == 2664 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2665 assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).span(interval) == 2666 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9))); 2667 2668 assert(interval.span(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3))); 2669 assert(interval.span(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4))); 2670 assert(interval.span(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4))); 2671 assert(interval.span(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4))); 2672 assert(interval.span(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4))); 2673 assert(interval.span(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4))); 2674 2675 assert(interval.span(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7))); 2676 assert(interval.span(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7))); 2677 assert(interval.span(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7))); 2678 assert(interval.span(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7))); 2679 assert(interval.span(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7))); 2680 assert(interval.span(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8))); 2681 2682 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2683 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2684 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2685 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2686 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2687 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2688 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2689 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2690 assert(!interval.span(interval).empty); 2691 assert(!interval.span(cInterval).empty); 2692 assert(!interval.span(iInterval).empty); 2693 assert(!interval.span(posInfInterval).empty); 2694 assert(!interval.span(cPosInfInterval).empty); 2695 assert(!interval.span(iPosInfInterval).empty); 2696 assert(!interval.span(negInfInterval).empty); 2697 assert(!interval.span(cNegInfInterval).empty); 2698 assert(!interval.span(iNegInfInterval).empty); 2699 assert(!cInterval.span(interval).empty); 2700 assert(!cInterval.span(cInterval).empty); 2701 assert(!cInterval.span(iInterval).empty); 2702 assert(!cInterval.span(posInfInterval).empty); 2703 assert(!cInterval.span(cPosInfInterval).empty); 2704 assert(!cInterval.span(iPosInfInterval).empty); 2705 assert(!cInterval.span(negInfInterval).empty); 2706 assert(!cInterval.span(cNegInfInterval).empty); 2707 assert(!cInterval.span(iNegInfInterval).empty); 2708 assert(!iInterval.span(interval).empty); 2709 assert(!iInterval.span(cInterval).empty); 2710 assert(!iInterval.span(iInterval).empty); 2711 assert(!iInterval.span(posInfInterval).empty); 2712 assert(!iInterval.span(cPosInfInterval).empty); 2713 assert(!iInterval.span(iPosInfInterval).empty); 2714 assert(!iInterval.span(negInfInterval).empty); 2715 assert(!iInterval.span(cNegInfInterval).empty); 2716 assert(!iInterval.span(iNegInfInterval).empty); 2717 2718 // Verify Examples. 2719 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) == 2720 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); 2721 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == 2722 Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); 2723 2724 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(1990, 7, 6))) == 2725 PosInfInterval!Date(Date(1990, 7 , 6))); 2726 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(2050, 1, 1))) == 2727 PosInfInterval!Date(Date(1996, 1 , 2))); 2728 2729 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1602, 5, 21))) == 2730 NegInfInterval!Date(Date(2012, 3 , 1))); 2731 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) == 2732 NegInfInterval!Date(Date(2013, 1 , 12))); 2733 } 2734 2735 // Test Interval's shift(duration). 2736 @safe unittest 2737 { 2738 import std.datetime.date; 2739 2740 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2741 2742 static void testIntervalFail(Interval!Date interval, in Duration duration) 2743 { 2744 interval.shift(duration); 2745 } 2746 2747 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1))); 2748 2749 static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__) 2750 { 2751 interval.shift(duration); 2752 assert(interval == expected); 2753 } 2754 2755 testInterval(interval, dur!"days"(22), Interval!Date(Date(2010, 7, 26), Date(2012, 1, 29))); 2756 testInterval(interval, dur!"days"(-22), Interval!Date(Date(2010, 6, 12), Date(2011, 12, 16))); 2757 2758 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2759 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2760 static assert(!__traits(compiles, cInterval.shift(dur!"days"(5)))); 2761 static assert(!__traits(compiles, iInterval.shift(dur!"days"(5)))); 2762 2763 // Verify Examples. 2764 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); 2765 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); 2766 2767 interval1.shift(dur!"days"(50)); 2768 assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25))); 2769 2770 interval2.shift(dur!"days"(-50)); 2771 assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15))); 2772 } 2773 2774 // Test Interval's shift(int, int, AllowDayOverflow). 2775 @safe unittest 2776 { 2777 import std.datetime.date; 2778 2779 { 2780 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2781 2782 static void testIntervalFail(Interval!Date interval, int years, int months) 2783 { 2784 interval.shift(years, months); 2785 } 2786 2787 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0)); 2788 2789 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, 2790 in I expected, size_t line = __LINE__) 2791 { 2792 interval.shift(years, months, allow); 2793 assert(interval == expected); 2794 } 2795 2796 testInterval(interval, 5, 0, AllowDayOverflow.yes, Interval!Date(Date(2015, 7, 4), Date(2017, 1, 7))); 2797 testInterval(interval, -5, 0, AllowDayOverflow.yes, Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7))); 2798 2799 auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31)); 2800 2801 testInterval(interval2, 1, 1, AllowDayOverflow.yes, Interval!Date(Date(2001, 3, 1), Date(2011, 7, 1))); 2802 testInterval(interval2, 1, -1, AllowDayOverflow.yes, Interval!Date(Date(2000, 12, 29), Date(2011, 5, 1))); 2803 testInterval(interval2, -1, -1, AllowDayOverflow.yes, Interval!Date(Date(1998, 12, 29), Date(2009, 5, 1))); 2804 testInterval(interval2, -1, 1, AllowDayOverflow.yes, Interval!Date(Date(1999, 3, 1), Date(2009, 7, 1))); 2805 2806 testInterval(interval2, 1, 1, AllowDayOverflow.no, Interval!Date(Date(2001, 2, 28), Date(2011, 6, 30))); 2807 testInterval(interval2, 1, -1, AllowDayOverflow.no, Interval!Date(Date(2000, 12, 29), Date(2011, 4, 30))); 2808 testInterval(interval2, -1, -1, AllowDayOverflow.no, Interval!Date(Date(1998, 12, 29), Date(2009, 4, 30))); 2809 testInterval(interval2, -1, 1, AllowDayOverflow.no, Interval!Date(Date(1999, 2, 28), Date(2009, 6, 30))); 2810 } 2811 2812 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2813 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2814 static assert(!__traits(compiles, cInterval.shift(5))); 2815 static assert(!__traits(compiles, iInterval.shift(5))); 2816 2817 // Verify Examples. 2818 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 2819 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 2820 2821 interval1.shift(2); 2822 assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1))); 2823 2824 interval2.shift(-2); 2825 assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1))); 2826 } 2827 2828 // Test Interval's expand(Duration). 2829 @safe unittest 2830 { 2831 import std.datetime.date; 2832 2833 auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7)); 2834 2835 static void testIntervalFail(I)(I interval, in Duration duration) 2836 { 2837 interval.expand(duration); 2838 } 2839 2840 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1))); 2841 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)), dur!"days"(-5))); 2842 2843 static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__) 2844 { 2845 interval.expand(duration); 2846 assert(interval == expected); 2847 } 2848 2849 testInterval(interval, dur!"days"(22), Interval!Date(Date(2000, 6, 12), Date(2012, 1, 29))); 2850 testInterval(interval, dur!"days"(-22), Interval!Date(Date(2000, 7, 26), Date(2011, 12, 16))); 2851 2852 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2853 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2854 static assert(!__traits(compiles, cInterval.expand(dur!"days"(5)))); 2855 static assert(!__traits(compiles, iInterval.expand(dur!"days"(5)))); 2856 2857 // Verify Examples. 2858 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 2859 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 2860 2861 interval1.expand(dur!"days"(2)); 2862 assert(interval1 == Interval!Date(Date(1995, 12, 31), Date(2012, 3, 3))); 2863 2864 interval2.expand(dur!"days"(-2)); 2865 assert(interval2 == Interval!Date(Date(1996, 1, 4), Date(2012, 2, 28))); 2866 } 2867 2868 // Test Interval's expand(int, int, AllowDayOverflow, Direction) 2869 @safe unittest 2870 { 2871 import std.datetime.date; 2872 2873 { 2874 auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7)); 2875 2876 static void testIntervalFail(Interval!Date interval, int years, int months) 2877 { 2878 interval.expand(years, months); 2879 } 2880 2881 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0)); 2882 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)), -5, 0)); 2883 2884 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, Direction dir, 2885 in I expected, size_t line = __LINE__) 2886 { 2887 interval.expand(years, months, allow, dir); 2888 assert(interval == expected); 2889 } 2890 2891 testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.both, 2892 Interval!Date(Date(1995, 7, 4), Date(2017, 1, 7))); 2893 testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.both, 2894 Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7))); 2895 2896 testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.fwd, 2897 Interval!Date(Date(2000, 7, 4), Date(2017, 1, 7))); 2898 testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.fwd, 2899 Interval!Date(Date(2000, 7, 4), Date(2007, 1, 7))); 2900 2901 testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.bwd, 2902 Interval!Date(Date(1995, 7, 4), Date(2012, 1, 7))); 2903 testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.bwd, 2904 Interval!Date(Date(2005, 7, 4), Date(2012, 1, 7))); 2905 2906 auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31)); 2907 2908 testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.both, 2909 Interval!Date(Date(1998, 12, 29), Date(2011, 7, 1))); 2910 testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.both, 2911 Interval!Date(Date(1999, 3, 1), Date(2011, 5, 1))); 2912 testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.both, 2913 Interval!Date(Date(2001, 3, 1), Date(2009, 5, 1))); 2914 testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.both, 2915 Interval!Date(Date(2000, 12, 29), Date(2009, 7, 1))); 2916 2917 testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.both, 2918 Interval!Date(Date(1998, 12, 29), Date(2011, 6, 30))); 2919 testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.both, 2920 Interval!Date(Date(1999, 2, 28), Date(2011, 4, 30))); 2921 testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.both, 2922 Interval!Date(Date(2001, 2, 28), Date(2009, 4, 30))); 2923 testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.both, 2924 Interval!Date(Date(2000, 12, 29), Date(2009, 6, 30))); 2925 2926 testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.fwd, 2927 Interval!Date(Date(2000, 1, 29), Date(2011, 7, 1))); 2928 testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.fwd, 2929 Interval!Date(Date(2000, 1, 29), Date(2011, 5, 1))); 2930 testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.fwd, 2931 Interval!Date(Date(2000, 1, 29), Date(2009, 5, 1))); 2932 testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.fwd, 2933 Interval!Date(Date(2000, 1, 29), Date(2009, 7, 1))); 2934 2935 testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.fwd, 2936 Interval!Date(Date(2000, 1, 29), Date(2011, 6, 30))); 2937 testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.fwd, 2938 Interval!Date(Date(2000, 1, 29), Date(2011, 4, 30))); 2939 testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.fwd, 2940 Interval!Date(Date(2000, 1, 29), Date(2009, 4, 30))); 2941 testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.fwd, 2942 Interval!Date(Date(2000, 1, 29), Date(2009, 6, 30))); 2943 2944 testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.bwd, 2945 Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31))); 2946 testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.bwd, 2947 Interval!Date(Date(1999, 3, 1), Date(2010, 5, 31))); 2948 testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.bwd, 2949 Interval!Date(Date(2001, 3, 1), Date(2010, 5, 31))); 2950 testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.bwd, 2951 Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31))); 2952 2953 testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.bwd, 2954 Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31))); 2955 testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.bwd, 2956 Interval!Date(Date(1999, 2, 28), Date(2010, 5, 31))); 2957 testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.bwd, 2958 Interval!Date(Date(2001, 2, 28), Date(2010, 5, 31))); 2959 testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.bwd, 2960 Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31))); 2961 } 2962 2963 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2964 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2965 static assert(!__traits(compiles, cInterval.expand(5))); 2966 static assert(!__traits(compiles, iInterval.expand(5))); 2967 2968 // Verify Examples. 2969 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 2970 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 2971 2972 interval1.expand(2); 2973 assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); 2974 2975 interval2.expand(-2); 2976 assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); 2977 } 2978 2979 // Test Interval's fwdRange. 2980 @system unittest 2981 { 2982 import std.datetime.date; 2983 2984 { 2985 auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)); 2986 2987 static void testInterval1(Interval!Date interval) 2988 { 2989 interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 2990 } 2991 2992 assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2993 2994 static void testInterval2(Interval!Date interval) 2995 { 2996 interval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront(); 2997 } 2998 2999 assertThrown!DateTimeException(testInterval2(interval)); 3000 3001 assert(!interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 3002 assert(interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).empty); 3003 3004 assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front == 3005 Date(2010, 9, 12)); 3006 3007 assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange( 3008 everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 17)); 3009 } 3010 3011 // Verify Examples. 3012 { 3013 auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); 3014 auto func = delegate (in Date date) 3015 { 3016 if ((date.day & 1) == 0) 3017 return date + dur!"days"(2); 3018 return date + dur!"days"(1); 3019 }; 3020 auto range = interval.fwdRange(func); 3021 3022 // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). 3023 assert(range.front == Date(2010, 9, 1)); 3024 3025 range.popFront(); 3026 assert(range.front == Date(2010, 9, 2)); 3027 3028 range.popFront(); 3029 assert(range.front == Date(2010, 9, 4)); 3030 3031 range.popFront(); 3032 assert(range.front == Date(2010, 9, 6)); 3033 3034 range.popFront(); 3035 assert(range.front == Date(2010, 9, 8)); 3036 3037 range.popFront(); 3038 assert(range.empty); 3039 } 3040 3041 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 3042 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 3043 assert(!cInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 3044 assert(!iInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 3045 } 3046 3047 // Test Interval's bwdRange. 3048 @system unittest 3049 { 3050 import std.datetime.date; 3051 3052 { 3053 auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)); 3054 3055 static void testInterval1(Interval!Date interval) 3056 { 3057 interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 3058 } 3059 3060 assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 3061 3062 static void testInterval2(Interval!Date interval) 3063 { 3064 interval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront(); 3065 } 3066 3067 assertThrown!DateTimeException(testInterval2(interval)); 3068 3069 assert(!interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty); 3070 assert(interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).empty); 3071 3072 assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange( 3073 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front == Date(2010, 10, 1)); 3074 3075 assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange( 3076 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 24)); 3077 } 3078 3079 // Verify Examples. 3080 { 3081 auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); 3082 auto func = delegate (in Date date) 3083 { 3084 if ((date.day & 1) == 0) 3085 return date - dur!"days"(2); 3086 return date - dur!"days"(1); 3087 }; 3088 auto range = interval.bwdRange(func); 3089 3090 // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). 3091 assert(range.front == Date(2010, 9, 9)); 3092 3093 range.popFront(); 3094 assert(range.front == Date(2010, 9, 8)); 3095 3096 range.popFront(); 3097 assert(range.front == Date(2010, 9, 6)); 3098 3099 range.popFront(); 3100 assert(range.front == Date(2010, 9, 4)); 3101 3102 range.popFront(); 3103 assert(range.front == Date(2010, 9, 2)); 3104 3105 range.popFront(); 3106 assert(range.empty); 3107 } 3108 3109 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 3110 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 3111 assert(!cInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 3112 assert(!iInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 3113 } 3114 3115 // Test Interval's toString(). 3116 @safe unittest 3117 { 3118 import std.datetime.date; 3119 3120 assert(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).toString() == "[2010-Jul-04 - 2012-Jan-07)"); 3121 3122 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 3123 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 3124 assert(cInterval.toString()); 3125 assert(iInterval.toString()); 3126 } 3127 3128 3129 /++ 3130 Represents an interval of time which has positive infinity as its end point. 3131 3132 Any ranges which iterate over a $(D PosInfInterval) are infinite. So, the 3133 main purpose of using $(D PosInfInterval) is to create an infinite range 3134 which starts at a fixed point in time and goes to positive infinity. 3135 +/ 3136 struct PosInfInterval(TP) 3137 { 3138 public: 3139 3140 /++ 3141 Params: 3142 begin = The time point which begins the interval. 3143 3144 Example: 3145 -------------------- 3146 auto interval = PosInfInterval!Date(Date(1996, 1, 2)); 3147 -------------------- 3148 +/ 3149 this(in TP begin) pure nothrow 3150 { 3151 _begin = cast(TP) begin; 3152 } 3153 3154 3155 /++ 3156 Params: 3157 rhs = The $(D PosInfInterval) to assign to this one. 3158 +/ 3159 ref PosInfInterval opAssign(const ref PosInfInterval rhs) pure nothrow 3160 { 3161 _begin = cast(TP) rhs._begin; 3162 return this; 3163 } 3164 3165 3166 /++ 3167 Params: 3168 rhs = The $(D PosInfInterval) to assign to this one. 3169 +/ 3170 ref PosInfInterval opAssign(PosInfInterval rhs) pure nothrow 3171 { 3172 _begin = cast(TP) rhs._begin; 3173 return this; 3174 } 3175 3176 3177 /++ 3178 The starting point of the interval. It is included in the interval. 3179 3180 Example: 3181 -------------------- 3182 assert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2)); 3183 -------------------- 3184 +/ 3185 @property TP begin() const pure nothrow 3186 { 3187 return cast(TP)_begin; 3188 } 3189 3190 3191 /++ 3192 The starting point of the interval. It is included in the interval. 3193 3194 Params: 3195 timePoint = The time point to set $(D begin) to. 3196 +/ 3197 @property void begin(TP timePoint) pure nothrow 3198 { 3199 _begin = timePoint; 3200 } 3201 3202 3203 /++ 3204 Whether the interval's length is 0. Always returns false. 3205 3206 Example: 3207 -------------------- 3208 assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty); 3209 -------------------- 3210 +/ 3211 enum bool empty = false; 3212 3213 3214 /++ 3215 Whether the given time point is within this interval. 3216 3217 Params: 3218 timePoint = The time point to check for inclusion in this interval. 3219 3220 Example: 3221 -------------------- 3222 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24))); 3223 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5))); 3224 -------------------- 3225 +/ 3226 bool contains(TP timePoint) const pure nothrow 3227 { 3228 return timePoint >= _begin; 3229 } 3230 3231 3232 /++ 3233 Whether the given interval is completely within this interval. 3234 3235 Params: 3236 interval = The interval to check for inclusion in this interval. 3237 3238 Throws: 3239 $(REF DateTimeException,std,datetime,date) if the given interval 3240 is empty. 3241 3242 Example: 3243 -------------------- 3244 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains( 3245 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 3246 3247 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains( 3248 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 3249 3250 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains( 3251 Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); 3252 -------------------- 3253 +/ 3254 bool contains(in Interval!TP interval) const pure 3255 { 3256 interval._enforceNotEmpty(); 3257 return interval._begin >= _begin; 3258 } 3259 3260 3261 /++ 3262 Whether the given interval is completely within this interval. 3263 3264 Params: 3265 interval = The interval to check for inclusion in this interval. 3266 3267 Example: 3268 -------------------- 3269 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains( 3270 PosInfInterval!Date(Date(1999, 5, 4)))); 3271 3272 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains( 3273 PosInfInterval!Date(Date(1995, 7, 2)))); 3274 -------------------- 3275 +/ 3276 bool contains(in PosInfInterval interval) const pure nothrow 3277 { 3278 return interval._begin >= _begin; 3279 } 3280 3281 3282 /++ 3283 Whether the given interval is completely within this interval. 3284 3285 Always returns false because an interval going to positive infinity 3286 can never contain an interval beginning at negative infinity. 3287 3288 Params: 3289 interval = The interval to check for inclusion in this interval. 3290 3291 Example: 3292 -------------------- 3293 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains( 3294 NegInfInterval!Date(Date(1996, 5, 4)))); 3295 -------------------- 3296 +/ 3297 bool contains(in NegInfInterval!TP interval) const pure nothrow 3298 { 3299 return false; 3300 } 3301 3302 3303 /++ 3304 Whether this interval is before the given time point. 3305 3306 Always returns false because an interval going to positive infinity 3307 can never be before any time point. 3308 3309 Params: 3310 timePoint = The time point to check whether this interval is before 3311 it. 3312 3313 Example: 3314 -------------------- 3315 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24))); 3316 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5))); 3317 -------------------- 3318 +/ 3319 bool isBefore(in TP timePoint) const pure nothrow 3320 { 3321 return false; 3322 } 3323 3324 3325 /++ 3326 Whether this interval is before the given interval and does not 3327 intersect it. 3328 3329 Always returns false (unless the given interval is empty) because an 3330 interval going to positive infinity can never be before any other 3331 interval. 3332 3333 Params: 3334 interval = The interval to check for against this interval. 3335 3336 Throws: 3337 $(REF DateTimeException,std,datetime,date) if the given interval 3338 is empty. 3339 3340 Example: 3341 -------------------- 3342 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( 3343 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 3344 3345 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( 3346 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 3347 -------------------- 3348 +/ 3349 bool isBefore(in Interval!TP interval) const pure 3350 { 3351 interval._enforceNotEmpty(); 3352 return false; 3353 } 3354 3355 3356 /++ 3357 Whether this interval is before the given interval and does not 3358 intersect it. 3359 3360 Always returns false because an interval going to positive infinity can 3361 never be before any other interval. 3362 3363 Params: 3364 interval = The interval to check for against this interval. 3365 3366 Example: 3367 -------------------- 3368 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( 3369 PosInfInterval!Date(Date(1992, 5, 4)))); 3370 3371 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( 3372 PosInfInterval!Date(Date(2013, 3, 7)))); 3373 -------------------- 3374 +/ 3375 bool isBefore(in PosInfInterval interval) const pure nothrow 3376 { 3377 return false; 3378 } 3379 3380 3381 /++ 3382 Whether this interval is before the given interval and does not 3383 intersect it. 3384 3385 Always returns false because an interval going to positive infinity can 3386 never be before any other interval. 3387 3388 Params: 3389 interval = The interval to check for against this interval. 3390 3391 Example: 3392 -------------------- 3393 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( 3394 NegInfInterval!Date(Date(1996, 5, 4)))); 3395 -------------------- 3396 +/ 3397 bool isBefore(in NegInfInterval!TP interval) const pure nothrow 3398 { 3399 return false; 3400 } 3401 3402 3403 /++ 3404 Whether this interval is after the given time point. 3405 3406 Params: 3407 timePoint = The time point to check whether this interval is after 3408 it. 3409 3410 Example: 3411 -------------------- 3412 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24))); 3413 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5))); 3414 -------------------- 3415 +/ 3416 bool isAfter(in TP timePoint) const pure nothrow 3417 { 3418 return timePoint < _begin; 3419 } 3420 3421 3422 /++ 3423 Whether this interval is after the given interval and does not intersect 3424 it. 3425 3426 Params: 3427 interval = The interval to check against this interval. 3428 3429 Throws: 3430 $(REF DateTimeException,std,datetime,date) if the given interval 3431 is empty. 3432 3433 Example: 3434 -------------------- 3435 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3436 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 3437 3438 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3439 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 3440 3441 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3442 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 3443 -------------------- 3444 +/ 3445 bool isAfter(in Interval!TP interval) const pure 3446 { 3447 interval._enforceNotEmpty(); 3448 return _begin >= interval._end; 3449 } 3450 3451 3452 /++ 3453 Whether this interval is after the given interval and does not intersect 3454 it. 3455 3456 Always returns false because an interval going to positive infinity can 3457 never be after another interval going to positive infinity. 3458 3459 Params: 3460 interval = The interval to check against this interval. 3461 3462 Example: 3463 -------------------- 3464 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3465 PosInfInterval!Date(Date(1990, 1, 7)))); 3466 3467 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3468 PosInfInterval!Date(Date(1999, 5, 4)))); 3469 -------------------- 3470 +/ 3471 bool isAfter(in PosInfInterval interval) const pure nothrow 3472 { 3473 return false; 3474 } 3475 3476 3477 /++ 3478 Whether this interval is after the given interval and does not intersect 3479 it. 3480 3481 Params: 3482 interval = The interval to check against this interval. 3483 3484 Example: 3485 -------------------- 3486 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3487 NegInfInterval!Date(Date(1996, 1, 2)))); 3488 3489 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3490 NegInfInterval!Date(Date(2000, 7, 1)))); 3491 -------------------- 3492 +/ 3493 bool isAfter(in NegInfInterval!TP interval) const pure nothrow 3494 { 3495 return _begin >= interval._end; 3496 } 3497 3498 3499 /++ 3500 Whether the given interval overlaps this interval. 3501 3502 Params: 3503 interval = The interval to check for intersection with this interval. 3504 3505 Throws: 3506 $(REF DateTimeException,std,datetime,date) if the given interval 3507 is empty. 3508 3509 Example: 3510 -------------------- 3511 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3512 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 3513 3514 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3515 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 3516 3517 assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3518 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 3519 -------------------- 3520 +/ 3521 bool intersects(in Interval!TP interval) const pure 3522 { 3523 interval._enforceNotEmpty(); 3524 return interval._end > _begin; 3525 } 3526 3527 3528 /++ 3529 Whether the given interval overlaps this interval. 3530 3531 Always returns true because two intervals going to positive infinity 3532 always overlap. 3533 3534 Params: 3535 interval = The interval to check for intersection with this 3536 interval. 3537 3538 Example: 3539 -------------------- 3540 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3541 PosInfInterval!Date(Date(1990, 1, 7)))); 3542 3543 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3544 PosInfInterval!Date(Date(1999, 5, 4)))); 3545 -------------------- 3546 +/ 3547 bool intersects(in PosInfInterval interval) const pure nothrow 3548 { 3549 return true; 3550 } 3551 3552 3553 /++ 3554 Whether the given interval overlaps this interval. 3555 3556 Params: 3557 interval = The interval to check for intersection with this 3558 interval. 3559 3560 Example: 3561 -------------------- 3562 assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3563 NegInfInterval!Date(Date(1996, 1, 2)))); 3564 3565 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3566 NegInfInterval!Date(Date(2000, 7, 1)))); 3567 -------------------- 3568 +/ 3569 bool intersects(in NegInfInterval!TP interval) const pure nothrow 3570 { 3571 return _begin < interval._end; 3572 } 3573 3574 3575 /++ 3576 Returns the intersection of two intervals 3577 3578 Params: 3579 interval = The interval to intersect with this interval. 3580 3581 Throws: 3582 $(REF DateTimeException,std,datetime,date) if the two intervals do 3583 not intersect or if the given interval is empty. 3584 3585 Example: 3586 -------------------- 3587 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( 3588 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 3589 Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); 3590 3591 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( 3592 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 3593 Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); 3594 -------------------- 3595 +/ 3596 Interval!TP intersection(in Interval!TP interval) const 3597 { 3598 import std.format : format; 3599 3600 enforce(this.intersects(interval), 3601 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 3602 3603 auto begin = _begin > interval._begin ? _begin : interval._begin; 3604 3605 return Interval!TP(begin, interval._end); 3606 } 3607 3608 3609 /++ 3610 Returns the intersection of two intervals 3611 3612 Params: 3613 interval = The interval to intersect with this interval. 3614 3615 Example: 3616 -------------------- 3617 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( 3618 PosInfInterval!Date(Date(1990, 7, 6))) == 3619 PosInfInterval!Date(Date(1996, 1 , 2))); 3620 3621 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( 3622 PosInfInterval!Date(Date(1999, 1, 12))) == 3623 PosInfInterval!Date(Date(1999, 1 , 12))); 3624 -------------------- 3625 +/ 3626 PosInfInterval intersection(in PosInfInterval interval) const pure nothrow 3627 { 3628 return PosInfInterval(_begin < interval._begin ? interval._begin : _begin); 3629 } 3630 3631 3632 /++ 3633 Returns the intersection of two intervals 3634 3635 Params: 3636 interval = The interval to intersect with this interval. 3637 3638 Throws: 3639 $(REF DateTimeException,std,datetime,date) if the two intervals do 3640 not intersect. 3641 3642 Example: 3643 -------------------- 3644 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( 3645 NegInfInterval!Date(Date(1999, 7, 6))) == 3646 Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); 3647 3648 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( 3649 NegInfInterval!Date(Date(2013, 1, 12))) == 3650 Interval!Date(Date(1996, 1 , 2), Date(2013, 1, 12))); 3651 -------------------- 3652 +/ 3653 Interval!TP intersection(in NegInfInterval!TP interval) const 3654 { 3655 import std.format : format; 3656 3657 enforce(this.intersects(interval), 3658 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 3659 3660 return Interval!TP(_begin, interval._end); 3661 } 3662 3663 3664 /++ 3665 Whether the given interval is adjacent to this interval. 3666 3667 Params: 3668 interval = The interval to check whether its adjecent to this 3669 interval. 3670 3671 Throws: 3672 $(REF DateTimeException,std,datetime,date) if the given interval 3673 is empty. 3674 3675 Example: 3676 -------------------- 3677 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( 3678 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 3679 3680 assert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent( 3681 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 3682 -------------------- 3683 +/ 3684 bool isAdjacent(in Interval!TP interval) const pure 3685 { 3686 interval._enforceNotEmpty(); 3687 return _begin == interval._end; 3688 } 3689 3690 3691 /++ 3692 Whether the given interval is adjacent to this interval. 3693 3694 Always returns false because two intervals going to positive infinity 3695 can never be adjacent to one another. 3696 3697 Params: 3698 interval = The interval to check whether its adjecent to this 3699 interval. 3700 3701 Example: 3702 -------------------- 3703 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( 3704 PosInfInterval!Date(Date(1990, 1, 7)))); 3705 3706 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( 3707 PosInfInterval!Date(Date(1996, 1, 2)))); 3708 -------------------- 3709 +/ 3710 bool isAdjacent(in PosInfInterval interval) const pure nothrow 3711 { 3712 return false; 3713 } 3714 3715 3716 /++ 3717 Whether the given interval is adjacent to this interval. 3718 3719 Params: 3720 interval = The interval to check whether its adjecent to this 3721 interval. 3722 3723 Example: 3724 -------------------- 3725 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( 3726 NegInfInterval!Date(Date(1996, 1, 2)))); 3727 3728 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( 3729 NegInfInterval!Date(Date(2000, 7, 1)))); 3730 -------------------- 3731 +/ 3732 bool isAdjacent(in NegInfInterval!TP interval) const pure nothrow 3733 { 3734 return _begin == interval._end; 3735 } 3736 3737 3738 /++ 3739 Returns the union of two intervals 3740 3741 Params: 3742 interval = The interval to merge with this interval. 3743 3744 Throws: 3745 $(REF DateTimeException,std,datetime,date) if the two intervals do 3746 not intersect and are not adjacent or if the given interval is 3747 empty. 3748 3749 Note: 3750 There is no overload for $(D merge) which takes a 3751 $(D NegInfInterval), because an interval 3752 going from negative infinity to positive infinity 3753 is not possible. 3754 3755 Example: 3756 -------------------- 3757 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( 3758 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 3759 PosInfInterval!Date(Date(1990, 7 , 6))); 3760 3761 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( 3762 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 3763 PosInfInterval!Date(Date(1996, 1 , 2))); 3764 -------------------- 3765 +/ 3766 PosInfInterval merge(in Interval!TP interval) const 3767 { 3768 import std.format : format; 3769 3770 enforce(this.isAdjacent(interval) || this.intersects(interval), 3771 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); 3772 3773 return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); 3774 } 3775 3776 3777 /++ 3778 Returns the union of two intervals 3779 3780 Params: 3781 interval = The interval to merge with this interval. 3782 3783 Note: 3784 There is no overload for $(D merge) which takes a 3785 $(D NegInfInterval), because an interval 3786 going from negative infinity to positive infinity 3787 is not possible. 3788 3789 Example: 3790 -------------------- 3791 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( 3792 PosInfInterval!Date(Date(1990, 7, 6))) == 3793 PosInfInterval!Date(Date(1990, 7 , 6))); 3794 3795 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( 3796 PosInfInterval!Date(Date(1999, 1, 12))) == 3797 PosInfInterval!Date(Date(1996, 1 , 2))); 3798 -------------------- 3799 +/ 3800 PosInfInterval merge(in PosInfInterval interval) const pure nothrow 3801 { 3802 return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); 3803 } 3804 3805 3806 /++ 3807 Returns an interval that covers from the earliest time point of two 3808 intervals up to (but not including) the latest time point of two 3809 intervals. 3810 3811 Params: 3812 interval = The interval to create a span together with this 3813 interval. 3814 3815 Throws: 3816 $(REF DateTimeException,std,datetime,date) if the given interval 3817 is empty. 3818 3819 Note: 3820 There is no overload for $(D span) which takes a 3821 $(D NegInfInterval), because an interval 3822 going from negative infinity to positive infinity 3823 is not possible. 3824 3825 Example: 3826 -------------------- 3827 assert(PosInfInterval!Date(Date(1996, 1, 2)).span( 3828 Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) == 3829 PosInfInterval!Date(Date(500, 8, 9))); 3830 3831 assert(PosInfInterval!Date(Date(1996, 1, 2)).span( 3832 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 3833 PosInfInterval!Date(Date(1990, 7 , 6))); 3834 3835 assert(PosInfInterval!Date(Date(1996, 1, 2)).span( 3836 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 3837 PosInfInterval!Date(Date(1996, 1 , 2))); 3838 -------------------- 3839 +/ 3840 PosInfInterval span(in Interval!TP interval) const pure 3841 { 3842 interval._enforceNotEmpty(); 3843 return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); 3844 } 3845 3846 3847 /++ 3848 Returns an interval that covers from the earliest time point of two 3849 intervals up to (but not including) the latest time point of two 3850 intervals. 3851 3852 Params: 3853 interval = The interval to create a span together with this 3854 interval. 3855 3856 Note: 3857 There is no overload for $(D span) which takes a 3858 $(D NegInfInterval), because an interval 3859 going from negative infinity to positive infinity 3860 is not possible. 3861 3862 Example: 3863 -------------------- 3864 assert(PosInfInterval!Date(Date(1996, 1, 2)).span( 3865 PosInfInterval!Date(Date(1990, 7, 6))) == 3866 PosInfInterval!Date(Date(1990, 7 , 6))); 3867 3868 assert(PosInfInterval!Date(Date(1996, 1, 2)).span( 3869 PosInfInterval!Date(Date(1999, 1, 12))) == 3870 PosInfInterval!Date(Date(1996, 1 , 2))); 3871 -------------------- 3872 +/ 3873 PosInfInterval span(in PosInfInterval interval) const pure nothrow 3874 { 3875 return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); 3876 } 3877 3878 3879 /++ 3880 Shifts the $(D begin) of this interval forward or backwards in time by 3881 the given duration (a positive duration shifts the interval forward; a 3882 negative duration shifts it backward). Effectively, it does 3883 $(D begin += duration). 3884 3885 Params: 3886 duration = The duration to shift the interval by. 3887 3888 Example: 3889 -------------------- 3890 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 3891 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 3892 3893 interval1.shift(dur!"days"(50)); 3894 assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21))); 3895 3896 interval2.shift(dur!"days"(-50)); 3897 assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13))); 3898 -------------------- 3899 +/ 3900 void shift(D)(D duration) pure nothrow 3901 if (__traits(compiles, begin + duration)) 3902 { 3903 _begin += duration; 3904 } 3905 3906 3907 static if (__traits(compiles, begin.add!"months"(1)) && 3908 __traits(compiles, begin.add!"years"(1))) 3909 { 3910 /++ 3911 Shifts the $(D begin) of this interval forward or backwards in time 3912 by the given number of years and/or months (a positive number of 3913 years and months shifts the interval forward; a negative number 3914 shifts it backward). It adds the years the given years and months to 3915 $(D begin). It effectively calls $(D add!"years"()) and then 3916 $(D add!"months"()) on $(D begin) with the given number of years and 3917 months. 3918 3919 Params: 3920 years = The number of years to shift the interval by. 3921 months = The number of months to shift the interval by. 3922 allowOverflow = Whether the days should be allowed to overflow 3923 on $(D begin), causing its month to increment. 3924 3925 Throws: 3926 $(REF DateTimeException,std,datetime,date) if this interval is 3927 empty or if the resulting interval would be invalid. 3928 3929 Example: 3930 -------------------- 3931 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 3932 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 3933 3934 interval1.shift(dur!"days"(50)); 3935 assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21))); 3936 3937 interval2.shift(dur!"days"(-50)); 3938 assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13))); 3939 -------------------- 3940 +/ 3941 void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) 3942 if (isIntegral!T) 3943 { 3944 auto begin = _begin; 3945 3946 begin.add!"years"(years, allowOverflow); 3947 begin.add!"months"(months, allowOverflow); 3948 3949 _begin = begin; 3950 } 3951 } 3952 3953 3954 /++ 3955 Expands the interval backwards in time. Effectively, it does 3956 $(D begin -= duration). 3957 3958 Params: 3959 duration = The duration to expand the interval by. 3960 3961 Example: 3962 -------------------- 3963 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 3964 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 3965 3966 interval1.expand(dur!"days"(2)); 3967 assert(interval1 == PosInfInterval!Date(Date(1995, 12, 31))); 3968 3969 interval2.expand(dur!"days"(-2)); 3970 assert(interval2 == PosInfInterval!Date(Date(1996, 1, 4))); 3971 -------------------- 3972 +/ 3973 void expand(D)(D duration) pure nothrow 3974 if (__traits(compiles, begin + duration)) 3975 { 3976 _begin -= duration; 3977 } 3978 3979 3980 static if (__traits(compiles, begin.add!"months"(1)) && 3981 __traits(compiles, begin.add!"years"(1))) 3982 { 3983 /++ 3984 Expands the interval forwards and/or backwards in time. Effectively, 3985 it subtracts the given number of months/years from $(D begin). 3986 3987 Params: 3988 years = The number of years to expand the interval by. 3989 months = The number of months to expand the interval by. 3990 allowOverflow = Whether the days should be allowed to overflow 3991 on $(D begin), causing its month to increment. 3992 3993 Throws: 3994 $(REF DateTimeException,std,datetime,date) if this interval is 3995 empty or if the resulting interval would be invalid. 3996 3997 Example: 3998 -------------------- 3999 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 4000 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 4001 4002 interval1.expand(2); 4003 assert(interval1 == PosInfInterval!Date(Date(1994, 1, 2))); 4004 4005 interval2.expand(-2); 4006 assert(interval2 == PosInfInterval!Date(Date(1998, 1, 2))); 4007 -------------------- 4008 +/ 4009 void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) 4010 if (isIntegral!T) 4011 { 4012 auto begin = _begin; 4013 4014 begin.add!"years"(-years, allowOverflow); 4015 begin.add!"months"(-months, allowOverflow); 4016 4017 _begin = begin; 4018 } 4019 } 4020 4021 4022 /++ 4023 Returns a range which iterates forward over the interval, starting 4024 at $(D begin), using $(D_PARAM func) to generate each successive time 4025 point. 4026 4027 The range's $(D front) is the interval's $(D begin). $(D_PARAM func) is 4028 used to generate the next $(D front) when $(D popFront) is called. If 4029 $(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called 4030 before the range is returned (so that $(D front) is a time point which 4031 $(D_PARAM func) would generate). 4032 4033 If $(D_PARAM func) ever generates a time point less than or equal to the 4034 current $(D front) of the range, then a 4035 $(REF DateTimeException,std,datetime,date) will be thrown. 4036 4037 There are helper functions in this module which generate common 4038 delegates to pass to $(D fwdRange). Their documentation starts with 4039 "Range-generating function," to make them easily searchable. 4040 4041 Params: 4042 func = The function used to generate the time points of the 4043 range over the interval. 4044 popFirst = Whether $(D popFront) should be called on the range 4045 before returning it. 4046 4047 Throws: 4048 $(REF DateTimeException,std,datetime,date) if this interval is 4049 empty. 4050 4051 Warning: 4052 $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) 4053 would be a function pointer to a pure function, but forcing 4054 $(D_PARAM func) to be pure is far too restrictive to be useful, and 4055 in order to have the ease of use of having functions which generate 4056 functions to pass to $(D fwdRange), $(D_PARAM func) must be a 4057 delegate. 4058 4059 If $(D_PARAM func) retains state which changes as it is called, then 4060 some algorithms will not work correctly, because the range's 4061 $(D save) will have failed to have really saved the range's state. 4062 To avoid such bugs, don't pass a delegate which is 4063 not logically pure to $(D fwdRange). If $(D_PARAM func) is given the 4064 same time point with two different calls, it must return the same 4065 result both times. 4066 4067 Of course, none of the functions in this module have this problem, 4068 so it's only relevant for custom delegates. 4069 4070 Example: 4071 -------------------- 4072 auto interval = PosInfInterval!Date(Date(2010, 9, 1)); 4073 auto func = delegate (in Date date) //For iterating over even-numbered days. 4074 { 4075 if ((date.day & 1) == 0) 4076 return date + dur!"days"(2); 4077 4078 return date + dur!"days"(1); 4079 }; 4080 auto range = interval.fwdRange(func); 4081 4082 //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). 4083 assert(range.front == Date(2010, 9, 1)); 4084 4085 range.popFront(); 4086 assert(range.front == Date(2010, 9, 2)); 4087 4088 range.popFront(); 4089 assert(range.front == Date(2010, 9, 4)); 4090 4091 range.popFront(); 4092 assert(range.front == Date(2010, 9, 6)); 4093 4094 range.popFront(); 4095 assert(range.front == Date(2010, 9, 8)); 4096 4097 range.popFront(); 4098 assert(!range.empty); 4099 -------------------- 4100 +/ 4101 PosInfIntervalRange!(TP) fwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const 4102 { 4103 auto range = PosInfIntervalRange!(TP)(this, func); 4104 4105 if (popFirst == PopFirst.yes) 4106 range.popFront(); 4107 4108 return range; 4109 } 4110 4111 4112 /+ 4113 Converts this interval to a string. 4114 +/ 4115 //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't 4116 //have versions of toString() with extra modifiers, so we define one version 4117 //with modifiers and one without. 4118 string toString() 4119 { 4120 return _toStringImpl(); 4121 } 4122 4123 4124 /++ 4125 Converts this interval to a string. 4126 +/ 4127 //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't 4128 //have versions of toString() with extra modifiers, so we define one version 4129 //with modifiers and one without. 4130 string toString() const nothrow 4131 { 4132 return _toStringImpl(); 4133 } 4134 4135 private: 4136 4137 /+ 4138 Since we have two versions of toString(), we have _toStringImpl() 4139 so that they can share implementations. 4140 +/ 4141 string _toStringImpl() const nothrow 4142 { 4143 import std.format : format; 4144 try 4145 return format("[%s - ∞)", _begin); 4146 catch (Exception e) 4147 assert(0, "format() threw."); 4148 } 4149 4150 4151 TP _begin; 4152 } 4153 4154 //Test PosInfInterval's constructor. 4155 @safe unittest 4156 { 4157 import std.datetime.date; 4158 import std.datetime.systime; 4159 4160 PosInfInterval!Date(Date.init); 4161 PosInfInterval!TimeOfDay(TimeOfDay.init); 4162 PosInfInterval!DateTime(DateTime.init); 4163 PosInfInterval!SysTime(SysTime(0)); 4164 4165 //Verify Examples. 4166 auto interval = PosInfInterval!Date(Date(1996, 1, 2)); 4167 } 4168 4169 //Test PosInfInterval's begin. 4170 @safe unittest 4171 { 4172 import std.datetime.date; 4173 4174 assert(PosInfInterval!Date(Date(1, 1, 1)).begin == Date(1, 1, 1)); 4175 assert(PosInfInterval!Date(Date(2010, 1, 1)).begin == Date(2010, 1, 1)); 4176 assert(PosInfInterval!Date(Date(1997, 12, 31)).begin == Date(1997, 12, 31)); 4177 4178 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4179 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4180 assert(cPosInfInterval.begin != Date.init); 4181 assert(iPosInfInterval.begin != Date.init); 4182 4183 //Verify Examples. 4184 assert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2)); 4185 } 4186 4187 //Test PosInfInterval's empty. 4188 @safe unittest 4189 { 4190 import std.datetime.date; 4191 import std.datetime.systime; 4192 4193 assert(!PosInfInterval!Date(Date(2010, 1, 1)).empty); 4194 assert(!PosInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty); 4195 assert(!PosInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty); 4196 assert(!PosInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty); 4197 4198 const cPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4199 immutable iPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4200 assert(!cPosInfInterval.empty); 4201 assert(!iPosInfInterval.empty); 4202 4203 //Verify Examples. 4204 assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty); 4205 } 4206 4207 //Test PosInfInterval's contains(time point). 4208 @safe unittest 4209 { 4210 import std.datetime.date; 4211 4212 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4213 4214 assert(!posInfInterval.contains(Date(2009, 7, 4))); 4215 assert(!posInfInterval.contains(Date(2010, 7, 3))); 4216 assert(posInfInterval.contains(Date(2010, 7, 4))); 4217 assert(posInfInterval.contains(Date(2010, 7, 5))); 4218 assert(posInfInterval.contains(Date(2011, 7, 1))); 4219 assert(posInfInterval.contains(Date(2012, 1, 6))); 4220 assert(posInfInterval.contains(Date(2012, 1, 7))); 4221 assert(posInfInterval.contains(Date(2012, 1, 8))); 4222 assert(posInfInterval.contains(Date(2013, 1, 7))); 4223 4224 const cdate = Date(2010, 7, 6); 4225 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4226 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4227 assert(posInfInterval.contains(cdate)); 4228 assert(cPosInfInterval.contains(cdate)); 4229 assert(iPosInfInterval.contains(cdate)); 4230 4231 //Verify Examples. 4232 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24))); 4233 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5))); 4234 } 4235 4236 //Test PosInfInterval's contains(Interval). 4237 @safe unittest 4238 { 4239 import std.datetime.date; 4240 4241 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4242 4243 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval) 4244 { 4245 posInfInterval.contains(interval); 4246 } 4247 4248 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4249 4250 assert(posInfInterval.contains(posInfInterval)); 4251 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4252 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 4253 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 4254 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 4255 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 4256 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 4257 assert(posInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 4258 assert(posInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 4259 assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 4260 assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 4261 assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 4262 assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 4263 4264 assert(!posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 3)))); 4265 assert(posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 4)))); 4266 assert(posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 5)))); 4267 assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 6)))); 4268 assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 7)))); 4269 assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 8)))); 4270 4271 assert(PosInfInterval!Date(Date(2010, 7, 3)).contains(posInfInterval)); 4272 assert(PosInfInterval!Date(Date(2010, 7, 4)).contains(posInfInterval)); 4273 assert(!PosInfInterval!Date(Date(2010, 7, 5)).contains(posInfInterval)); 4274 assert(!PosInfInterval!Date(Date(2012, 1, 6)).contains(posInfInterval)); 4275 assert(!PosInfInterval!Date(Date(2012, 1, 7)).contains(posInfInterval)); 4276 assert(!PosInfInterval!Date(Date(2012, 1, 8)).contains(posInfInterval)); 4277 4278 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 3)))); 4279 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 4)))); 4280 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 5)))); 4281 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 6)))); 4282 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 7)))); 4283 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 8)))); 4284 4285 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4286 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4287 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4288 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4289 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4290 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4291 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4292 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4293 assert(posInfInterval.contains(interval)); 4294 assert(posInfInterval.contains(cInterval)); 4295 assert(posInfInterval.contains(iInterval)); 4296 assert(posInfInterval.contains(posInfInterval)); 4297 assert(posInfInterval.contains(cPosInfInterval)); 4298 assert(posInfInterval.contains(iPosInfInterval)); 4299 assert(!posInfInterval.contains(negInfInterval)); 4300 assert(!posInfInterval.contains(cNegInfInterval)); 4301 assert(!posInfInterval.contains(iNegInfInterval)); 4302 assert(cPosInfInterval.contains(interval)); 4303 assert(cPosInfInterval.contains(cInterval)); 4304 assert(cPosInfInterval.contains(iInterval)); 4305 assert(cPosInfInterval.contains(posInfInterval)); 4306 assert(cPosInfInterval.contains(cPosInfInterval)); 4307 assert(cPosInfInterval.contains(iPosInfInterval)); 4308 assert(!cPosInfInterval.contains(negInfInterval)); 4309 assert(!cPosInfInterval.contains(cNegInfInterval)); 4310 assert(!cPosInfInterval.contains(iNegInfInterval)); 4311 assert(iPosInfInterval.contains(interval)); 4312 assert(iPosInfInterval.contains(cInterval)); 4313 assert(iPosInfInterval.contains(iInterval)); 4314 assert(iPosInfInterval.contains(posInfInterval)); 4315 assert(iPosInfInterval.contains(cPosInfInterval)); 4316 assert(iPosInfInterval.contains(iPosInfInterval)); 4317 assert(!iPosInfInterval.contains(negInfInterval)); 4318 assert(!iPosInfInterval.contains(cNegInfInterval)); 4319 assert(!iPosInfInterval.contains(iNegInfInterval)); 4320 4321 //Verify Examples. 4322 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 4323 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 4324 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); 4325 4326 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(PosInfInterval!Date(Date(1999, 5, 4)))); 4327 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(PosInfInterval!Date(Date(1995, 7, 2)))); 4328 4329 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(NegInfInterval!Date(Date(1996, 5, 4)))); 4330 } 4331 4332 //Test PosInfInterval's isBefore(time point). 4333 @safe unittest 4334 { 4335 import std.datetime.date; 4336 4337 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4338 4339 assert(!posInfInterval.isBefore(Date(2009, 7, 3))); 4340 assert(!posInfInterval.isBefore(Date(2010, 7, 3))); 4341 assert(!posInfInterval.isBefore(Date(2010, 7, 4))); 4342 assert(!posInfInterval.isBefore(Date(2010, 7, 5))); 4343 assert(!posInfInterval.isBefore(Date(2011, 7, 1))); 4344 assert(!posInfInterval.isBefore(Date(2012, 1, 6))); 4345 assert(!posInfInterval.isBefore(Date(2012, 1, 7))); 4346 assert(!posInfInterval.isBefore(Date(2012, 1, 8))); 4347 assert(!posInfInterval.isBefore(Date(2013, 1, 7))); 4348 4349 const cdate = Date(2010, 7, 6); 4350 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4351 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4352 assert(!posInfInterval.isBefore(cdate)); 4353 assert(!cPosInfInterval.isBefore(cdate)); 4354 assert(!iPosInfInterval.isBefore(cdate)); 4355 4356 //Verify Examples. 4357 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24))); 4358 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5))); 4359 } 4360 4361 //Test PosInfInterval's isBefore(Interval). 4362 @safe unittest 4363 { 4364 import std.datetime.date; 4365 4366 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4367 4368 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval) 4369 { 4370 posInfInterval.isBefore(interval); 4371 } 4372 4373 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4374 4375 assert(!posInfInterval.isBefore(posInfInterval)); 4376 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4377 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 4378 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 4379 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 4380 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 4381 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 4382 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 4383 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 4384 assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 4385 assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 4386 assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 4387 assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 4388 4389 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 3)))); 4390 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 4)))); 4391 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 5)))); 4392 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 6)))); 4393 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 7)))); 4394 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 8)))); 4395 4396 assert(!PosInfInterval!Date(Date(2010, 7, 3)).isBefore(posInfInterval)); 4397 assert(!PosInfInterval!Date(Date(2010, 7, 4)).isBefore(posInfInterval)); 4398 assert(!PosInfInterval!Date(Date(2010, 7, 5)).isBefore(posInfInterval)); 4399 assert(!PosInfInterval!Date(Date(2012, 1, 6)).isBefore(posInfInterval)); 4400 assert(!PosInfInterval!Date(Date(2012, 1, 7)).isBefore(posInfInterval)); 4401 assert(!PosInfInterval!Date(Date(2012, 1, 8)).isBefore(posInfInterval)); 4402 4403 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 3)))); 4404 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 4)))); 4405 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 5)))); 4406 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 6)))); 4407 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 7)))); 4408 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 8)))); 4409 4410 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4411 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4412 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4413 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4414 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4415 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4416 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4417 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4418 assert(!posInfInterval.isBefore(interval)); 4419 assert(!posInfInterval.isBefore(cInterval)); 4420 assert(!posInfInterval.isBefore(iInterval)); 4421 assert(!posInfInterval.isBefore(posInfInterval)); 4422 assert(!posInfInterval.isBefore(cPosInfInterval)); 4423 assert(!posInfInterval.isBefore(iPosInfInterval)); 4424 assert(!posInfInterval.isBefore(negInfInterval)); 4425 assert(!posInfInterval.isBefore(cNegInfInterval)); 4426 assert(!posInfInterval.isBefore(iNegInfInterval)); 4427 assert(!cPosInfInterval.isBefore(interval)); 4428 assert(!cPosInfInterval.isBefore(cInterval)); 4429 assert(!cPosInfInterval.isBefore(iInterval)); 4430 assert(!cPosInfInterval.isBefore(posInfInterval)); 4431 assert(!cPosInfInterval.isBefore(cPosInfInterval)); 4432 assert(!cPosInfInterval.isBefore(iPosInfInterval)); 4433 assert(!cPosInfInterval.isBefore(negInfInterval)); 4434 assert(!cPosInfInterval.isBefore(cNegInfInterval)); 4435 assert(!cPosInfInterval.isBefore(iNegInfInterval)); 4436 assert(!iPosInfInterval.isBefore(interval)); 4437 assert(!iPosInfInterval.isBefore(cInterval)); 4438 assert(!iPosInfInterval.isBefore(iInterval)); 4439 assert(!iPosInfInterval.isBefore(posInfInterval)); 4440 assert(!iPosInfInterval.isBefore(cPosInfInterval)); 4441 assert(!iPosInfInterval.isBefore(iPosInfInterval)); 4442 assert(!iPosInfInterval.isBefore(negInfInterval)); 4443 assert(!iPosInfInterval.isBefore(cNegInfInterval)); 4444 assert(!iPosInfInterval.isBefore(iNegInfInterval)); 4445 4446 //Verify Examples. 4447 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 4448 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 4449 4450 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(PosInfInterval!Date(Date(1992, 5, 4)))); 4451 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(PosInfInterval!Date(Date(2013, 3, 7)))); 4452 4453 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(NegInfInterval!Date(Date(1996, 5, 4)))); 4454 } 4455 4456 //Test PosInfInterval's isAfter(time point). 4457 @safe unittest 4458 { 4459 import std.datetime.date; 4460 4461 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4462 4463 assert(posInfInterval.isAfter(Date(2009, 7, 3))); 4464 assert(posInfInterval.isAfter(Date(2010, 7, 3))); 4465 assert(!posInfInterval.isAfter(Date(2010, 7, 4))); 4466 assert(!posInfInterval.isAfter(Date(2010, 7, 5))); 4467 assert(!posInfInterval.isAfter(Date(2011, 7, 1))); 4468 assert(!posInfInterval.isAfter(Date(2012, 1, 6))); 4469 assert(!posInfInterval.isAfter(Date(2012, 1, 7))); 4470 assert(!posInfInterval.isAfter(Date(2012, 1, 8))); 4471 assert(!posInfInterval.isAfter(Date(2013, 1, 7))); 4472 4473 const cdate = Date(2010, 7, 6); 4474 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4475 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4476 assert(!posInfInterval.isAfter(cdate)); 4477 assert(!cPosInfInterval.isAfter(cdate)); 4478 assert(!iPosInfInterval.isAfter(cdate)); 4479 4480 //Verify Examples. 4481 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24))); 4482 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5))); 4483 } 4484 4485 //Test PosInfInterval's isAfter(Interval). 4486 @safe unittest 4487 { 4488 import std.datetime.date; 4489 4490 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4491 4492 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval) 4493 { 4494 posInfInterval.isAfter(interval); 4495 } 4496 4497 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4498 4499 assert(!posInfInterval.isAfter(posInfInterval)); 4500 assert(posInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4501 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 4502 assert(posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 4503 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 4504 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 4505 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 4506 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 4507 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 4508 assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 4509 assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 4510 assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 4511 assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 4512 4513 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 3)))); 4514 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 4)))); 4515 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 5)))); 4516 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 6)))); 4517 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 7)))); 4518 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 8)))); 4519 4520 assert(!PosInfInterval!Date(Date(2010, 7, 3)).isAfter(posInfInterval)); 4521 assert(!PosInfInterval!Date(Date(2010, 7, 4)).isAfter(posInfInterval)); 4522 assert(!PosInfInterval!Date(Date(2010, 7, 5)).isAfter(posInfInterval)); 4523 assert(!PosInfInterval!Date(Date(2012, 1, 6)).isAfter(posInfInterval)); 4524 assert(!PosInfInterval!Date(Date(2012, 1, 7)).isAfter(posInfInterval)); 4525 assert(!PosInfInterval!Date(Date(2012, 1, 8)).isAfter(posInfInterval)); 4526 4527 assert(posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 3)))); 4528 assert(posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 4)))); 4529 assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 5)))); 4530 assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 6)))); 4531 assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 7)))); 4532 assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 8)))); 4533 4534 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4535 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4536 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4537 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4538 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4539 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4540 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4541 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4542 assert(!posInfInterval.isAfter(interval)); 4543 assert(!posInfInterval.isAfter(cInterval)); 4544 assert(!posInfInterval.isAfter(iInterval)); 4545 assert(!posInfInterval.isAfter(posInfInterval)); 4546 assert(!posInfInterval.isAfter(cPosInfInterval)); 4547 assert(!posInfInterval.isAfter(iPosInfInterval)); 4548 assert(!posInfInterval.isAfter(negInfInterval)); 4549 assert(!posInfInterval.isAfter(cNegInfInterval)); 4550 assert(!posInfInterval.isAfter(iNegInfInterval)); 4551 assert(!cPosInfInterval.isAfter(interval)); 4552 assert(!cPosInfInterval.isAfter(cInterval)); 4553 assert(!cPosInfInterval.isAfter(iInterval)); 4554 assert(!cPosInfInterval.isAfter(posInfInterval)); 4555 assert(!cPosInfInterval.isAfter(cPosInfInterval)); 4556 assert(!cPosInfInterval.isAfter(iPosInfInterval)); 4557 assert(!cPosInfInterval.isAfter(negInfInterval)); 4558 assert(!cPosInfInterval.isAfter(cNegInfInterval)); 4559 assert(!cPosInfInterval.isAfter(iNegInfInterval)); 4560 assert(!iPosInfInterval.isAfter(interval)); 4561 assert(!iPosInfInterval.isAfter(cInterval)); 4562 assert(!iPosInfInterval.isAfter(iInterval)); 4563 assert(!iPosInfInterval.isAfter(posInfInterval)); 4564 assert(!iPosInfInterval.isAfter(cPosInfInterval)); 4565 assert(!iPosInfInterval.isAfter(iPosInfInterval)); 4566 assert(!iPosInfInterval.isAfter(negInfInterval)); 4567 assert(!iPosInfInterval.isAfter(cNegInfInterval)); 4568 assert(!iPosInfInterval.isAfter(iNegInfInterval)); 4569 4570 //Verify Examples. 4571 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 4572 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 4573 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 4574 4575 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(PosInfInterval!Date(Date(1990, 1, 7)))); 4576 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(PosInfInterval!Date(Date(1999, 5, 4)))); 4577 4578 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(NegInfInterval!Date(Date(1996, 1, 2)))); 4579 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(NegInfInterval!Date(Date(2000, 7, 1)))); 4580 } 4581 4582 //Test PosInfInterval's intersects(). 4583 @safe unittest 4584 { 4585 import std.datetime.date; 4586 4587 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4588 4589 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval) 4590 { 4591 posInfInterval.intersects(interval); 4592 } 4593 4594 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4595 4596 assert(posInfInterval.intersects(posInfInterval)); 4597 assert(!posInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4598 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 4599 assert(!posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 4600 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 4601 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 4602 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 4603 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 4604 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 4605 assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 4606 assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 4607 assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 4608 assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 4609 4610 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 3)))); 4611 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 4)))); 4612 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 5)))); 4613 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 6)))); 4614 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 7)))); 4615 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 8)))); 4616 4617 assert(PosInfInterval!Date(Date(2010, 7, 3)).intersects(posInfInterval)); 4618 assert(PosInfInterval!Date(Date(2010, 7, 4)).intersects(posInfInterval)); 4619 assert(PosInfInterval!Date(Date(2010, 7, 5)).intersects(posInfInterval)); 4620 assert(PosInfInterval!Date(Date(2012, 1, 6)).intersects(posInfInterval)); 4621 assert(PosInfInterval!Date(Date(2012, 1, 7)).intersects(posInfInterval)); 4622 assert(PosInfInterval!Date(Date(2012, 1, 8)).intersects(posInfInterval)); 4623 4624 assert(!posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 3)))); 4625 assert(!posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 4)))); 4626 assert(posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 5)))); 4627 assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 6)))); 4628 assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 7)))); 4629 assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 8)))); 4630 4631 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4632 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4633 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4634 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4635 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4636 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4637 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4638 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4639 assert(posInfInterval.intersects(interval)); 4640 assert(posInfInterval.intersects(cInterval)); 4641 assert(posInfInterval.intersects(iInterval)); 4642 assert(posInfInterval.intersects(posInfInterval)); 4643 assert(posInfInterval.intersects(cPosInfInterval)); 4644 assert(posInfInterval.intersects(iPosInfInterval)); 4645 assert(posInfInterval.intersects(negInfInterval)); 4646 assert(posInfInterval.intersects(cNegInfInterval)); 4647 assert(posInfInterval.intersects(iNegInfInterval)); 4648 assert(cPosInfInterval.intersects(interval)); 4649 assert(cPosInfInterval.intersects(cInterval)); 4650 assert(cPosInfInterval.intersects(iInterval)); 4651 assert(cPosInfInterval.intersects(posInfInterval)); 4652 assert(cPosInfInterval.intersects(cPosInfInterval)); 4653 assert(cPosInfInterval.intersects(iPosInfInterval)); 4654 assert(cPosInfInterval.intersects(negInfInterval)); 4655 assert(cPosInfInterval.intersects(cNegInfInterval)); 4656 assert(cPosInfInterval.intersects(iNegInfInterval)); 4657 assert(iPosInfInterval.intersects(interval)); 4658 assert(iPosInfInterval.intersects(cInterval)); 4659 assert(iPosInfInterval.intersects(iInterval)); 4660 assert(iPosInfInterval.intersects(posInfInterval)); 4661 assert(iPosInfInterval.intersects(cPosInfInterval)); 4662 assert(iPosInfInterval.intersects(iPosInfInterval)); 4663 assert(iPosInfInterval.intersects(negInfInterval)); 4664 assert(iPosInfInterval.intersects(cNegInfInterval)); 4665 assert(iPosInfInterval.intersects(iNegInfInterval)); 4666 4667 //Verify Examples. 4668 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 4669 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 4670 assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 4671 4672 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(PosInfInterval!Date(Date(1990, 1, 7)))); 4673 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(PosInfInterval!Date(Date(1999, 5, 4)))); 4674 4675 assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(NegInfInterval!Date(Date(1996, 1, 2)))); 4676 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(NegInfInterval!Date(Date(2000, 7, 1)))); 4677 } 4678 4679 //Test PosInfInterval's intersection(). 4680 @safe unittest 4681 { 4682 import std.datetime.date; 4683 4684 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4685 4686 static void testInterval(I, J)(in I interval1, in J interval2) 4687 { 4688 interval1.intersection(interval2); 4689 } 4690 4691 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4692 4693 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4694 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 4695 4696 assertThrown!DateTimeException(testInterval(posInfInterval, NegInfInterval!Date(Date(2010, 7, 3)))); 4697 assertThrown!DateTimeException(testInterval(posInfInterval, NegInfInterval!Date(Date(2010, 7, 4)))); 4698 4699 assert(posInfInterval.intersection(posInfInterval) == posInfInterval); 4700 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 4701 Interval!Date(Date(2010, 7, 4), Date(2013, 7, 3))); 4702 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 4703 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); 4704 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 4705 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 4706 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 4707 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 4708 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 4709 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); 4710 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 4711 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); 4712 assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 4713 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 4714 assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 4715 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))); 4716 assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 4717 Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))); 4718 assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == 4719 Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))); 4720 4721 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 4))); 4722 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4))); 4723 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 5))); 4724 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2012, 1, 6))); 4725 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2012, 1, 7))); 4726 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2012, 1, 8))); 4727 4728 assert(PosInfInterval!Date(Date(2010, 7, 3)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4729 assert(PosInfInterval!Date(Date(2010, 7, 4)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4730 assert(PosInfInterval!Date(Date(2010, 7, 5)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 5))); 4731 assert(PosInfInterval!Date(Date(2012, 1, 6)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 6))); 4732 assert(PosInfInterval!Date(Date(2012, 1, 7)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 7))); 4733 assert(PosInfInterval!Date(Date(2012, 1, 8)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 8))); 4734 4735 assert(posInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == 4736 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); 4737 assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == 4738 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6))); 4739 assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == 4740 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 4741 assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == 4742 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 4743 4744 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4745 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4746 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4747 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4748 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4749 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4750 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4751 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4752 assert(!posInfInterval.intersection(interval).empty); 4753 assert(!posInfInterval.intersection(cInterval).empty); 4754 assert(!posInfInterval.intersection(iInterval).empty); 4755 assert(!posInfInterval.intersection(posInfInterval).empty); 4756 assert(!posInfInterval.intersection(cPosInfInterval).empty); 4757 assert(!posInfInterval.intersection(iPosInfInterval).empty); 4758 assert(!posInfInterval.intersection(negInfInterval).empty); 4759 assert(!posInfInterval.intersection(cNegInfInterval).empty); 4760 assert(!posInfInterval.intersection(iNegInfInterval).empty); 4761 assert(!cPosInfInterval.intersection(interval).empty); 4762 assert(!cPosInfInterval.intersection(cInterval).empty); 4763 assert(!cPosInfInterval.intersection(iInterval).empty); 4764 assert(!cPosInfInterval.intersection(posInfInterval).empty); 4765 assert(!cPosInfInterval.intersection(cPosInfInterval).empty); 4766 assert(!cPosInfInterval.intersection(iPosInfInterval).empty); 4767 assert(!cPosInfInterval.intersection(negInfInterval).empty); 4768 assert(!cPosInfInterval.intersection(cNegInfInterval).empty); 4769 assert(!cPosInfInterval.intersection(iNegInfInterval).empty); 4770 assert(!iPosInfInterval.intersection(interval).empty); 4771 assert(!iPosInfInterval.intersection(cInterval).empty); 4772 assert(!iPosInfInterval.intersection(iInterval).empty); 4773 assert(!iPosInfInterval.intersection(posInfInterval).empty); 4774 assert(!iPosInfInterval.intersection(cPosInfInterval).empty); 4775 assert(!iPosInfInterval.intersection(iPosInfInterval).empty); 4776 assert(!iPosInfInterval.intersection(negInfInterval).empty); 4777 assert(!iPosInfInterval.intersection(cNegInfInterval).empty); 4778 assert(!iPosInfInterval.intersection(iNegInfInterval).empty); 4779 4780 //Verify Examples. 4781 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 4782 Interval!Date(Date(1996, 1, 2), Date(2000, 8, 2))); 4783 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 4784 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))); 4785 4786 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) == 4787 PosInfInterval!Date(Date(1996, 1, 2))); 4788 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) == 4789 PosInfInterval!Date(Date(1999, 1, 12))); 4790 4791 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) == 4792 Interval!Date(Date(1996, 1, 2), Date(1999, 7, 6))); 4793 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) == 4794 Interval!Date(Date(1996, 1, 2), Date(2013, 1, 12))); 4795 } 4796 4797 //Test PosInfInterval's isAdjacent(). 4798 @safe unittest 4799 { 4800 import std.datetime.date; 4801 4802 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4803 4804 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval) 4805 { 4806 posInfInterval.isAdjacent(interval); 4807 } 4808 4809 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4810 4811 assert(!posInfInterval.isAdjacent(posInfInterval)); 4812 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4813 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 4814 assert(posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 4815 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 4816 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 4817 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 4818 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 4819 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 4820 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 4821 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 4822 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 4823 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 4824 4825 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3)))); 4826 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4)))); 4827 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5)))); 4828 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6)))); 4829 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7)))); 4830 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8)))); 4831 4832 assert(!PosInfInterval!Date(Date(2010, 7, 3)).isAdjacent(posInfInterval)); 4833 assert(!PosInfInterval!Date(Date(2010, 7, 4)).isAdjacent(posInfInterval)); 4834 assert(!PosInfInterval!Date(Date(2010, 7, 5)).isAdjacent(posInfInterval)); 4835 assert(!PosInfInterval!Date(Date(2012, 1, 6)).isAdjacent(posInfInterval)); 4836 assert(!PosInfInterval!Date(Date(2012, 1, 7)).isAdjacent(posInfInterval)); 4837 assert(!PosInfInterval!Date(Date(2012, 1, 8)).isAdjacent(posInfInterval)); 4838 4839 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3)))); 4840 assert(posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4)))); 4841 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5)))); 4842 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6)))); 4843 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7)))); 4844 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8)))); 4845 4846 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4847 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4848 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4849 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4850 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4851 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4852 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4853 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4854 assert(!posInfInterval.isAdjacent(interval)); 4855 assert(!posInfInterval.isAdjacent(cInterval)); 4856 assert(!posInfInterval.isAdjacent(iInterval)); 4857 assert(!posInfInterval.isAdjacent(posInfInterval)); 4858 assert(!posInfInterval.isAdjacent(cPosInfInterval)); 4859 assert(!posInfInterval.isAdjacent(iPosInfInterval)); 4860 assert(!posInfInterval.isAdjacent(negInfInterval)); 4861 assert(!posInfInterval.isAdjacent(cNegInfInterval)); 4862 assert(!posInfInterval.isAdjacent(iNegInfInterval)); 4863 assert(!cPosInfInterval.isAdjacent(interval)); 4864 assert(!cPosInfInterval.isAdjacent(cInterval)); 4865 assert(!cPosInfInterval.isAdjacent(iInterval)); 4866 assert(!cPosInfInterval.isAdjacent(posInfInterval)); 4867 assert(!cPosInfInterval.isAdjacent(cPosInfInterval)); 4868 assert(!cPosInfInterval.isAdjacent(iPosInfInterval)); 4869 assert(!cPosInfInterval.isAdjacent(negInfInterval)); 4870 assert(!cPosInfInterval.isAdjacent(cNegInfInterval)); 4871 assert(!cPosInfInterval.isAdjacent(iNegInfInterval)); 4872 assert(!iPosInfInterval.isAdjacent(interval)); 4873 assert(!iPosInfInterval.isAdjacent(cInterval)); 4874 assert(!iPosInfInterval.isAdjacent(iInterval)); 4875 assert(!iPosInfInterval.isAdjacent(posInfInterval)); 4876 assert(!iPosInfInterval.isAdjacent(cPosInfInterval)); 4877 assert(!iPosInfInterval.isAdjacent(iPosInfInterval)); 4878 assert(!iPosInfInterval.isAdjacent(negInfInterval)); 4879 assert(!iPosInfInterval.isAdjacent(cNegInfInterval)); 4880 assert(!iPosInfInterval.isAdjacent(iNegInfInterval)); 4881 4882 //Verify Examples. 4883 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 4884 assert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 4885 4886 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(PosInfInterval!Date(Date(1990, 1, 7)))); 4887 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(PosInfInterval!Date(Date(1996, 1, 2)))); 4888 4889 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2)))); 4890 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(NegInfInterval!Date(Date(2000, 7, 1)))); 4891 } 4892 4893 //Test PosInfInterval's merge(). 4894 @safe unittest 4895 { 4896 import std.datetime.date; 4897 4898 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4899 4900 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval) 4901 { 4902 posInfInterval.merge(interval); 4903 } 4904 4905 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4906 4907 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4908 4909 assert(posInfInterval.merge(posInfInterval) == posInfInterval); 4910 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 4911 PosInfInterval!Date(Date(2010, 7, 1))); 4912 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 4913 PosInfInterval!Date(Date(2010, 7, 3))); 4914 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 4915 PosInfInterval!Date(Date(2010, 7, 3))); 4916 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 4917 PosInfInterval!Date(Date(2010, 7, 3))); 4918 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 4919 PosInfInterval!Date(Date(2010, 7, 3))); 4920 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 4921 PosInfInterval!Date(Date(2010, 7, 4))); 4922 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 4923 PosInfInterval!Date(Date(2010, 7, 4))); 4924 assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 4925 PosInfInterval!Date(Date(2010, 7, 4))); 4926 assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 4927 PosInfInterval!Date(Date(2010, 7, 4))); 4928 assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 4929 PosInfInterval!Date(Date(2010, 7, 4))); 4930 assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == 4931 PosInfInterval!Date(Date(2010, 7, 4))); 4932 4933 assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3))); 4934 assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4))); 4935 assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4))); 4936 assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4))); 4937 assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4))); 4938 assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4))); 4939 4940 assert(PosInfInterval!Date(Date(2010, 7, 3)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 3))); 4941 assert(PosInfInterval!Date(Date(2010, 7, 4)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4942 assert(PosInfInterval!Date(Date(2010, 7, 5)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4943 assert(PosInfInterval!Date(Date(2012, 1, 6)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4944 assert(PosInfInterval!Date(Date(2012, 1, 7)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4945 assert(PosInfInterval!Date(Date(2012, 1, 8)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4946 4947 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 3))))); 4948 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 4))))); 4949 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 5))))); 4950 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 6))))); 4951 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 7))))); 4952 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 8))))); 4953 4954 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4955 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4956 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4957 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4958 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4959 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4960 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4961 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4962 assert(!posInfInterval.merge(interval).empty); 4963 assert(!posInfInterval.merge(cInterval).empty); 4964 assert(!posInfInterval.merge(iInterval).empty); 4965 assert(!posInfInterval.merge(posInfInterval).empty); 4966 assert(!posInfInterval.merge(cPosInfInterval).empty); 4967 assert(!posInfInterval.merge(iPosInfInterval).empty); 4968 static assert(!__traits(compiles, posInfInterval.merge(negInfInterval))); 4969 static assert(!__traits(compiles, posInfInterval.merge(cNegInfInterval))); 4970 static assert(!__traits(compiles, posInfInterval.merge(iNegInfInterval))); 4971 assert(!cPosInfInterval.merge(interval).empty); 4972 assert(!cPosInfInterval.merge(cInterval).empty); 4973 assert(!cPosInfInterval.merge(iInterval).empty); 4974 assert(!cPosInfInterval.merge(posInfInterval).empty); 4975 assert(!cPosInfInterval.merge(cPosInfInterval).empty); 4976 assert(!cPosInfInterval.merge(iPosInfInterval).empty); 4977 static assert(!__traits(compiles, cPosInfInterval.merge(negInfInterval))); 4978 static assert(!__traits(compiles, cPosInfInterval.merge(cNegInfInterval))); 4979 static assert(!__traits(compiles, cPosInfInterval.merge(iNegInfInterval))); 4980 assert(!iPosInfInterval.merge(interval).empty); 4981 assert(!iPosInfInterval.merge(cInterval).empty); 4982 assert(!iPosInfInterval.merge(iInterval).empty); 4983 assert(!iPosInfInterval.merge(posInfInterval).empty); 4984 assert(!iPosInfInterval.merge(cPosInfInterval).empty); 4985 assert(!iPosInfInterval.merge(iPosInfInterval).empty); 4986 static assert(!__traits(compiles, iPosInfInterval.merge(negInfInterval))); 4987 static assert(!__traits(compiles, iPosInfInterval.merge(cNegInfInterval))); 4988 static assert(!__traits(compiles, iPosInfInterval.merge(iNegInfInterval))); 4989 4990 //Verify Examples. 4991 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 4992 PosInfInterval!Date(Date(1990, 7, 6))); 4993 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 4994 PosInfInterval!Date(Date(1996, 1, 2))); 4995 4996 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(PosInfInterval!Date(Date(1990, 7, 6))) == 4997 PosInfInterval!Date(Date(1990, 7, 6))); 4998 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(PosInfInterval!Date(Date(1999, 1, 12))) == 4999 PosInfInterval!Date(Date(1996, 1, 2))); 5000 } 5001 5002 //Test PosInfInterval's span(). 5003 @safe unittest 5004 { 5005 import std.datetime.date; 5006 5007 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5008 5009 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval) 5010 { 5011 posInfInterval.span(interval); 5012 } 5013 5014 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 5015 5016 assert(posInfInterval.span(posInfInterval) == posInfInterval); 5017 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == 5018 PosInfInterval!Date(Date(2010, 7, 1))); 5019 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 5020 PosInfInterval!Date(Date(2010, 7, 1))); 5021 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 5022 PosInfInterval!Date(Date(2010, 7, 3))); 5023 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 5024 PosInfInterval!Date(Date(2010, 7, 3))); 5025 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 5026 PosInfInterval!Date(Date(2010, 7, 3))); 5027 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 5028 PosInfInterval!Date(Date(2010, 7, 3))); 5029 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 5030 PosInfInterval!Date(Date(2010, 7, 4))); 5031 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 5032 PosInfInterval!Date(Date(2010, 7, 4))); 5033 assert(posInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 5034 PosInfInterval!Date(Date(2010, 7, 4))); 5035 assert(posInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 5036 PosInfInterval!Date(Date(2010, 7, 4))); 5037 assert(posInfInterval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 5038 PosInfInterval!Date(Date(2010, 7, 4))); 5039 assert(posInfInterval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == 5040 PosInfInterval!Date(Date(2010, 7, 4))); 5041 5042 assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3))); 5043 assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4))); 5044 assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4))); 5045 assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4))); 5046 assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4))); 5047 assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4))); 5048 5049 assert(PosInfInterval!Date(Date(2010, 7, 3)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 3))); 5050 assert(PosInfInterval!Date(Date(2010, 7, 4)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 5051 assert(PosInfInterval!Date(Date(2010, 7, 5)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 5052 assert(PosInfInterval!Date(Date(2012, 1, 6)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 5053 assert(PosInfInterval!Date(Date(2012, 1, 7)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 5054 assert(PosInfInterval!Date(Date(2012, 1, 8)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 5055 5056 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 3))))); 5057 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 4))))); 5058 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 5))))); 5059 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 6))))); 5060 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 7))))); 5061 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 8))))); 5062 5063 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 5064 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 5065 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 5066 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5067 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5068 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 5069 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 5070 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 5071 assert(!posInfInterval.span(interval).empty); 5072 assert(!posInfInterval.span(cInterval).empty); 5073 assert(!posInfInterval.span(iInterval).empty); 5074 assert(!posInfInterval.span(posInfInterval).empty); 5075 assert(!posInfInterval.span(cPosInfInterval).empty); 5076 assert(!posInfInterval.span(iPosInfInterval).empty); 5077 static assert(!__traits(compiles, posInfInterval.span(negInfInterval))); 5078 static assert(!__traits(compiles, posInfInterval.span(cNegInfInterval))); 5079 static assert(!__traits(compiles, posInfInterval.span(iNegInfInterval))); 5080 assert(!cPosInfInterval.span(interval).empty); 5081 assert(!cPosInfInterval.span(cInterval).empty); 5082 assert(!cPosInfInterval.span(iInterval).empty); 5083 assert(!cPosInfInterval.span(posInfInterval).empty); 5084 assert(!cPosInfInterval.span(cPosInfInterval).empty); 5085 assert(!cPosInfInterval.span(iPosInfInterval).empty); 5086 static assert(!__traits(compiles, cPosInfInterval.span(negInfInterval))); 5087 static assert(!__traits(compiles, cPosInfInterval.span(cNegInfInterval))); 5088 static assert(!__traits(compiles, cPosInfInterval.span(iNegInfInterval))); 5089 assert(!iPosInfInterval.span(interval).empty); 5090 assert(!iPosInfInterval.span(cInterval).empty); 5091 assert(!iPosInfInterval.span(iInterval).empty); 5092 assert(!iPosInfInterval.span(posInfInterval).empty); 5093 assert(!iPosInfInterval.span(cPosInfInterval).empty); 5094 assert(!iPosInfInterval.span(iPosInfInterval).empty); 5095 static assert(!__traits(compiles, iPosInfInterval.span(negInfInterval))); 5096 static assert(!__traits(compiles, iPosInfInterval.span(cNegInfInterval))); 5097 static assert(!__traits(compiles, iPosInfInterval.span(iNegInfInterval))); 5098 5099 //Verify Examples. 5100 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) == 5101 PosInfInterval!Date(Date(500, 8, 9))); 5102 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 5103 PosInfInterval!Date(Date(1990, 7, 6))); 5104 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 5105 PosInfInterval!Date(Date(1996, 1, 2))); 5106 5107 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(PosInfInterval!Date(Date(1990, 7, 6))) == 5108 PosInfInterval!Date(Date(1990, 7, 6))); 5109 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(PosInfInterval!Date(Date(1999, 1, 12))) == 5110 PosInfInterval!Date(Date(1996, 1, 2))); 5111 } 5112 5113 //Test PosInfInterval's shift(). 5114 @safe unittest 5115 { 5116 import std.datetime.date; 5117 5118 auto interval = PosInfInterval!Date(Date(2010, 7, 4)); 5119 5120 static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__) 5121 { 5122 interval.shift(duration); 5123 assert(interval == expected); 5124 } 5125 5126 testInterval(interval, dur!"days"(22), PosInfInterval!Date(Date(2010, 7, 26))); 5127 testInterval(interval, dur!"days"(-22), PosInfInterval!Date(Date(2010, 6, 12))); 5128 5129 const cInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5130 immutable iInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5131 static assert(!__traits(compiles, cInterval.shift(dur!"days"(5)))); 5132 static assert(!__traits(compiles, iInterval.shift(dur!"days"(5)))); 5133 5134 //Verify Examples. 5135 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 5136 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 5137 5138 interval1.shift(dur!"days"(50)); 5139 assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21))); 5140 5141 interval2.shift(dur!"days"(-50)); 5142 assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13))); 5143 } 5144 5145 //Test PosInfInterval's shift(int, int, AllowDayOverflow). 5146 @safe unittest 5147 { 5148 import std.datetime.date; 5149 5150 { 5151 auto interval = PosInfInterval!Date(Date(2010, 7, 4)); 5152 5153 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, 5154 in I expected, size_t line = __LINE__) 5155 { 5156 interval.shift(years, months, allow); 5157 assert(interval == expected); 5158 } 5159 5160 testInterval(interval, 5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2015, 7, 4))); 5161 testInterval(interval, -5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2005, 7, 4))); 5162 5163 auto interval2 = PosInfInterval!Date(Date(2000, 1, 29)); 5164 5165 testInterval(interval2, 1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2001, 3, 1))); 5166 testInterval(interval2, 1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2000, 12, 29))); 5167 testInterval(interval2, -1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1998, 12, 29))); 5168 testInterval(interval2, -1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1999, 3, 1))); 5169 5170 testInterval(interval2, 1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(2001, 2, 28))); 5171 testInterval(interval2, 1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(2000, 12, 29))); 5172 testInterval(interval2, -1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(1998, 12, 29))); 5173 testInterval(interval2, -1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(1999, 2, 28))); 5174 } 5175 5176 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5177 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5178 static assert(!__traits(compiles, cPosInfInterval.shift(1))); 5179 static assert(!__traits(compiles, iPosInfInterval.shift(1))); 5180 5181 //Verify Examples. 5182 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 5183 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 5184 5185 interval1.shift(2); 5186 assert(interval1 == PosInfInterval!Date(Date(1998, 1, 2))); 5187 5188 interval2.shift(-2); 5189 assert(interval2 == PosInfInterval!Date(Date(1994, 1, 2))); 5190 } 5191 5192 //Test PosInfInterval's expand(). 5193 @safe unittest 5194 { 5195 import std.datetime.date; 5196 5197 auto interval = PosInfInterval!Date(Date(2000, 7, 4)); 5198 5199 static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__) 5200 { 5201 interval.expand(duration); 5202 assert(interval == expected); 5203 } 5204 5205 testInterval(interval, dur!"days"(22), PosInfInterval!Date(Date(2000, 6, 12))); 5206 testInterval(interval, dur!"days"(-22), PosInfInterval!Date(Date(2000, 7, 26))); 5207 5208 const cInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5209 immutable iInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5210 static assert(!__traits(compiles, cInterval.expand(dur!"days"(5)))); 5211 static assert(!__traits(compiles, iInterval.expand(dur!"days"(5)))); 5212 5213 //Verify Examples. 5214 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 5215 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 5216 5217 interval1.expand(dur!"days"(2)); 5218 assert(interval1 == PosInfInterval!Date(Date(1995, 12, 31))); 5219 5220 interval2.expand(dur!"days"(-2)); 5221 assert(interval2 == PosInfInterval!Date(Date(1996, 1, 4))); 5222 } 5223 5224 //Test PosInfInterval's expand(int, int, AllowDayOverflow). 5225 @safe unittest 5226 { 5227 import std.datetime.date; 5228 5229 { 5230 auto interval = PosInfInterval!Date(Date(2000, 7, 4)); 5231 5232 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, 5233 in I expected, size_t line = __LINE__) 5234 { 5235 interval.expand(years, months, allow); 5236 assert(interval == expected); 5237 } 5238 5239 testInterval(interval, 5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(1995, 7, 4))); 5240 testInterval(interval, -5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2005, 7, 4))); 5241 5242 auto interval2 = PosInfInterval!Date(Date(2000, 1, 29)); 5243 5244 testInterval(interval2, 1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1998, 12, 29))); 5245 testInterval(interval2, 1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1999, 3, 1))); 5246 testInterval(interval2, -1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2001, 3, 1))); 5247 testInterval(interval2, -1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2000, 12, 29))); 5248 5249 testInterval(interval2, 1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(1998, 12, 29))); 5250 testInterval(interval2, 1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(1999, 2, 28))); 5251 testInterval(interval2, -1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(2001, 2, 28))); 5252 testInterval(interval2, -1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(2000, 12, 29))); 5253 } 5254 5255 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5256 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5257 static assert(!__traits(compiles, cPosInfInterval.expand(1))); 5258 static assert(!__traits(compiles, iPosInfInterval.expand(1))); 5259 5260 //Verify Examples. 5261 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 5262 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 5263 5264 interval1.expand(2); 5265 assert(interval1 == PosInfInterval!Date(Date(1994, 1, 2))); 5266 5267 interval2.expand(-2); 5268 assert(interval2 == PosInfInterval!Date(Date(1998, 1, 2))); 5269 } 5270 5271 //Test PosInfInterval's fwdRange(). 5272 @system unittest 5273 { 5274 import std.datetime.date; 5275 5276 auto posInfInterval = PosInfInterval!Date(Date(2010, 9, 19)); 5277 5278 static void testInterval(PosInfInterval!Date posInfInterval) 5279 { 5280 posInfInterval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront(); 5281 } 5282 5283 assertThrown!DateTimeException(testInterval(posInfInterval)); 5284 5285 assert(PosInfInterval!Date(Date(2010, 9, 12)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front == 5286 Date(2010, 9, 12)); 5287 5288 assert(PosInfInterval!Date(Date(2010, 9, 12)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front == 5289 Date(2010, 9, 17)); 5290 5291 //Verify Examples. 5292 auto interval = PosInfInterval!Date(Date(2010, 9, 1)); 5293 auto func = delegate (in Date date) 5294 { 5295 if ((date.day & 1) == 0) 5296 return date + dur!"days"(2); 5297 return date + dur!"days"(1); 5298 }; 5299 auto range = interval.fwdRange(func); 5300 5301 assert(range.front == Date(2010, 9, 1)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). 5302 5303 range.popFront(); 5304 assert(range.front == Date(2010, 9, 2)); 5305 5306 range.popFront(); 5307 assert(range.front == Date(2010, 9, 4)); 5308 5309 range.popFront(); 5310 assert(range.front == Date(2010, 9, 6)); 5311 5312 range.popFront(); 5313 assert(range.front == Date(2010, 9, 8)); 5314 5315 range.popFront(); 5316 assert(!range.empty); 5317 5318 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5319 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5320 assert(!cPosInfInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 5321 assert(!iPosInfInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 5322 } 5323 5324 //Test PosInfInterval's toString(). 5325 @safe unittest 5326 { 5327 import std.datetime.date; 5328 assert(PosInfInterval!Date(Date(2010, 7, 4)).toString() == "[2010-Jul-04 - ∞)"); 5329 5330 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5331 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5332 assert(cPosInfInterval.toString()); 5333 assert(iPosInfInterval.toString()); 5334 } 5335 5336 5337 /++ 5338 Represents an interval of time which has negative infinity as its starting 5339 point. 5340 5341 Any ranges which iterate over a $(D NegInfInterval) are infinite. So, the 5342 main purpose of using $(D NegInfInterval) is to create an infinite range 5343 which starts at negative infinity and goes to a fixed end point. 5344 Iterate over it in reverse. 5345 +/ 5346 struct NegInfInterval(TP) 5347 { 5348 public: 5349 5350 /++ 5351 Params: 5352 end = The time point which ends the interval. 5353 5354 Example: 5355 -------------------- 5356 auto interval = PosInfInterval!Date(Date(1996, 1, 2)); 5357 -------------------- 5358 +/ 5359 this(in TP end) pure nothrow 5360 { 5361 _end = cast(TP) end; 5362 } 5363 5364 5365 /++ 5366 Params: 5367 rhs = The $(D NegInfInterval) to assign to this one. 5368 +/ 5369 ref NegInfInterval opAssign(const ref NegInfInterval rhs) pure nothrow 5370 { 5371 _end = cast(TP) rhs._end; 5372 return this; 5373 } 5374 5375 5376 /++ 5377 Params: 5378 rhs = The $(D NegInfInterval) to assign to this one. 5379 +/ 5380 ref NegInfInterval opAssign(NegInfInterval rhs) pure nothrow 5381 { 5382 _end = cast(TP) rhs._end; 5383 return this; 5384 } 5385 5386 5387 /++ 5388 The end point of the interval. It is excluded from the interval. 5389 5390 Example: 5391 -------------------- 5392 assert(NegInfInterval!Date(Date(2012, 3, 1)).end == Date(2012, 3, 1)); 5393 -------------------- 5394 +/ 5395 @property TP end() const pure nothrow 5396 { 5397 return cast(TP)_end; 5398 } 5399 5400 5401 /++ 5402 The end point of the interval. It is excluded from the interval. 5403 5404 Params: 5405 timePoint = The time point to set end to. 5406 +/ 5407 @property void end(TP timePoint) pure nothrow 5408 { 5409 _end = timePoint; 5410 } 5411 5412 5413 /++ 5414 Whether the interval's length is 0. Always returns false. 5415 5416 Example: 5417 -------------------- 5418 assert(!NegInfInterval!Date(Date(1996, 1, 2)).empty); 5419 -------------------- 5420 +/ 5421 enum bool empty = false; 5422 5423 5424 /++ 5425 Whether the given time point is within this interval. 5426 5427 Params: 5428 timePoint = The time point to check for inclusion in this interval. 5429 5430 Example: 5431 -------------------- 5432 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(1994, 12, 24))); 5433 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2000, 1, 5))); 5434 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2012, 3, 1))); 5435 -------------------- 5436 +/ 5437 bool contains(TP timePoint) const pure nothrow 5438 { 5439 return timePoint < _end; 5440 } 5441 5442 5443 /++ 5444 Whether the given interval is completely within this interval. 5445 5446 Params: 5447 interval = The interval to check for inclusion in this interval. 5448 5449 Throws: 5450 $(REF DateTimeException,std,datetime,date) if the given interval 5451 is empty. 5452 5453 Example: 5454 -------------------- 5455 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains( 5456 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 5457 5458 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains( 5459 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 5460 5461 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains( 5462 Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); 5463 -------------------- 5464 +/ 5465 bool contains(in Interval!TP interval) const pure 5466 { 5467 interval._enforceNotEmpty(); 5468 return interval._end <= _end; 5469 } 5470 5471 5472 /++ 5473 Whether the given interval is completely within this interval. 5474 5475 Always returns false because an interval beginning at negative 5476 infinity can never contain an interval going to positive infinity. 5477 5478 Params: 5479 interval = The interval to check for inclusion in this interval. 5480 5481 Example: 5482 -------------------- 5483 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains( 5484 PosInfInterval!Date(Date(1999, 5, 4)))); 5485 -------------------- 5486 +/ 5487 bool contains(in PosInfInterval!TP interval) const pure nothrow 5488 { 5489 return false; 5490 } 5491 5492 5493 /++ 5494 Whether the given interval is completely within this interval. 5495 5496 Params: 5497 interval = The interval to check for inclusion in this interval. 5498 5499 Example: 5500 -------------------- 5501 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains( 5502 NegInfInterval!Date(Date(1996, 5, 4)))); 5503 5504 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains( 5505 NegInfInterval!Date(Date(2013, 7, 9)))); 5506 -------------------- 5507 +/ 5508 bool contains(in NegInfInterval interval) const pure nothrow 5509 { 5510 return interval._end <= _end; 5511 } 5512 5513 5514 /++ 5515 Whether this interval is before the given time point. 5516 5517 Params: 5518 timePoint = The time point to check whether this interval is 5519 before it. 5520 5521 Example: 5522 -------------------- 5523 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(1994, 12, 24))); 5524 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2000, 1, 5))); 5525 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2012, 3, 1))); 5526 -------------------- 5527 +/ 5528 bool isBefore(in TP timePoint) const pure nothrow 5529 { 5530 return timePoint >= _end; 5531 } 5532 5533 5534 /++ 5535 Whether this interval is before the given interval and does not 5536 intersect it. 5537 5538 Params: 5539 interval = The interval to check for against this interval. 5540 5541 Throws: 5542 $(REF DateTimeException,std,datetime,date) if the given interval 5543 is empty 5544 5545 Example: 5546 -------------------- 5547 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5548 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 5549 5550 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5551 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 5552 5553 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5554 Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 5555 -------------------- 5556 +/ 5557 bool isBefore(in Interval!TP interval) const pure 5558 { 5559 interval._enforceNotEmpty(); 5560 return _end <= interval._begin; 5561 } 5562 5563 5564 /++ 5565 Whether this interval is before the given interval and does not 5566 intersect it. 5567 5568 Params: 5569 interval = The interval to check for against this interval. 5570 5571 Example: 5572 -------------------- 5573 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5574 PosInfInterval!Date(Date(1999, 5, 4)))); 5575 5576 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5577 PosInfInterval!Date(Date(2012, 3, 1)))); 5578 -------------------- 5579 +/ 5580 bool isBefore(in PosInfInterval!TP interval) const pure nothrow 5581 { 5582 return _end <= interval._begin; 5583 } 5584 5585 5586 /++ 5587 Whether this interval is before the given interval and does not 5588 intersect it. 5589 5590 Always returns false because an interval beginning at negative 5591 infinity can never be before another interval beginning at negative 5592 infinity. 5593 5594 Params: 5595 interval = The interval to check for against this interval. 5596 5597 Example: 5598 -------------------- 5599 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5600 NegInfInterval!Date(Date(1996, 5, 4)))); 5601 5602 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5603 NegInfInterval!Date(Date(2013, 7, 9)))); 5604 -------------------- 5605 +/ 5606 bool isBefore(in NegInfInterval interval) const pure nothrow 5607 { 5608 return false; 5609 } 5610 5611 5612 /++ 5613 Whether this interval is after the given time point. 5614 5615 Always returns false because an interval beginning at negative infinity 5616 can never be after any time point. 5617 5618 Params: 5619 timePoint = The time point to check whether this interval is after 5620 it. 5621 5622 Example: 5623 -------------------- 5624 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(1994, 12, 24))); 5625 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2000, 1, 5))); 5626 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2012, 3, 1))); 5627 -------------------- 5628 +/ 5629 bool isAfter(in TP timePoint) const pure nothrow 5630 { 5631 return false; 5632 } 5633 5634 5635 /++ 5636 Whether this interval is after the given interval and does not 5637 intersect it. 5638 5639 Always returns false (unless the given interval is empty) because an 5640 interval beginning at negative infinity can never be after any other 5641 interval. 5642 5643 Params: 5644 interval = The interval to check against this interval. 5645 5646 Throws: 5647 $(REF DateTimeException,std,datetime,date) if the given interval 5648 is empty. 5649 5650 Example: 5651 -------------------- 5652 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5653 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 5654 5655 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5656 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 5657 5658 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5659 Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 5660 -------------------- 5661 +/ 5662 bool isAfter(in Interval!TP interval) const pure 5663 { 5664 interval._enforceNotEmpty(); 5665 return false; 5666 } 5667 5668 5669 /++ 5670 Whether this interval is after the given interval and does not intersect 5671 it. 5672 5673 Always returns false because an interval beginning at negative infinity 5674 can never be after any other interval. 5675 5676 Params: 5677 interval = The interval to check against this interval. 5678 5679 Example: 5680 -------------------- 5681 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5682 PosInfInterval!Date(Date(1999, 5, 4)))); 5683 5684 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5685 PosInfInterval!Date(Date(2012, 3, 1)))); 5686 -------------------- 5687 +/ 5688 bool isAfter(in PosInfInterval!TP interval) const pure nothrow 5689 { 5690 return false; 5691 } 5692 5693 5694 /++ 5695 Whether this interval is after the given interval and does not intersect 5696 it. 5697 5698 Always returns false because an interval beginning at negative infinity 5699 can never be after any other interval. 5700 5701 Params: 5702 interval = The interval to check against this interval. 5703 5704 Example: 5705 -------------------- 5706 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5707 NegInfInterval!Date(Date(1996, 5, 4)))); 5708 5709 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5710 NegInfInterval!Date(Date(2013, 7, 9)))); 5711 -------------------- 5712 +/ 5713 bool isAfter(in NegInfInterval interval) const pure nothrow 5714 { 5715 return false; 5716 } 5717 5718 5719 /++ 5720 Whether the given interval overlaps this interval. 5721 5722 Params: 5723 interval = The interval to check for intersection with this interval. 5724 5725 Throws: 5726 $(REF DateTimeException,std,datetime,date) if the given interval 5727 is empty. 5728 5729 Example: 5730 -------------------- 5731 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5732 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 5733 5734 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5735 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 5736 5737 assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5738 Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 5739 -------------------- 5740 +/ 5741 bool intersects(in Interval!TP interval) const pure 5742 { 5743 interval._enforceNotEmpty(); 5744 return interval._begin < _end; 5745 } 5746 5747 5748 /++ 5749 Whether the given interval overlaps this interval. 5750 5751 Params: 5752 interval = The interval to check for intersection with this 5753 interval. 5754 5755 Example: 5756 -------------------- 5757 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5758 PosInfInterval!Date(Date(1999, 5, 4)))); 5759 5760 assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5761 PosInfInterval!Date(Date(2012, 3, 1)))); 5762 -------------------- 5763 +/ 5764 bool intersects(in PosInfInterval!TP interval) const pure nothrow 5765 { 5766 return interval._begin < _end; 5767 } 5768 5769 5770 /++ 5771 Whether the given interval overlaps this interval. 5772 5773 Always returns true because two intervals beginning at negative infinity 5774 always overlap. 5775 5776 Params: 5777 interval = The interval to check for intersection with this interval. 5778 5779 Example: 5780 -------------------- 5781 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5782 NegInfInterval!Date(Date(1996, 5, 4)))); 5783 5784 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5785 NegInfInterval!Date(Date(2013, 7, 9)))); 5786 -------------------- 5787 +/ 5788 bool intersects(in NegInfInterval!TP interval) const pure nothrow 5789 { 5790 return true; 5791 } 5792 5793 5794 /++ 5795 Returns the intersection of two intervals 5796 5797 Params: 5798 interval = The interval to intersect with this interval. 5799 5800 Throws: 5801 $(REF DateTimeException,std,datetime,date) if the two intervals do 5802 not intersect or if the given interval is empty. 5803 5804 Example: 5805 -------------------- 5806 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( 5807 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 5808 Interval!Date(Date(1990, 7 , 6), Date(2000, 8, 2))); 5809 5810 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( 5811 Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == 5812 Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); 5813 -------------------- 5814 +/ 5815 Interval!TP intersection(in Interval!TP interval) const 5816 { 5817 import std.format : format; 5818 5819 enforce(this.intersects(interval), 5820 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 5821 5822 auto end = _end < interval._end ? _end : interval._end; 5823 5824 return Interval!TP(interval._begin, end); 5825 } 5826 5827 5828 /++ 5829 Returns the intersection of two intervals 5830 5831 Params: 5832 interval = The interval to intersect with this interval. 5833 5834 Throws: 5835 $(REF DateTimeException,std,datetime,date) if the two intervals do 5836 not intersect. 5837 5838 Example: 5839 -------------------- 5840 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( 5841 PosInfInterval!Date(Date(1990, 7, 6))) == 5842 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); 5843 5844 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( 5845 PosInfInterval!Date(Date(1999, 1, 12))) == 5846 Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); 5847 -------------------- 5848 +/ 5849 Interval!TP intersection(in PosInfInterval!TP interval) const 5850 { 5851 import std.format : format; 5852 5853 enforce(this.intersects(interval), 5854 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 5855 5856 return Interval!TP(interval._begin, _end); 5857 } 5858 5859 5860 /++ 5861 Returns the intersection of two intervals 5862 5863 Params: 5864 interval = The interval to intersect with this interval. 5865 5866 Example: 5867 -------------------- 5868 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( 5869 NegInfInterval!Date(Date(1999, 7, 6))) == 5870 NegInfInterval!Date(Date(1999, 7 , 6))); 5871 5872 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( 5873 NegInfInterval!Date(Date(2013, 1, 12))) == 5874 NegInfInterval!Date(Date(2012, 3 , 1))); 5875 -------------------- 5876 +/ 5877 NegInfInterval intersection(in NegInfInterval interval) const nothrow 5878 { 5879 return NegInfInterval(_end < interval._end ? _end : interval._end); 5880 } 5881 5882 5883 /++ 5884 Whether the given interval is adjacent to this interval. 5885 5886 Params: 5887 interval = The interval to check whether its adjecent to this 5888 interval. 5889 5890 Throws: 5891 $(REF DateTimeException,std,datetime,date) if the given interval 5892 is empty. 5893 5894 Example: 5895 -------------------- 5896 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5897 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 5898 5899 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5900 Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1)))); 5901 5902 assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5903 Interval!Date(Date(2012, 3, 1), Date(2019, 2, 2)))); 5904 5905 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5906 Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 5907 -------------------- 5908 +/ 5909 bool isAdjacent(in Interval!TP interval) const pure 5910 { 5911 interval._enforceNotEmpty(); 5912 return interval._begin == _end; 5913 } 5914 5915 5916 /++ 5917 Whether the given interval is adjacent to this interval. 5918 5919 Params: 5920 interval = The interval to check whether its adjecent to this 5921 interval. 5922 5923 Example: 5924 -------------------- 5925 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5926 PosInfInterval!Date(Date(1999, 5, 4)))); 5927 5928 assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5929 PosInfInterval!Date(Date(2012, 3, 1)))); 5930 -------------------- 5931 +/ 5932 bool isAdjacent(in PosInfInterval!TP interval) const pure nothrow 5933 { 5934 return interval._begin == _end; 5935 } 5936 5937 5938 /++ 5939 Whether the given interval is adjacent to this interval. 5940 5941 Always returns false because two intervals beginning at negative 5942 infinity can never be adjacent to one another. 5943 5944 Params: 5945 interval = The interval to check whether its adjecent to this 5946 interval. 5947 5948 Example: 5949 -------------------- 5950 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5951 NegInfInterval!Date(Date(1996, 5, 4)))); 5952 5953 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5954 NegInfInterval!Date(Date(2012, 3, 1)))); 5955 -------------------- 5956 +/ 5957 bool isAdjacent(in NegInfInterval interval) const pure nothrow 5958 { 5959 return false; 5960 } 5961 5962 5963 /++ 5964 Returns the union of two intervals 5965 5966 Params: 5967 interval = The interval to merge with this interval. 5968 5969 Throws: 5970 $(REF DateTimeException,std,datetime,date) if the two intervals do 5971 not intersect and are not adjacent or if the given interval is empty. 5972 5973 Note: 5974 There is no overload for $(D merge) which takes a 5975 $(D PosInfInterval), because an interval 5976 going from negative infinity to positive infinity 5977 is not possible. 5978 5979 Example: 5980 -------------------- 5981 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge( 5982 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 5983 NegInfInterval!Date(Date(2012, 3 , 1))); 5984 5985 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge( 5986 Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == 5987 NegInfInterval!Date(Date(2015, 9 , 2))); 5988 -------------------- 5989 +/ 5990 NegInfInterval merge(in Interval!TP interval) const 5991 { 5992 import std.format : format; 5993 5994 enforce(this.isAdjacent(interval) || this.intersects(interval), 5995 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); 5996 5997 return NegInfInterval(_end > interval._end ? _end : interval._end); 5998 } 5999 6000 6001 /++ 6002 Returns the union of two intervals 6003 6004 Params: 6005 interval = The interval to merge with this interval. 6006 6007 Note: 6008 There is no overload for $(D merge) which takes a 6009 $(D PosInfInterval), because an interval 6010 going from negative infinity to positive infinity 6011 is not possible. 6012 6013 Example: 6014 -------------------- 6015 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge( 6016 NegInfInterval!Date(Date(1999, 7, 6))) == 6017 NegInfInterval!Date(Date(2012, 3 , 1))); 6018 6019 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge( 6020 NegInfInterval!Date(Date(2013, 1, 12))) == 6021 NegInfInterval!Date(Date(2013, 1 , 12))); 6022 -------------------- 6023 +/ 6024 NegInfInterval merge(in NegInfInterval interval) const pure nothrow 6025 { 6026 return NegInfInterval(_end > interval._end ? _end : interval._end); 6027 } 6028 6029 6030 /++ 6031 Returns an interval that covers from the earliest time point of two 6032 intervals up to (but not including) the latest time point of two 6033 intervals. 6034 6035 Params: 6036 interval = The interval to create a span together with this 6037 interval. 6038 6039 Throws: 6040 $(REF DateTimeException,std,datetime,date) if the given interval 6041 is empty. 6042 6043 Note: 6044 There is no overload for $(D span) which takes a 6045 $(D PosInfInterval), because an interval 6046 going from negative infinity to positive infinity 6047 is not possible. 6048 6049 Example: 6050 -------------------- 6051 assert(NegInfInterval!Date(Date(2012, 3, 1)).span( 6052 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 6053 NegInfInterval!Date(Date(2012, 3 , 1))); 6054 6055 assert(NegInfInterval!Date(Date(2012, 3, 1)).span( 6056 Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == 6057 NegInfInterval!Date(Date(2015, 9 , 2))); 6058 6059 assert(NegInfInterval!Date(Date(1600, 1, 7)).span( 6060 Interval!Date(Date(2012, 3, 11), Date(2017, 7, 1))) == 6061 NegInfInterval!Date(Date(2017, 7 , 1))); 6062 -------------------- 6063 +/ 6064 NegInfInterval span(in Interval!TP interval) const pure 6065 { 6066 interval._enforceNotEmpty(); 6067 return NegInfInterval(_end > interval._end ? _end : interval._end); 6068 } 6069 6070 6071 /++ 6072 Returns an interval that covers from the earliest time point of two 6073 intervals up to (but not including) the latest time point of two 6074 intervals. 6075 6076 Params: 6077 interval = The interval to create a span together with this 6078 interval. 6079 6080 Note: 6081 There is no overload for $(D span) which takes a 6082 $(D PosInfInterval), because an interval 6083 going from negative infinity to positive infinity 6084 is not possible. 6085 6086 Example: 6087 -------------------- 6088 assert(NegInfInterval!Date(Date(2012, 3, 1)).span( 6089 NegInfInterval!Date(Date(1999, 7, 6))) == 6090 NegInfInterval!Date(Date(2012, 3 , 1))); 6091 6092 assert(NegInfInterval!Date(Date(2012, 3, 1)).span( 6093 NegInfInterval!Date(Date(2013, 1, 12))) == 6094 NegInfInterval!Date(Date(2013, 1 , 12))); 6095 -------------------- 6096 +/ 6097 NegInfInterval span(in NegInfInterval interval) const pure nothrow 6098 { 6099 return NegInfInterval(_end > interval._end ? _end : interval._end); 6100 } 6101 6102 6103 /++ 6104 Shifts the $(D end) of this interval forward or backwards in time by the 6105 given duration (a positive duration shifts the interval forward; a 6106 negative duration shifts it backward). Effectively, it does 6107 $(D end += duration). 6108 6109 Params: 6110 duration = The duration to shift the interval by. 6111 6112 Example: 6113 -------------------- 6114 auto interval1 = NegInfInterval!Date(Date(2012, 4, 5)); 6115 auto interval2 = NegInfInterval!Date(Date(2012, 4, 5)); 6116 6117 interval1.shift(dur!"days"(50)); 6118 assert(interval1 == NegInfInterval!Date(Date(2012, 5, 25))); 6119 6120 interval2.shift(dur!"days"(-50)); 6121 assert(interval2 == NegInfInterval!Date( Date(2012, 2, 15))); 6122 -------------------- 6123 +/ 6124 void shift(D)(D duration) pure nothrow 6125 if (__traits(compiles, end + duration)) 6126 { 6127 _end += duration; 6128 } 6129 6130 6131 static if (__traits(compiles, end.add!"months"(1)) && 6132 __traits(compiles, end.add!"years"(1))) 6133 { 6134 /++ 6135 Shifts the $(D end) of this interval forward or backwards in time by 6136 the given number of years and/or months (a positive number of years 6137 and months shifts the interval forward; a negative number shifts it 6138 backward). It adds the years the given years and months to end. It 6139 effectively calls $(D add!"years"()) and then $(D add!"months"()) 6140 on end with the given number of years and months. 6141 6142 Params: 6143 years = The number of years to shift the interval by. 6144 months = The number of months to shift the interval by. 6145 allowOverflow = Whether the days should be allowed to overflow 6146 on $(D end), causing its month to increment. 6147 6148 Throws: 6149 $(REF DateTimeException,std,datetime,date) if empty is true or 6150 if the resulting interval would be invalid. 6151 6152 Example: 6153 -------------------- 6154 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); 6155 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); 6156 6157 interval1.shift(2); 6158 assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1))); 6159 6160 interval2.shift(-2); 6161 assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1))); 6162 -------------------- 6163 +/ 6164 void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) 6165 if (isIntegral!T) 6166 { 6167 auto end = _end; 6168 6169 end.add!"years"(years, allowOverflow); 6170 end.add!"months"(months, allowOverflow); 6171 6172 _end = end; 6173 } 6174 } 6175 6176 6177 /++ 6178 Expands the interval forwards in time. Effectively, it does 6179 $(D end += duration). 6180 6181 Params: 6182 duration = The duration to expand the interval by. 6183 6184 Example: 6185 -------------------- 6186 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); 6187 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); 6188 6189 interval1.expand(dur!"days"(2)); 6190 assert(interval1 == NegInfInterval!Date(Date(2012, 3, 3))); 6191 6192 interval2.expand(dur!"days"(-2)); 6193 assert(interval2 == NegInfInterval!Date(Date(2012, 2, 28))); 6194 -------------------- 6195 +/ 6196 void expand(D)(D duration) pure nothrow 6197 if (__traits(compiles, end + duration)) 6198 { 6199 _end += duration; 6200 } 6201 6202 6203 static if (__traits(compiles, end.add!"months"(1)) && 6204 __traits(compiles, end.add!"years"(1))) 6205 { 6206 /++ 6207 Expands the interval forwards and/or backwards in time. Effectively, 6208 it adds the given number of months/years to end. 6209 6210 Params: 6211 years = The number of years to expand the interval by. 6212 months = The number of months to expand the interval by. 6213 allowOverflow = Whether the days should be allowed to overflow 6214 on $(D end), causing their month to increment. 6215 6216 Throws: 6217 $(REF DateTimeException,std,datetime,date) if empty is true or 6218 if the resulting interval would be invalid. 6219 6220 Example: 6221 -------------------- 6222 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); 6223 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); 6224 6225 interval1.expand(2); 6226 assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1))); 6227 6228 interval2.expand(-2); 6229 assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1))); 6230 -------------------- 6231 +/ 6232 void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) 6233 if (isIntegral!T) 6234 { 6235 auto end = _end; 6236 6237 end.add!"years"(years, allowOverflow); 6238 end.add!"months"(months, allowOverflow); 6239 6240 _end = end; 6241 } 6242 } 6243 6244 6245 /++ 6246 Returns a range which iterates backwards over the interval, starting 6247 at $(D end), using $(D_PARAM func) to generate each successive time 6248 point. 6249 6250 The range's $(D front) is the interval's $(D end). $(D_PARAM func) is 6251 used to generate the next $(D front) when $(D popFront) is called. If 6252 $(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called 6253 before the range is returned (so that $(D front) is a time point which 6254 $(D_PARAM func) would generate). 6255 6256 If $(D_PARAM func) ever generates a time point greater than or equal to 6257 the current $(D front) of the range, then a 6258 $(REF DateTimeException,std,datetime,date) will be thrown. 6259 6260 There are helper functions in this module which generate common 6261 delegates to pass to $(D bwdRange). Their documentation starts with 6262 "Range-generating function," to make them easily searchable. 6263 6264 Params: 6265 func = The function used to generate the time points of the 6266 range over the interval. 6267 popFirst = Whether $(D popFront) should be called on the range 6268 before returning it. 6269 6270 Throws: 6271 $(REF DateTimeException,std,datetime,date) if this interval is 6272 empty. 6273 6274 Warning: 6275 $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) 6276 would be a function pointer to a pure function, but forcing 6277 $(D_PARAM func) to be pure is far too restrictive to be useful, and 6278 in order to have the ease of use of having functions which generate 6279 functions to pass to $(D fwdRange), $(D_PARAM func) must be a 6280 delegate. 6281 6282 If $(D_PARAM func) retains state which changes as it is called, then 6283 some algorithms will not work correctly, because the range's 6284 $(D save) will have failed to have really saved the range's state. 6285 To avoid such bugs, don't pass a delegate which is 6286 not logically pure to $(D fwdRange). If $(D_PARAM func) is given the 6287 same time point with two different calls, it must return the same 6288 result both times. 6289 6290 Of course, none of the functions in this module have this problem, 6291 so it's only relevant for custom delegates. 6292 6293 Example: 6294 -------------------- 6295 auto interval = NegInfInterval!Date(Date(2010, 9, 9)); 6296 auto func = delegate (in Date date) //For iterating over even-numbered days. 6297 { 6298 if ((date.day & 1) == 0) 6299 return date - dur!"days"(2); 6300 6301 return date - dur!"days"(1); 6302 }; 6303 auto range = interval.bwdRange(func); 6304 6305 assert(range.front == Date(2010, 9, 9)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). 6306 6307 range.popFront(); 6308 assert(range.front == Date(2010, 9, 8)); 6309 6310 range.popFront(); 6311 assert(range.front == Date(2010, 9, 6)); 6312 6313 range.popFront(); 6314 assert(range.front == Date(2010, 9, 4)); 6315 6316 range.popFront(); 6317 assert(range.front == Date(2010, 9, 2)); 6318 6319 range.popFront(); 6320 assert(!range.empty); 6321 -------------------- 6322 +/ 6323 NegInfIntervalRange!(TP) bwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const 6324 { 6325 auto range = NegInfIntervalRange!(TP)(this, func); 6326 6327 if (popFirst == PopFirst.yes) 6328 range.popFront(); 6329 6330 return range; 6331 } 6332 6333 6334 /+ 6335 Converts this interval to a string. 6336 +/ 6337 //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't 6338 //have versions of toString() with extra modifiers, so we define one version 6339 //with modifiers and one without. 6340 string toString() 6341 { 6342 return _toStringImpl(); 6343 } 6344 6345 6346 /++ 6347 Converts this interval to a string. 6348 +/ 6349 //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't 6350 //have versions of toString() with extra modifiers, so we define one version 6351 //with modifiers and one without. 6352 string toString() const nothrow 6353 { 6354 return _toStringImpl(); 6355 } 6356 6357 private: 6358 6359 /+ 6360 Since we have two versions of toString(), we have _toStringImpl() 6361 so that they can share implementations. 6362 +/ 6363 string _toStringImpl() const nothrow 6364 { 6365 import std.format : format; 6366 try 6367 return format("[-∞ - %s)", _end); 6368 catch (Exception e) 6369 assert(0, "format() threw."); 6370 } 6371 6372 6373 TP _end; 6374 } 6375 6376 //Test NegInfInterval's constructor. 6377 @safe unittest 6378 { 6379 import std.datetime.date; 6380 import std.datetime.systime; 6381 6382 NegInfInterval!Date(Date.init); 6383 NegInfInterval!TimeOfDay(TimeOfDay.init); 6384 NegInfInterval!DateTime(DateTime.init); 6385 NegInfInterval!SysTime(SysTime(0)); 6386 } 6387 6388 //Test NegInfInterval's end. 6389 @safe unittest 6390 { 6391 import std.datetime.date; 6392 6393 assert(NegInfInterval!Date(Date(2010, 1, 1)).end == Date(2010, 1, 1)); 6394 assert(NegInfInterval!Date(Date(2010, 1, 1)).end == Date(2010, 1, 1)); 6395 assert(NegInfInterval!Date(Date(1998, 1, 1)).end == Date(1998, 1, 1)); 6396 6397 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6398 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6399 assert(cNegInfInterval.end != Date.init); 6400 assert(iNegInfInterval.end != Date.init); 6401 6402 //Verify Examples. 6403 assert(NegInfInterval!Date(Date(2012, 3, 1)).end == Date(2012, 3, 1)); 6404 } 6405 6406 //Test NegInfInterval's empty. 6407 @safe unittest 6408 { 6409 import std.datetime.date; 6410 import std.datetime.systime; 6411 6412 assert(!NegInfInterval!Date(Date(2010, 1, 1)).empty); 6413 assert(!NegInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty); 6414 assert(!NegInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty); 6415 assert(!NegInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty); 6416 6417 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6418 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6419 assert(!cNegInfInterval.empty); 6420 assert(!iNegInfInterval.empty); 6421 6422 //Verify Examples. 6423 assert(!NegInfInterval!Date(Date(1996, 1, 2)).empty); 6424 } 6425 6426 //Test NegInfInterval's contains(time point). 6427 @safe unittest 6428 { 6429 import std.datetime.date; 6430 6431 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6432 6433 assert(negInfInterval.contains(Date(2009, 7, 4))); 6434 assert(negInfInterval.contains(Date(2010, 7, 3))); 6435 assert(negInfInterval.contains(Date(2010, 7, 4))); 6436 assert(negInfInterval.contains(Date(2010, 7, 5))); 6437 assert(negInfInterval.contains(Date(2011, 7, 1))); 6438 assert(negInfInterval.contains(Date(2012, 1, 6))); 6439 assert(!negInfInterval.contains(Date(2012, 1, 7))); 6440 assert(!negInfInterval.contains(Date(2012, 1, 8))); 6441 assert(!negInfInterval.contains(Date(2013, 1, 7))); 6442 6443 const cdate = Date(2010, 7, 6); 6444 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6445 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6446 assert(negInfInterval.contains(cdate)); 6447 assert(cNegInfInterval.contains(cdate)); 6448 assert(iNegInfInterval.contains(cdate)); 6449 6450 //Verify Examples. 6451 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(1994, 12, 24))); 6452 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2000, 1, 5))); 6453 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2012, 3, 1))); 6454 } 6455 6456 //Test NegInfInterval's contains(Interval). 6457 @safe unittest 6458 { 6459 import std.datetime.date; 6460 6461 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6462 6463 static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval) 6464 { 6465 negInfInterval.contains(interval); 6466 } 6467 6468 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 6469 6470 assert(negInfInterval.contains(negInfInterval)); 6471 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 6472 assert(!negInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 6473 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 6474 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 6475 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 6476 assert(!negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 6477 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 6478 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 6479 assert(negInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 6480 assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 6481 assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 6482 assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 6483 6484 assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 3)))); 6485 assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 4)))); 6486 assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 5)))); 6487 assert(negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 6)))); 6488 assert(negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 7)))); 6489 assert(!negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 8)))); 6490 6491 assert(!NegInfInterval!Date(Date(2010, 7, 3)).contains(negInfInterval)); 6492 assert(!NegInfInterval!Date(Date(2010, 7, 4)).contains(negInfInterval)); 6493 assert(!NegInfInterval!Date(Date(2010, 7, 5)).contains(negInfInterval)); 6494 assert(!NegInfInterval!Date(Date(2012, 1, 6)).contains(negInfInterval)); 6495 assert(NegInfInterval!Date(Date(2012, 1, 7)).contains(negInfInterval)); 6496 assert(NegInfInterval!Date(Date(2012, 1, 8)).contains(negInfInterval)); 6497 6498 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 3)))); 6499 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 4)))); 6500 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 5)))); 6501 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 6)))); 6502 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 7)))); 6503 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 8)))); 6504 6505 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6506 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6507 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6508 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6509 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6510 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6511 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6512 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6513 assert(negInfInterval.contains(interval)); 6514 assert(negInfInterval.contains(cInterval)); 6515 assert(negInfInterval.contains(iInterval)); 6516 assert(!negInfInterval.contains(posInfInterval)); 6517 assert(!negInfInterval.contains(cPosInfInterval)); 6518 assert(!negInfInterval.contains(iPosInfInterval)); 6519 assert(negInfInterval.contains(negInfInterval)); 6520 assert(negInfInterval.contains(cNegInfInterval)); 6521 assert(negInfInterval.contains(iNegInfInterval)); 6522 assert(cNegInfInterval.contains(interval)); 6523 assert(cNegInfInterval.contains(cInterval)); 6524 assert(cNegInfInterval.contains(iInterval)); 6525 assert(!cNegInfInterval.contains(posInfInterval)); 6526 assert(!cNegInfInterval.contains(cPosInfInterval)); 6527 assert(!cNegInfInterval.contains(iPosInfInterval)); 6528 assert(cNegInfInterval.contains(negInfInterval)); 6529 assert(cNegInfInterval.contains(cNegInfInterval)); 6530 assert(cNegInfInterval.contains(iNegInfInterval)); 6531 assert(iNegInfInterval.contains(interval)); 6532 assert(iNegInfInterval.contains(cInterval)); 6533 assert(iNegInfInterval.contains(iInterval)); 6534 assert(!iNegInfInterval.contains(posInfInterval)); 6535 assert(!iNegInfInterval.contains(cPosInfInterval)); 6536 assert(!iNegInfInterval.contains(iPosInfInterval)); 6537 assert(iNegInfInterval.contains(negInfInterval)); 6538 assert(iNegInfInterval.contains(cNegInfInterval)); 6539 assert(iNegInfInterval.contains(iNegInfInterval)); 6540 6541 //Verify Examples. 6542 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 6543 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 6544 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); 6545 6546 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4)))); 6547 6548 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4)))); 6549 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(2013, 7, 9)))); 6550 } 6551 6552 //Test NegInfInterval's isBefore(time point). 6553 @safe unittest 6554 { 6555 import std.datetime.date; 6556 6557 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6558 6559 assert(!negInfInterval.isBefore(Date(2009, 7, 4))); 6560 assert(!negInfInterval.isBefore(Date(2010, 7, 3))); 6561 assert(!negInfInterval.isBefore(Date(2010, 7, 4))); 6562 assert(!negInfInterval.isBefore(Date(2010, 7, 5))); 6563 assert(!negInfInterval.isBefore(Date(2011, 7, 1))); 6564 assert(!negInfInterval.isBefore(Date(2012, 1, 6))); 6565 assert(negInfInterval.isBefore(Date(2012, 1, 7))); 6566 assert(negInfInterval.isBefore(Date(2012, 1, 8))); 6567 assert(negInfInterval.isBefore(Date(2013, 1, 7))); 6568 6569 const cdate = Date(2010, 7, 6); 6570 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6571 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6572 assert(!negInfInterval.isBefore(cdate)); 6573 assert(!cNegInfInterval.isBefore(cdate)); 6574 assert(!iNegInfInterval.isBefore(cdate)); 6575 6576 //Verify Examples. 6577 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(1994, 12, 24))); 6578 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2000, 1, 5))); 6579 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2012, 3, 1))); 6580 } 6581 6582 //Test NegInfInterval's isBefore(Interval). 6583 @safe unittest 6584 { 6585 import std.datetime.date; 6586 6587 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6588 6589 static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval) 6590 { 6591 negInfInterval.isBefore(interval); 6592 } 6593 6594 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 6595 6596 assert(!negInfInterval.isBefore(negInfInterval)); 6597 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 6598 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 6599 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 6600 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 6601 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 6602 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 6603 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 6604 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 6605 assert(!negInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 6606 assert(!negInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 6607 assert(negInfInterval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 6608 assert(negInfInterval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 6609 6610 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 3)))); 6611 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 4)))); 6612 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 5)))); 6613 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 6)))); 6614 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 7)))); 6615 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 8)))); 6616 6617 assert(!NegInfInterval!Date(Date(2010, 7, 3)).isBefore(negInfInterval)); 6618 assert(!NegInfInterval!Date(Date(2010, 7, 4)).isBefore(negInfInterval)); 6619 assert(!NegInfInterval!Date(Date(2010, 7, 5)).isBefore(negInfInterval)); 6620 assert(!NegInfInterval!Date(Date(2012, 1, 6)).isBefore(negInfInterval)); 6621 assert(!NegInfInterval!Date(Date(2012, 1, 7)).isBefore(negInfInterval)); 6622 assert(!NegInfInterval!Date(Date(2012, 1, 8)).isBefore(negInfInterval)); 6623 6624 assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 3)))); 6625 assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 4)))); 6626 assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 5)))); 6627 assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 6)))); 6628 assert(negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 7)))); 6629 assert(negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 8)))); 6630 6631 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6632 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6633 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6634 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6635 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6636 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6637 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6638 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6639 assert(!negInfInterval.isBefore(interval)); 6640 assert(!negInfInterval.isBefore(cInterval)); 6641 assert(!negInfInterval.isBefore(iInterval)); 6642 assert(!negInfInterval.isBefore(posInfInterval)); 6643 assert(!negInfInterval.isBefore(cPosInfInterval)); 6644 assert(!negInfInterval.isBefore(iPosInfInterval)); 6645 assert(!negInfInterval.isBefore(negInfInterval)); 6646 assert(!negInfInterval.isBefore(cNegInfInterval)); 6647 assert(!negInfInterval.isBefore(iNegInfInterval)); 6648 assert(!cNegInfInterval.isBefore(interval)); 6649 assert(!cNegInfInterval.isBefore(cInterval)); 6650 assert(!cNegInfInterval.isBefore(iInterval)); 6651 assert(!cNegInfInterval.isBefore(posInfInterval)); 6652 assert(!cNegInfInterval.isBefore(cPosInfInterval)); 6653 assert(!cNegInfInterval.isBefore(iPosInfInterval)); 6654 assert(!cNegInfInterval.isBefore(negInfInterval)); 6655 assert(!cNegInfInterval.isBefore(cNegInfInterval)); 6656 assert(!cNegInfInterval.isBefore(iNegInfInterval)); 6657 assert(!iNegInfInterval.isBefore(interval)); 6658 assert(!iNegInfInterval.isBefore(cInterval)); 6659 assert(!iNegInfInterval.isBefore(iInterval)); 6660 assert(!iNegInfInterval.isBefore(posInfInterval)); 6661 assert(!iNegInfInterval.isBefore(cPosInfInterval)); 6662 assert(!iNegInfInterval.isBefore(iPosInfInterval)); 6663 assert(!iNegInfInterval.isBefore(negInfInterval)); 6664 assert(!iNegInfInterval.isBefore(cNegInfInterval)); 6665 assert(!iNegInfInterval.isBefore(iNegInfInterval)); 6666 6667 //Verify Examples. 6668 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 6669 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 6670 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 6671 6672 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4)))); 6673 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2012, 3, 1)))); 6674 6675 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4)))); 6676 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(2013, 7, 9)))); 6677 } 6678 6679 //Test NegInfInterval's isAfter(time point). 6680 @safe unittest 6681 { 6682 import std.datetime.date; 6683 6684 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6685 6686 assert(!negInfInterval.isAfter(Date(2009, 7, 4))); 6687 assert(!negInfInterval.isAfter(Date(2010, 7, 3))); 6688 assert(!negInfInterval.isAfter(Date(2010, 7, 4))); 6689 assert(!negInfInterval.isAfter(Date(2010, 7, 5))); 6690 assert(!negInfInterval.isAfter(Date(2011, 7, 1))); 6691 assert(!negInfInterval.isAfter(Date(2012, 1, 6))); 6692 assert(!negInfInterval.isAfter(Date(2012, 1, 7))); 6693 assert(!negInfInterval.isAfter(Date(2012, 1, 8))); 6694 assert(!negInfInterval.isAfter(Date(2013, 1, 7))); 6695 6696 const cdate = Date(2010, 7, 6); 6697 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6698 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6699 assert(!negInfInterval.isAfter(cdate)); 6700 assert(!cNegInfInterval.isAfter(cdate)); 6701 assert(!iNegInfInterval.isAfter(cdate)); 6702 } 6703 6704 //Test NegInfInterval's isAfter(Interval). 6705 @safe unittest 6706 { 6707 import std.datetime.date; 6708 6709 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6710 6711 static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval) 6712 { 6713 negInfInterval.isAfter(interval); 6714 } 6715 6716 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 6717 6718 assert(!negInfInterval.isAfter(negInfInterval)); 6719 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 6720 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 6721 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 6722 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 6723 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 6724 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 6725 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 6726 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 6727 assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 6728 assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 6729 assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 6730 assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 6731 6732 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 3)))); 6733 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 4)))); 6734 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 5)))); 6735 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 6)))); 6736 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 7)))); 6737 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 8)))); 6738 6739 assert(!NegInfInterval!Date(Date(2010, 7, 3)).isAfter(negInfInterval)); 6740 assert(!NegInfInterval!Date(Date(2010, 7, 4)).isAfter(negInfInterval)); 6741 assert(!NegInfInterval!Date(Date(2010, 7, 5)).isAfter(negInfInterval)); 6742 assert(!NegInfInterval!Date(Date(2012, 1, 6)).isAfter(negInfInterval)); 6743 assert(!NegInfInterval!Date(Date(2012, 1, 7)).isAfter(negInfInterval)); 6744 assert(!NegInfInterval!Date(Date(2012, 1, 8)).isAfter(negInfInterval)); 6745 6746 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 3)))); 6747 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 4)))); 6748 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 5)))); 6749 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 6)))); 6750 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 7)))); 6751 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 8)))); 6752 6753 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6754 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6755 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6756 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6757 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6758 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6759 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6760 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6761 assert(!negInfInterval.isAfter(interval)); 6762 assert(!negInfInterval.isAfter(cInterval)); 6763 assert(!negInfInterval.isAfter(iInterval)); 6764 assert(!negInfInterval.isAfter(posInfInterval)); 6765 assert(!negInfInterval.isAfter(cPosInfInterval)); 6766 assert(!negInfInterval.isAfter(iPosInfInterval)); 6767 assert(!negInfInterval.isAfter(negInfInterval)); 6768 assert(!negInfInterval.isAfter(cNegInfInterval)); 6769 assert(!negInfInterval.isAfter(iNegInfInterval)); 6770 assert(!cNegInfInterval.isAfter(interval)); 6771 assert(!cNegInfInterval.isAfter(cInterval)); 6772 assert(!cNegInfInterval.isAfter(iInterval)); 6773 assert(!cNegInfInterval.isAfter(posInfInterval)); 6774 assert(!cNegInfInterval.isAfter(cPosInfInterval)); 6775 assert(!cNegInfInterval.isAfter(iPosInfInterval)); 6776 assert(!cNegInfInterval.isAfter(negInfInterval)); 6777 assert(!cNegInfInterval.isAfter(cNegInfInterval)); 6778 assert(!cNegInfInterval.isAfter(iNegInfInterval)); 6779 assert(!iNegInfInterval.isAfter(interval)); 6780 assert(!iNegInfInterval.isAfter(cInterval)); 6781 assert(!iNegInfInterval.isAfter(iInterval)); 6782 assert(!iNegInfInterval.isAfter(posInfInterval)); 6783 assert(!iNegInfInterval.isAfter(cPosInfInterval)); 6784 assert(!iNegInfInterval.isAfter(iPosInfInterval)); 6785 assert(!iNegInfInterval.isAfter(negInfInterval)); 6786 assert(!iNegInfInterval.isAfter(cNegInfInterval)); 6787 assert(!iNegInfInterval.isAfter(iNegInfInterval)); 6788 6789 //Verify Examples. 6790 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(1994, 12, 24))); 6791 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2000, 1, 5))); 6792 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2012, 3, 1))); 6793 6794 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 6795 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 6796 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 6797 6798 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4)))); 6799 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(2012, 3, 1)))); 6800 6801 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 5, 4)))); 6802 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(2013, 7, 9)))); 6803 } 6804 6805 //Test NegInfInterval's intersects(). 6806 @safe unittest 6807 { 6808 import std.datetime.date; 6809 6810 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6811 6812 static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval) 6813 { 6814 negInfInterval.intersects(interval); 6815 } 6816 6817 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 6818 6819 assert(negInfInterval.intersects(negInfInterval)); 6820 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 6821 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 6822 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 6823 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 6824 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 6825 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 6826 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 6827 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 6828 assert(negInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 6829 assert(negInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 6830 assert(!negInfInterval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 6831 assert(!negInfInterval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 6832 6833 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 3)))); 6834 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 4)))); 6835 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 5)))); 6836 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 6)))); 6837 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 7)))); 6838 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 8)))); 6839 6840 assert(NegInfInterval!Date(Date(2010, 7, 3)).intersects(negInfInterval)); 6841 assert(NegInfInterval!Date(Date(2010, 7, 4)).intersects(negInfInterval)); 6842 assert(NegInfInterval!Date(Date(2010, 7, 5)).intersects(negInfInterval)); 6843 assert(NegInfInterval!Date(Date(2012, 1, 6)).intersects(negInfInterval)); 6844 assert(NegInfInterval!Date(Date(2012, 1, 7)).intersects(negInfInterval)); 6845 assert(NegInfInterval!Date(Date(2012, 1, 8)).intersects(negInfInterval)); 6846 6847 assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 3)))); 6848 assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 4)))); 6849 assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 5)))); 6850 assert(negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 6)))); 6851 assert(!negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 7)))); 6852 assert(!negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 8)))); 6853 6854 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6855 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6856 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6857 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6858 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6859 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6860 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6861 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6862 assert(negInfInterval.intersects(interval)); 6863 assert(negInfInterval.intersects(cInterval)); 6864 assert(negInfInterval.intersects(iInterval)); 6865 assert(negInfInterval.intersects(posInfInterval)); 6866 assert(negInfInterval.intersects(cPosInfInterval)); 6867 assert(negInfInterval.intersects(iPosInfInterval)); 6868 assert(negInfInterval.intersects(negInfInterval)); 6869 assert(negInfInterval.intersects(cNegInfInterval)); 6870 assert(negInfInterval.intersects(iNegInfInterval)); 6871 assert(cNegInfInterval.intersects(interval)); 6872 assert(cNegInfInterval.intersects(cInterval)); 6873 assert(cNegInfInterval.intersects(iInterval)); 6874 assert(cNegInfInterval.intersects(posInfInterval)); 6875 assert(cNegInfInterval.intersects(cPosInfInterval)); 6876 assert(cNegInfInterval.intersects(iPosInfInterval)); 6877 assert(cNegInfInterval.intersects(negInfInterval)); 6878 assert(cNegInfInterval.intersects(cNegInfInterval)); 6879 assert(cNegInfInterval.intersects(iNegInfInterval)); 6880 assert(iNegInfInterval.intersects(interval)); 6881 assert(iNegInfInterval.intersects(cInterval)); 6882 assert(iNegInfInterval.intersects(iInterval)); 6883 assert(iNegInfInterval.intersects(posInfInterval)); 6884 assert(iNegInfInterval.intersects(cPosInfInterval)); 6885 assert(iNegInfInterval.intersects(iPosInfInterval)); 6886 assert(iNegInfInterval.intersects(negInfInterval)); 6887 assert(iNegInfInterval.intersects(cNegInfInterval)); 6888 assert(iNegInfInterval.intersects(iNegInfInterval)); 6889 6890 //Verify Examples. 6891 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 6892 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 6893 assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 6894 6895 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4)))); 6896 assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1)))); 6897 6898 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 5, 4)))); 6899 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2013, 7, 9)))); 6900 } 6901 6902 //Test NegInfInterval's intersection(). 6903 @safe unittest 6904 { 6905 import std.datetime.date; 6906 6907 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6908 6909 static void testInterval(I, J)(in I interval1, in J interval2) 6910 { 6911 interval1.intersection(interval2); 6912 } 6913 6914 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 6915 6916 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 6917 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 6918 6919 assertThrown!DateTimeException(testInterval(negInfInterval, PosInfInterval!Date(Date(2012, 1, 7)))); 6920 assertThrown!DateTimeException(testInterval(negInfInterval, PosInfInterval!Date(Date(2012, 1, 8)))); 6921 6922 assert(negInfInterval.intersection(negInfInterval) == negInfInterval); 6923 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == 6924 Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))); 6925 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 6926 Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); 6927 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 6928 Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))); 6929 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 6930 Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))); 6931 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 6932 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 6933 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 6934 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 6935 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 6936 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); 6937 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 6938 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); 6939 assert(negInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 6940 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 6941 assert(negInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 6942 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 6943 6944 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2010, 7, 3))); 6945 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2010, 7, 4))); 6946 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2010, 7, 5))); 6947 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 6))); 6948 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7))); 6949 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 7))); 6950 6951 assert(NegInfInterval!Date(Date(2010, 7, 3)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 3))); 6952 assert(NegInfInterval!Date(Date(2010, 7, 4)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 4))); 6953 assert(NegInfInterval!Date(Date(2010, 7, 5)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 5))); 6954 assert(NegInfInterval!Date(Date(2012, 1, 6)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 6))); 6955 assert(NegInfInterval!Date(Date(2012, 1, 7)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 6956 assert(NegInfInterval!Date(Date(2012, 1, 8)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 6957 6958 assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == 6959 Interval!Date(Date(2010, 7, 3), Date(2012, 1 ,7))); 6960 assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == 6961 Interval!Date(Date(2010, 7, 4), Date(2012, 1 ,7))); 6962 assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == 6963 Interval!Date(Date(2010, 7, 5), Date(2012, 1 ,7))); 6964 assert(negInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == 6965 Interval!Date(Date(2012, 1, 6), Date(2012, 1 ,7))); 6966 6967 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6968 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6969 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6970 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6971 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6972 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6973 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6974 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6975 assert(!negInfInterval.intersection(interval).empty); 6976 assert(!negInfInterval.intersection(cInterval).empty); 6977 assert(!negInfInterval.intersection(iInterval).empty); 6978 assert(!negInfInterval.intersection(posInfInterval).empty); 6979 assert(!negInfInterval.intersection(cPosInfInterval).empty); 6980 assert(!negInfInterval.intersection(iPosInfInterval).empty); 6981 assert(!negInfInterval.intersection(negInfInterval).empty); 6982 assert(!negInfInterval.intersection(cNegInfInterval).empty); 6983 assert(!negInfInterval.intersection(iNegInfInterval).empty); 6984 assert(!cNegInfInterval.intersection(interval).empty); 6985 assert(!cNegInfInterval.intersection(cInterval).empty); 6986 assert(!cNegInfInterval.intersection(iInterval).empty); 6987 assert(!cNegInfInterval.intersection(posInfInterval).empty); 6988 assert(!cNegInfInterval.intersection(cPosInfInterval).empty); 6989 assert(!cNegInfInterval.intersection(iPosInfInterval).empty); 6990 assert(!cNegInfInterval.intersection(negInfInterval).empty); 6991 assert(!cNegInfInterval.intersection(cNegInfInterval).empty); 6992 assert(!cNegInfInterval.intersection(iNegInfInterval).empty); 6993 assert(!iNegInfInterval.intersection(interval).empty); 6994 assert(!iNegInfInterval.intersection(cInterval).empty); 6995 assert(!iNegInfInterval.intersection(iInterval).empty); 6996 assert(!iNegInfInterval.intersection(posInfInterval).empty); 6997 assert(!iNegInfInterval.intersection(cPosInfInterval).empty); 6998 assert(!iNegInfInterval.intersection(iPosInfInterval).empty); 6999 assert(!iNegInfInterval.intersection(negInfInterval).empty); 7000 assert(!iNegInfInterval.intersection(cNegInfInterval).empty); 7001 assert(!iNegInfInterval.intersection(iNegInfInterval).empty); 7002 7003 //Verify Examples. 7004 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 7005 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))); 7006 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == 7007 Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1))); 7008 7009 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) == 7010 Interval!Date(Date(1990, 7, 6), Date(2012, 3, 1))); 7011 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) == 7012 Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1))); 7013 7014 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) == 7015 NegInfInterval!Date(Date(1999, 7, 6))); 7016 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) == 7017 NegInfInterval!Date(Date(2012, 3, 1))); 7018 } 7019 7020 //Test NegInfInterval's isAdjacent(). 7021 @safe unittest 7022 { 7023 import std.datetime.date; 7024 7025 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7026 7027 static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval) 7028 { 7029 negInfInterval.isAdjacent(interval); 7030 } 7031 7032 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 7033 7034 assert(!negInfInterval.isAdjacent(negInfInterval)); 7035 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 7036 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 7037 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 7038 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 7039 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 7040 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 7041 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 7042 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 7043 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 7044 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 7045 assert(negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 7046 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 7047 7048 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3)))); 7049 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4)))); 7050 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5)))); 7051 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6)))); 7052 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7)))); 7053 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8)))); 7054 7055 assert(!NegInfInterval!Date(Date(2010, 7, 3)).isAdjacent(negInfInterval)); 7056 assert(!NegInfInterval!Date(Date(2010, 7, 4)).isAdjacent(negInfInterval)); 7057 assert(!NegInfInterval!Date(Date(2010, 7, 5)).isAdjacent(negInfInterval)); 7058 assert(!NegInfInterval!Date(Date(2012, 1, 6)).isAdjacent(negInfInterval)); 7059 assert(!NegInfInterval!Date(Date(2012, 1, 7)).isAdjacent(negInfInterval)); 7060 assert(!NegInfInterval!Date(Date(2012, 1, 8)).isAdjacent(negInfInterval)); 7061 7062 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3)))); 7063 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4)))); 7064 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5)))); 7065 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6)))); 7066 assert(negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7)))); 7067 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8)))); 7068 7069 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7070 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7071 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7072 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7073 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7074 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7075 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7076 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7077 assert(!negInfInterval.isAdjacent(interval)); 7078 assert(!negInfInterval.isAdjacent(cInterval)); 7079 assert(!negInfInterval.isAdjacent(iInterval)); 7080 assert(!negInfInterval.isAdjacent(posInfInterval)); 7081 assert(!negInfInterval.isAdjacent(cPosInfInterval)); 7082 assert(!negInfInterval.isAdjacent(iPosInfInterval)); 7083 assert(!negInfInterval.isAdjacent(negInfInterval)); 7084 assert(!negInfInterval.isAdjacent(cNegInfInterval)); 7085 assert(!negInfInterval.isAdjacent(iNegInfInterval)); 7086 assert(!cNegInfInterval.isAdjacent(interval)); 7087 assert(!cNegInfInterval.isAdjacent(cInterval)); 7088 assert(!cNegInfInterval.isAdjacent(iInterval)); 7089 assert(!cNegInfInterval.isAdjacent(posInfInterval)); 7090 assert(!cNegInfInterval.isAdjacent(cPosInfInterval)); 7091 assert(!cNegInfInterval.isAdjacent(iPosInfInterval)); 7092 assert(!cNegInfInterval.isAdjacent(negInfInterval)); 7093 assert(!cNegInfInterval.isAdjacent(cNegInfInterval)); 7094 assert(!cNegInfInterval.isAdjacent(iNegInfInterval)); 7095 assert(!iNegInfInterval.isAdjacent(interval)); 7096 assert(!iNegInfInterval.isAdjacent(cInterval)); 7097 assert(!iNegInfInterval.isAdjacent(iInterval)); 7098 assert(!iNegInfInterval.isAdjacent(posInfInterval)); 7099 assert(!iNegInfInterval.isAdjacent(cPosInfInterval)); 7100 assert(!iNegInfInterval.isAdjacent(iPosInfInterval)); 7101 assert(!iNegInfInterval.isAdjacent(negInfInterval)); 7102 assert(!iNegInfInterval.isAdjacent(cNegInfInterval)); 7103 assert(!iNegInfInterval.isAdjacent(iNegInfInterval)); 7104 7105 //Verify Examples. 7106 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 7107 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1)))); 7108 assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2012, 3, 1), Date(2019, 2, 2)))); 7109 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 7110 7111 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4)))); 7112 assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1)))); 7113 7114 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 5, 4)))); 7115 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(2012, 3, 1)))); 7116 } 7117 7118 //Test NegInfInterval's merge(). 7119 @safe unittest 7120 { 7121 import std.datetime.date; 7122 7123 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7124 7125 static void testInterval(I, J)(in I interval1, in J interval2) 7126 { 7127 interval1.merge(interval2); 7128 } 7129 7130 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 7131 7132 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 7133 7134 assert(negInfInterval.merge(negInfInterval) == negInfInterval); 7135 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == 7136 NegInfInterval!Date(Date(2012, 1, 7))); 7137 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 7138 NegInfInterval!Date(Date(2013, 7, 3))); 7139 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 7140 NegInfInterval!Date(Date(2012, 1, 7))); 7141 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 7142 NegInfInterval!Date(Date(2012, 1, 7))); 7143 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 7144 NegInfInterval!Date(Date(2012, 1, 7))); 7145 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 7146 NegInfInterval!Date(Date(2012, 1, 8))); 7147 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 7148 NegInfInterval!Date(Date(2012, 1, 7))); 7149 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 7150 NegInfInterval!Date(Date(2012, 1, 7))); 7151 assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 7152 NegInfInterval!Date(Date(2012, 1, 7))); 7153 assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 7154 NegInfInterval!Date(Date(2012, 1, 8))); 7155 assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 7156 NegInfInterval!Date(Date(2012, 1, 8))); 7157 7158 assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7))); 7159 assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7))); 7160 assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7))); 7161 assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7))); 7162 assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7))); 7163 assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8))); 7164 7165 assert(NegInfInterval!Date(Date(2010, 7, 3)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7166 assert(NegInfInterval!Date(Date(2010, 7, 4)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7167 assert(NegInfInterval!Date(Date(2010, 7, 5)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7168 assert(NegInfInterval!Date(Date(2012, 1, 6)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7169 assert(NegInfInterval!Date(Date(2012, 1, 7)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7170 assert(NegInfInterval!Date(Date(2012, 1, 8)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 8))); 7171 7172 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 3))))); 7173 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 4))))); 7174 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 5))))); 7175 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 6))))); 7176 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 7))))); 7177 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 8))))); 7178 7179 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7180 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7181 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7182 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7183 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7184 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7185 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7186 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7187 assert(!negInfInterval.merge(interval).empty); 7188 assert(!negInfInterval.merge(cInterval).empty); 7189 assert(!negInfInterval.merge(iInterval).empty); 7190 static assert(!__traits(compiles, negInfInterval.merge(posInfInterval))); 7191 static assert(!__traits(compiles, negInfInterval.merge(cPosInfInterval))); 7192 static assert(!__traits(compiles, negInfInterval.merge(iPosInfInterval))); 7193 assert(!negInfInterval.merge(negInfInterval).empty); 7194 assert(!negInfInterval.merge(cNegInfInterval).empty); 7195 assert(!negInfInterval.merge(iNegInfInterval).empty); 7196 assert(!cNegInfInterval.merge(interval).empty); 7197 assert(!cNegInfInterval.merge(cInterval).empty); 7198 assert(!cNegInfInterval.merge(iInterval).empty); 7199 static assert(!__traits(compiles, cNegInfInterval.merge(posInfInterval))); 7200 static assert(!__traits(compiles, cNegInfInterval.merge(cPosInfInterval))); 7201 static assert(!__traits(compiles, cNegInfInterval.merge(iPosInfInterval))); 7202 assert(!cNegInfInterval.merge(negInfInterval).empty); 7203 assert(!cNegInfInterval.merge(cNegInfInterval).empty); 7204 assert(!cNegInfInterval.merge(iNegInfInterval).empty); 7205 assert(!iNegInfInterval.merge(interval).empty); 7206 assert(!iNegInfInterval.merge(cInterval).empty); 7207 assert(!iNegInfInterval.merge(iInterval).empty); 7208 static assert(!__traits(compiles, iNegInfInterval.merge(posInfInterval))); 7209 static assert(!__traits(compiles, iNegInfInterval.merge(cPosInfInterval))); 7210 static assert(!__traits(compiles, iNegInfInterval.merge(iPosInfInterval))); 7211 assert(!iNegInfInterval.merge(negInfInterval).empty); 7212 assert(!iNegInfInterval.merge(cNegInfInterval).empty); 7213 assert(!iNegInfInterval.merge(iNegInfInterval).empty); 7214 7215 //Verify Examples. 7216 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 7217 NegInfInterval!Date(Date(2012, 3, 1))); 7218 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == 7219 NegInfInterval!Date(Date(2015, 9, 2))); 7220 7221 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1999, 7, 6))) == 7222 NegInfInterval!Date(Date(2012, 3, 1))); 7223 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) == 7224 NegInfInterval!Date(Date(2013, 1, 12))); 7225 } 7226 7227 //Test NegInfInterval's span(). 7228 @safe unittest 7229 { 7230 import std.datetime.date; 7231 7232 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7233 7234 static void testInterval(I, J)(in I interval1, in J interval2) 7235 { 7236 interval1.span(interval2); 7237 } 7238 7239 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 7240 7241 assert(negInfInterval.span(negInfInterval) == negInfInterval); 7242 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == 7243 NegInfInterval!Date(Date(2012, 1, 7))); 7244 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 7245 NegInfInterval!Date(Date(2013, 7, 3))); 7246 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 7247 NegInfInterval!Date(Date(2012, 1, 7))); 7248 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 7249 NegInfInterval!Date(Date(2012, 1, 7))); 7250 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 7251 NegInfInterval!Date(Date(2012, 1, 7))); 7252 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 7253 NegInfInterval!Date(Date(2012, 1, 8))); 7254 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 7255 NegInfInterval!Date(Date(2012, 1, 7))); 7256 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 7257 NegInfInterval!Date(Date(2012, 1, 7))); 7258 assert(negInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 7259 NegInfInterval!Date(Date(2012, 1, 7))); 7260 assert(negInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 7261 NegInfInterval!Date(Date(2012, 1, 8))); 7262 assert(negInfInterval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 7263 NegInfInterval!Date(Date(2012, 1, 8))); 7264 assert(negInfInterval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == 7265 NegInfInterval!Date(Date(2012, 1, 9))); 7266 7267 assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7))); 7268 assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7))); 7269 assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7))); 7270 assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7))); 7271 assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7))); 7272 assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8))); 7273 7274 assert(NegInfInterval!Date(Date(2010, 7, 3)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7275 assert(NegInfInterval!Date(Date(2010, 7, 4)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7276 assert(NegInfInterval!Date(Date(2010, 7, 5)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7277 assert(NegInfInterval!Date(Date(2012, 1, 6)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7278 assert(NegInfInterval!Date(Date(2012, 1, 7)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7279 assert(NegInfInterval!Date(Date(2012, 1, 8)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 8))); 7280 7281 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 3))))); 7282 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 4))))); 7283 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 5))))); 7284 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 6))))); 7285 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 7))))); 7286 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 8))))); 7287 7288 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7289 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7290 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7291 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7292 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7293 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7294 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7295 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7296 assert(!negInfInterval.span(interval).empty); 7297 assert(!negInfInterval.span(cInterval).empty); 7298 assert(!negInfInterval.span(iInterval).empty); 7299 static assert(!__traits(compiles, negInfInterval.span(posInfInterval))); 7300 static assert(!__traits(compiles, negInfInterval.span(cPosInfInterval))); 7301 static assert(!__traits(compiles, negInfInterval.span(iPosInfInterval))); 7302 assert(!negInfInterval.span(negInfInterval).empty); 7303 assert(!negInfInterval.span(cNegInfInterval).empty); 7304 assert(!negInfInterval.span(iNegInfInterval).empty); 7305 assert(!cNegInfInterval.span(interval).empty); 7306 assert(!cNegInfInterval.span(cInterval).empty); 7307 assert(!cNegInfInterval.span(iInterval).empty); 7308 static assert(!__traits(compiles, cNegInfInterval.span(posInfInterval))); 7309 static assert(!__traits(compiles, cNegInfInterval.span(cPosInfInterval))); 7310 static assert(!__traits(compiles, cNegInfInterval.span(iPosInfInterval))); 7311 assert(!cNegInfInterval.span(negInfInterval).empty); 7312 assert(!cNegInfInterval.span(cNegInfInterval).empty); 7313 assert(!cNegInfInterval.span(iNegInfInterval).empty); 7314 assert(!iNegInfInterval.span(interval).empty); 7315 assert(!iNegInfInterval.span(cInterval).empty); 7316 assert(!iNegInfInterval.span(iInterval).empty); 7317 static assert(!__traits(compiles, iNegInfInterval.span(posInfInterval))); 7318 static assert(!__traits(compiles, iNegInfInterval.span(cPosInfInterval))); 7319 static assert(!__traits(compiles, iNegInfInterval.span(iPosInfInterval))); 7320 assert(!iNegInfInterval.span(negInfInterval).empty); 7321 assert(!iNegInfInterval.span(cNegInfInterval).empty); 7322 assert(!iNegInfInterval.span(iNegInfInterval).empty); 7323 7324 //Verify Examples. 7325 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 7326 NegInfInterval!Date(Date(2012, 3, 1))); 7327 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == 7328 NegInfInterval!Date(Date(2015, 9, 2))); 7329 assert(NegInfInterval!Date(Date(1600, 1, 7)).span(Interval!Date(Date(2012, 3, 11), Date(2017, 7, 1))) == 7330 NegInfInterval!Date(Date(2017, 7, 1))); 7331 7332 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1999, 7, 6))) == 7333 NegInfInterval!Date(Date(2012, 3, 1))); 7334 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) == 7335 NegInfInterval!Date(Date(2013, 1, 12))); 7336 } 7337 7338 //Test NegInfInterval's shift(). 7339 @safe unittest 7340 { 7341 import std.datetime.date; 7342 7343 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 7344 7345 static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__) 7346 { 7347 interval.shift(duration); 7348 assert(interval == expected); 7349 } 7350 7351 testInterval(interval, dur!"days"(22), NegInfInterval!Date(Date(2012, 1, 29))); 7352 testInterval(interval, dur!"days"(-22), NegInfInterval!Date(Date(2011, 12, 16))); 7353 7354 const cInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7355 immutable iInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7356 static assert(!__traits(compiles, cInterval.shift(dur!"days"(5)))); 7357 static assert(!__traits(compiles, iInterval.shift(dur!"days"(5)))); 7358 7359 //Verify Examples. 7360 auto interval1 = NegInfInterval!Date(Date(2012, 4, 5)); 7361 auto interval2 = NegInfInterval!Date(Date(2012, 4, 5)); 7362 7363 interval1.shift(dur!"days"(50)); 7364 assert(interval1 == NegInfInterval!Date(Date(2012, 5, 25))); 7365 7366 interval2.shift(dur!"days"(-50)); 7367 assert(interval2 == NegInfInterval!Date( Date(2012, 2, 15))); 7368 } 7369 7370 //Test NegInfInterval's shift(int, int, AllowDayOverflow). 7371 @safe unittest 7372 { 7373 import std.datetime.date; 7374 7375 { 7376 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 7377 7378 static void testIntervalFail(I)(I interval, int years, int months) 7379 { 7380 interval.shift(years, months); 7381 } 7382 7383 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, 7384 in I expected, size_t line = __LINE__) 7385 { 7386 interval.shift(years, months, allow); 7387 assert(interval == expected); 7388 } 7389 7390 testInterval(interval, 5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2017, 1, 7))); 7391 testInterval(interval, -5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2007, 1, 7))); 7392 7393 auto interval2 = NegInfInterval!Date(Date(2010, 5, 31)); 7394 7395 testInterval(interval2, 1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 7, 1))); 7396 testInterval(interval2, 1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 5, 1))); 7397 testInterval(interval2, -1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 5, 1))); 7398 testInterval(interval2, -1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 7, 1))); 7399 7400 testInterval(interval2, 1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 6, 30))); 7401 testInterval(interval2, 1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 4, 30))); 7402 testInterval(interval2, -1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 4, 30))); 7403 testInterval(interval2, -1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 6, 30))); 7404 } 7405 7406 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7407 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7408 static assert(!__traits(compiles, cNegInfInterval.shift(1))); 7409 static assert(!__traits(compiles, iNegInfInterval.shift(1))); 7410 7411 //Verify Examples. 7412 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); 7413 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); 7414 7415 interval1.shift(2); 7416 assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1))); 7417 7418 interval2.shift(-2); 7419 assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1))); 7420 } 7421 7422 //Test NegInfInterval's expand(). 7423 @safe unittest 7424 { 7425 import std.datetime.date; 7426 7427 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 7428 7429 static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__) 7430 { 7431 interval.expand(duration); 7432 assert(interval == expected); 7433 } 7434 7435 testInterval(interval, dur!"days"(22), NegInfInterval!Date(Date(2012, 1, 29))); 7436 testInterval(interval, dur!"days"(-22), NegInfInterval!Date(Date(2011, 12, 16))); 7437 7438 const cInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7439 immutable iInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7440 static assert(!__traits(compiles, cInterval.expand(dur!"days"(5)))); 7441 static assert(!__traits(compiles, iInterval.expand(dur!"days"(5)))); 7442 7443 //Verify Examples. 7444 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); 7445 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); 7446 7447 interval1.expand(dur!"days"(2)); 7448 assert(interval1 == NegInfInterval!Date(Date(2012, 3, 3))); 7449 7450 interval2.expand(dur!"days"(-2)); 7451 assert(interval2 == NegInfInterval!Date(Date(2012, 2, 28))); 7452 } 7453 7454 //Test NegInfInterval's expand(int, int, AllowDayOverflow). 7455 @safe unittest 7456 { 7457 import std.datetime.date; 7458 7459 { 7460 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 7461 7462 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, 7463 in I expected, size_t line = __LINE__) 7464 { 7465 interval.expand(years, months, allow); 7466 assert(interval == expected); 7467 } 7468 7469 testInterval(interval, 5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2017, 1, 7))); 7470 testInterval(interval, -5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2007, 1, 7))); 7471 7472 auto interval2 = NegInfInterval!Date(Date(2010, 5, 31)); 7473 7474 testInterval(interval2, 1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 7, 1))); 7475 testInterval(interval2, 1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 5, 1))); 7476 testInterval(interval2, -1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 5, 1))); 7477 testInterval(interval2, -1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 7, 1))); 7478 7479 testInterval(interval2, 1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 6, 30))); 7480 testInterval(interval2, 1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 4, 30))); 7481 testInterval(interval2, -1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 4, 30))); 7482 testInterval(interval2, -1, 1, AllowDayOverflow.no, NegInfInterval!Date( Date(2009, 6, 30))); 7483 } 7484 7485 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7486 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7487 static assert(!__traits(compiles, cNegInfInterval.expand(1))); 7488 static assert(!__traits(compiles, iNegInfInterval.expand(1))); 7489 7490 //Verify Examples. 7491 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); 7492 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); 7493 7494 interval1.expand(2); 7495 assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1))); 7496 7497 interval2.expand(-2); 7498 assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1))); 7499 } 7500 7501 //Test NegInfInterval's bwdRange(). 7502 @system unittest 7503 { 7504 import std.datetime.date; 7505 7506 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7507 7508 static void testInterval(NegInfInterval!Date negInfInterval) 7509 { 7510 negInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront(); 7511 } 7512 7513 assertThrown!DateTimeException(testInterval(negInfInterval)); 7514 7515 assert(NegInfInterval!Date(Date(2010, 10, 1)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front == 7516 Date(2010, 10, 1)); 7517 7518 assert(NegInfInterval!Date(Date(2010, 10, 1)).bwdRange( 7519 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 24)); 7520 7521 //Verify Examples. 7522 auto interval = NegInfInterval!Date(Date(2010, 9, 9)); 7523 auto func = delegate (in Date date) 7524 { 7525 if ((date.day & 1) == 0) 7526 return date - dur!"days"(2); 7527 return date - dur!"days"(1); 7528 }; 7529 auto range = interval.bwdRange(func); 7530 7531 //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). 7532 assert(range.front == Date(2010, 9, 9)); 7533 7534 range.popFront(); 7535 assert(range.front == Date(2010, 9, 8)); 7536 7537 range.popFront(); 7538 assert(range.front == Date(2010, 9, 6)); 7539 7540 range.popFront(); 7541 assert(range.front == Date(2010, 9, 4)); 7542 7543 range.popFront(); 7544 assert(range.front == Date(2010, 9, 2)); 7545 7546 range.popFront(); 7547 assert(!range.empty); 7548 7549 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7550 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7551 assert(!cNegInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty); 7552 assert(!iNegInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty); 7553 } 7554 7555 //Test NegInfInterval's toString(). 7556 @safe unittest 7557 { 7558 import std.datetime.date; 7559 7560 assert(NegInfInterval!Date(Date(2012, 1, 7)).toString() == "[-∞ - 2012-Jan-07)"); 7561 7562 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7563 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7564 assert(cNegInfInterval.toString()); 7565 assert(iNegInfInterval.toString()); 7566 } 7567 7568 7569 /++ 7570 Range-generating function. 7571 7572 Returns a delegate which returns the next time point with the given 7573 $(D DayOfWeek) in a range. 7574 7575 Using this delegate allows iteration over successive time points which 7576 are all the same day of the week. e.g. passing $(D DayOfWeek.mon) to 7577 $(D everyDayOfWeek) would result in a delegate which could be used to 7578 iterate over all of the Mondays in a range. 7579 7580 Params: 7581 dir = The direction to iterate in. If passing the return value to 7582 $(D fwdRange), use $(D Direction.fwd). If passing it to 7583 $(D bwdRange), use $(D Direction.bwd). 7584 dayOfWeek = The week that each time point in the range will be. 7585 +/ 7586 TP delegate(in TP) everyDayOfWeek(TP, Direction dir = Direction.fwd)(DayOfWeek dayOfWeek) nothrow 7587 if (isTimePoint!TP && 7588 (dir == Direction.fwd || dir == Direction.bwd) && 7589 __traits(hasMember, TP, "dayOfWeek") && 7590 !__traits(isStaticFunction, TP.dayOfWeek) && 7591 is(typeof(TP.dayOfWeek) == DayOfWeek)) 7592 { 7593 TP func(in TP tp) 7594 { 7595 TP retval = cast(TP) tp; 7596 immutable days = daysToDayOfWeek(retval.dayOfWeek, dayOfWeek); 7597 7598 static if (dir == Direction.fwd) 7599 immutable adjustedDays = days == 0 ? 7 : days; 7600 else 7601 immutable adjustedDays = days == 0 ? -7 : days - 7; 7602 7603 return retval += dur!"days"(adjustedDays); 7604 } 7605 7606 return &func; 7607 } 7608 7609 /// 7610 @system unittest 7611 { 7612 import std.datetime.date : Date, DayOfWeek; 7613 7614 auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27)); 7615 auto func = everyDayOfWeek!Date(DayOfWeek.mon); 7616 auto range = interval.fwdRange(func); 7617 7618 // A Thursday. Using PopFirst.yes would have made this Date(2010, 9, 6). 7619 assert(range.front == Date(2010, 9, 2)); 7620 7621 range.popFront(); 7622 assert(range.front == Date(2010, 9, 6)); 7623 7624 range.popFront(); 7625 assert(range.front == Date(2010, 9, 13)); 7626 7627 range.popFront(); 7628 assert(range.front == Date(2010, 9, 20)); 7629 7630 range.popFront(); 7631 assert(range.empty); 7632 } 7633 7634 @system unittest 7635 { 7636 import std.datetime.date; 7637 import std.datetime.systime; 7638 7639 auto funcFwd = everyDayOfWeek!Date(DayOfWeek.mon); 7640 auto funcBwd = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.mon); 7641 7642 assert(funcFwd(Date(2010, 8, 28)) == Date(2010, 8, 30)); 7643 assert(funcFwd(Date(2010, 8, 29)) == Date(2010, 8, 30)); 7644 assert(funcFwd(Date(2010, 8, 30)) == Date(2010, 9, 6)); 7645 assert(funcFwd(Date(2010, 8, 31)) == Date(2010, 9, 6)); 7646 assert(funcFwd(Date(2010, 9, 1)) == Date(2010, 9, 6)); 7647 assert(funcFwd(Date(2010, 9, 2)) == Date(2010, 9, 6)); 7648 assert(funcFwd(Date(2010, 9, 3)) == Date(2010, 9, 6)); 7649 assert(funcFwd(Date(2010, 9, 4)) == Date(2010, 9, 6)); 7650 assert(funcFwd(Date(2010, 9, 5)) == Date(2010, 9, 6)); 7651 assert(funcFwd(Date(2010, 9, 6)) == Date(2010, 9, 13)); 7652 assert(funcFwd(Date(2010, 9, 7)) == Date(2010, 9, 13)); 7653 7654 assert(funcBwd(Date(2010, 8, 28)) == Date(2010, 8, 23)); 7655 assert(funcBwd(Date(2010, 8, 29)) == Date(2010, 8, 23)); 7656 assert(funcBwd(Date(2010, 8, 30)) == Date(2010, 8, 23)); 7657 assert(funcBwd(Date(2010, 8, 31)) == Date(2010, 8, 30)); 7658 assert(funcBwd(Date(2010, 9, 1)) == Date(2010, 8, 30)); 7659 assert(funcBwd(Date(2010, 9, 2)) == Date(2010, 8, 30)); 7660 assert(funcBwd(Date(2010, 9, 3)) == Date(2010, 8, 30)); 7661 assert(funcBwd(Date(2010, 9, 4)) == Date(2010, 8, 30)); 7662 assert(funcBwd(Date(2010, 9, 5)) == Date(2010, 8, 30)); 7663 assert(funcBwd(Date(2010, 9, 6)) == Date(2010, 8, 30)); 7664 assert(funcBwd(Date(2010, 9, 7)) == Date(2010, 9, 6)); 7665 7666 static assert(!__traits(compiles, everyDayOfWeek!TimeOfDay(DayOfWeek.mon))); 7667 assert(everyDayOfWeek!DateTime(DayOfWeek.mon) !is null); 7668 assert(everyDayOfWeek!SysTime(DayOfWeek.mon) !is null); 7669 } 7670 7671 7672 /++ 7673 Range-generating function. 7674 7675 Returns a delegate which returns the next time point with the given month 7676 which would be reached by adding months to the given time point. 7677 7678 So, using this delegate allows iteration over successive time points 7679 which are in the same month but different years. For example, 7680 iterate over each successive December 25th in an interval by starting with a 7681 date which had the 25th as its day and passed $(D Month.dec) to 7682 $(D everyMonth) to create the delegate. 7683 7684 Since it wouldn't really make sense to be iterating over a specific month 7685 and end up with some of the time points in the succeeding month or two years 7686 after the previous time point, $(D AllowDayOverflow.no) is always used when 7687 calculating the next time point. 7688 7689 Params: 7690 dir = The direction to iterate in. If passing the return value to 7691 $(D fwdRange), use $(D Direction.fwd). If passing it to 7692 $(D bwdRange), use $(D Direction.bwd). 7693 month = The month that each time point in the range will be in 7694 (January is 1). 7695 +/ 7696 TP delegate(in TP) everyMonth(TP, Direction dir = Direction.fwd)(int month) 7697 if (isTimePoint!TP && 7698 (dir == Direction.fwd || dir == Direction.bwd) && 7699 __traits(hasMember, TP, "month") && 7700 !__traits(isStaticFunction, TP.month) && 7701 is(typeof(TP.month) == Month)) 7702 { 7703 import std.datetime.date : enforceValid, monthsToMonth; 7704 7705 enforceValid!"months"(month); 7706 7707 TP func(in TP tp) 7708 { 7709 TP retval = cast(TP) tp; 7710 immutable months = monthsToMonth(retval.month, month); 7711 7712 static if (dir == Direction.fwd) 7713 immutable adjustedMonths = months == 0 ? 12 : months; 7714 else 7715 immutable adjustedMonths = months == 0 ? -12 : months - 12; 7716 7717 retval.add!"months"(adjustedMonths, AllowDayOverflow.no); 7718 7719 if (retval.month != month) 7720 { 7721 retval.add!"months"(-1); 7722 assert(retval.month == month); 7723 } 7724 7725 return retval; 7726 } 7727 7728 return &func; 7729 } 7730 7731 /// 7732 @system unittest 7733 { 7734 import std.datetime.date : Date, Month; 7735 7736 auto interval = Interval!Date(Date(2000, 1, 30), Date(2004, 8, 5)); 7737 auto func = everyMonth!Date(Month.feb); 7738 auto range = interval.fwdRange(func); 7739 7740 // Using PopFirst.yes would have made this Date(2010, 2, 29). 7741 assert(range.front == Date(2000, 1, 30)); 7742 7743 range.popFront(); 7744 assert(range.front == Date(2000, 2, 29)); 7745 7746 range.popFront(); 7747 assert(range.front == Date(2001, 2, 28)); 7748 7749 range.popFront(); 7750 assert(range.front == Date(2002, 2, 28)); 7751 7752 range.popFront(); 7753 assert(range.front == Date(2003, 2, 28)); 7754 7755 range.popFront(); 7756 assert(range.front == Date(2004, 2, 28)); 7757 7758 range.popFront(); 7759 assert(range.empty); 7760 } 7761 7762 @system unittest 7763 { 7764 import std.datetime.date; 7765 import std.datetime.systime; 7766 7767 auto funcFwd = everyMonth!Date(Month.jun); 7768 auto funcBwd = everyMonth!(Date, Direction.bwd)(Month.jun); 7769 7770 assert(funcFwd(Date(2010, 5, 31)) == Date(2010, 6, 30)); 7771 assert(funcFwd(Date(2010, 6, 30)) == Date(2011, 6, 30)); 7772 assert(funcFwd(Date(2010, 7, 31)) == Date(2011, 6, 30)); 7773 assert(funcFwd(Date(2010, 8, 31)) == Date(2011, 6, 30)); 7774 assert(funcFwd(Date(2010, 9, 30)) == Date(2011, 6, 30)); 7775 assert(funcFwd(Date(2010, 10, 31)) == Date(2011, 6, 30)); 7776 assert(funcFwd(Date(2010, 11, 30)) == Date(2011, 6, 30)); 7777 assert(funcFwd(Date(2010, 12, 31)) == Date(2011, 6, 30)); 7778 assert(funcFwd(Date(2011, 1, 31)) == Date(2011, 6, 30)); 7779 assert(funcFwd(Date(2011, 2, 28)) == Date(2011, 6, 28)); 7780 assert(funcFwd(Date(2011, 3, 31)) == Date(2011, 6, 30)); 7781 assert(funcFwd(Date(2011, 4, 30)) == Date(2011, 6, 30)); 7782 assert(funcFwd(Date(2011, 5, 31)) == Date(2011, 6, 30)); 7783 assert(funcFwd(Date(2011, 6, 30)) == Date(2012, 6, 30)); 7784 assert(funcFwd(Date(2011, 7, 31)) == Date(2012, 6, 30)); 7785 7786 assert(funcBwd(Date(2010, 5, 31)) == Date(2009, 6, 30)); 7787 assert(funcBwd(Date(2010, 6, 30)) == Date(2009, 6, 30)); 7788 assert(funcBwd(Date(2010, 7, 31)) == Date(2010, 6, 30)); 7789 assert(funcBwd(Date(2010, 8, 31)) == Date(2010, 6, 30)); 7790 assert(funcBwd(Date(2010, 9, 30)) == Date(2010, 6, 30)); 7791 assert(funcBwd(Date(2010, 10, 31)) == Date(2010, 6, 30)); 7792 assert(funcBwd(Date(2010, 11, 30)) == Date(2010, 6, 30)); 7793 assert(funcBwd(Date(2010, 12, 31)) == Date(2010, 6, 30)); 7794 assert(funcBwd(Date(2011, 1, 31)) == Date(2010, 6, 30)); 7795 assert(funcBwd(Date(2011, 2, 28)) == Date(2010, 6, 28)); 7796 assert(funcBwd(Date(2011, 3, 31)) == Date(2010, 6, 30)); 7797 assert(funcBwd(Date(2011, 4, 30)) == Date(2010, 6, 30)); 7798 assert(funcBwd(Date(2011, 5, 31)) == Date(2010, 6, 30)); 7799 assert(funcBwd(Date(2011, 6, 30)) == Date(2010, 6, 30)); 7800 assert(funcBwd(Date(2011, 7, 30)) == Date(2011, 6, 30)); 7801 7802 static assert(!__traits(compiles, everyMonth!TimeOfDay(Month.jan))); 7803 assert(everyMonth!DateTime(Month.jan) !is null); 7804 assert(everyMonth!SysTime(Month.jan) !is null); 7805 } 7806 7807 7808 /++ 7809 Range-generating function. 7810 7811 Returns a delegate which returns the next time point which is the given 7812 duration later. 7813 7814 Using this delegate allows iteration over successive time points which 7815 are apart by the given duration e.g. passing $(D dur!"days"(3)) to 7816 $(D everyDuration) would result in a delegate which could be used to iterate 7817 over a range of days which are each 3 days apart. 7818 7819 Params: 7820 dir = The direction to iterate in. If passing the return value to 7821 $(D fwdRange), use $(D Direction.fwd). If passing it to 7822 $(D bwdRange), use $(D Direction.bwd). 7823 duration = The duration which separates each successive time point in 7824 the range. 7825 +/ 7826 TP delegate(in TP) everyDuration(TP, Direction dir = Direction.fwd, D)(D duration) nothrow 7827 if (isTimePoint!TP && 7828 __traits(compiles, TP.init + duration) && 7829 (dir == Direction.fwd || dir == Direction.bwd)) 7830 { 7831 TP func(in TP tp) 7832 { 7833 static if (dir == Direction.fwd) 7834 return tp + duration; 7835 else 7836 return tp - duration; 7837 } 7838 7839 return &func; 7840 } 7841 7842 /// 7843 @system unittest 7844 { 7845 import core.time : dur; 7846 import std.datetime.date : Date; 7847 7848 auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27)); 7849 auto func = everyDuration!Date(dur!"days"(8)); 7850 auto range = interval.fwdRange(func); 7851 7852 // Using PopFirst.yes would have made this Date(2010, 9, 10). 7853 assert(range.front == Date(2010, 9, 2)); 7854 7855 range.popFront(); 7856 assert(range.front == Date(2010, 9, 10)); 7857 7858 range.popFront(); 7859 assert(range.front == Date(2010, 9, 18)); 7860 7861 range.popFront(); 7862 assert(range.front == Date(2010, 9, 26)); 7863 7864 range.popFront(); 7865 assert(range.empty); 7866 } 7867 7868 @system unittest 7869 { 7870 import std.datetime.date; 7871 import std.datetime.systime; 7872 7873 auto funcFwd = everyDuration!Date(dur!"days"(27)); 7874 auto funcBwd = everyDuration!(Date, Direction.bwd)(dur!"days"(27)); 7875 7876 assert(funcFwd(Date(2009, 12, 25)) == Date(2010, 1, 21)); 7877 assert(funcFwd(Date(2009, 12, 26)) == Date(2010, 1, 22)); 7878 assert(funcFwd(Date(2009, 12, 27)) == Date(2010, 1, 23)); 7879 assert(funcFwd(Date(2009, 12, 28)) == Date(2010, 1, 24)); 7880 7881 assert(funcBwd(Date(2010, 1, 21)) == Date(2009, 12, 25)); 7882 assert(funcBwd(Date(2010, 1, 22)) == Date(2009, 12, 26)); 7883 assert(funcBwd(Date(2010, 1, 23)) == Date(2009, 12, 27)); 7884 assert(funcBwd(Date(2010, 1, 24)) == Date(2009, 12, 28)); 7885 7886 assert(everyDuration!Date(dur!"hnsecs"(1)) !is null); 7887 assert(everyDuration!TimeOfDay(dur!"hnsecs"(1)) !is null); 7888 assert(everyDuration!DateTime(dur!"hnsecs"(1)) !is null); 7889 assert(everyDuration!SysTime(dur!"hnsecs"(1)) !is null); 7890 } 7891 7892 7893 /++ 7894 Range-generating function. 7895 7896 Returns a delegate which returns the next time point which is the given 7897 number of years, month, and duration later. 7898 7899 The difference between this version of $(D everyDuration) and the version 7900 which just takes a $(REF Duration, core,time) is that this one also takes 7901 the number of years and months (along with an $(D AllowDayOverflow) to 7902 indicate whether adding years and months should allow the days to overflow). 7903 7904 Note that if iterating forward, $(D add!"years"()) is called on the given 7905 time point, then $(D add!"months"()), and finally the duration is added 7906 to it. However, if iterating backwards, the duration is added first, then 7907 $(D add!"months"()) is called, and finally $(D add!"years"()) is called. 7908 That way, going backwards generates close to the same time points that 7909 iterating forward does, but since adding years and months is not entirely 7910 reversible (due to possible day overflow, regardless of whether 7911 $(D AllowDayOverflow.yes) or $(D AllowDayOverflow.no) is used), it can't be 7912 guaranteed that iterating backwards will give the same time points as 7913 iterating forward would have (even assuming that the end of the range is a 7914 time point which would be returned by the delegate when iterating forward 7915 from $(D begin)). 7916 7917 Params: 7918 dir = The direction to iterate in. If passing the return 7919 value to $(D fwdRange), use $(D Direction.fwd). If 7920 passing it to $(D bwdRange), use $(D Direction.bwd). 7921 years = The number of years to add to the time point passed to 7922 the delegate. 7923 months = The number of months to add to the time point passed to 7924 the delegate. 7925 allowOverflow = Whether the days should be allowed to overflow on 7926 $(D begin) and $(D end), causing their month to 7927 increment. 7928 duration = The duration to add to the time point passed to the 7929 delegate. 7930 +/ 7931 TP delegate(in TP) everyDuration(TP, Direction dir = Direction.fwd, D) 7932 (int years, 7933 int months = 0, 7934 AllowDayOverflow allowOverflow = AllowDayOverflow.yes, 7935 D duration = dur!"days"(0)) nothrow 7936 if (isTimePoint!TP && 7937 __traits(compiles, TP.init + duration) && 7938 __traits(compiles, TP.init.add!"years"(years)) && 7939 __traits(compiles, TP.init.add!"months"(months)) && 7940 (dir == Direction.fwd || dir == Direction.bwd)) 7941 { 7942 TP func(in TP tp) 7943 { 7944 static if (dir == Direction.fwd) 7945 { 7946 TP retval = cast(TP) tp; 7947 7948 retval.add!"years"(years, allowOverflow); 7949 retval.add!"months"(months, allowOverflow); 7950 7951 return retval + duration; 7952 } 7953 else 7954 { 7955 TP retval = tp - duration; 7956 7957 retval.add!"months"(-months, allowOverflow); 7958 retval.add!"years"(-years, allowOverflow); 7959 7960 return retval; 7961 } 7962 } 7963 7964 return &func; 7965 } 7966 7967 /// 7968 @system unittest 7969 { 7970 import core.time : dur; 7971 import std.datetime.date : AllowDayOverflow, Date; 7972 7973 auto interval = Interval!Date(Date(2010, 9, 2), Date(2025, 9, 27)); 7974 auto func = everyDuration!Date(4, 1, AllowDayOverflow.yes, dur!"days"(2)); 7975 auto range = interval.fwdRange(func); 7976 7977 // Using PopFirst.yes would have made this Date(2014, 10, 12). 7978 assert(range.front == Date(2010, 9, 2)); 7979 7980 range.popFront(); 7981 assert(range.front == Date(2014, 10, 4)); 7982 7983 range.popFront(); 7984 assert(range.front == Date(2018, 11, 6)); 7985 7986 range.popFront(); 7987 assert(range.front == Date(2022, 12, 8)); 7988 7989 range.popFront(); 7990 assert(range.empty); 7991 } 7992 7993 @system unittest 7994 { 7995 import std.datetime.date; 7996 import std.datetime.systime; 7997 7998 { 7999 auto funcFwd = everyDuration!Date(1, 2, AllowDayOverflow.yes, dur!"days"(3)); 8000 auto funcBwd = everyDuration!(Date, Direction.bwd)(1, 2, AllowDayOverflow.yes, dur!"days"(3)); 8001 8002 assert(funcFwd(Date(2009, 12, 25)) == Date(2011, 2, 28)); 8003 assert(funcFwd(Date(2009, 12, 26)) == Date(2011, 3, 1)); 8004 assert(funcFwd(Date(2009, 12, 27)) == Date(2011, 3, 2)); 8005 assert(funcFwd(Date(2009, 12, 28)) == Date(2011, 3, 3)); 8006 assert(funcFwd(Date(2009, 12, 29)) == Date(2011, 3, 4)); 8007 8008 assert(funcBwd(Date(2011, 2, 28)) == Date(2009, 12, 25)); 8009 assert(funcBwd(Date(2011, 3, 1)) == Date(2009, 12, 26)); 8010 assert(funcBwd(Date(2011, 3, 2)) == Date(2009, 12, 27)); 8011 assert(funcBwd(Date(2011, 3, 3)) == Date(2009, 12, 28)); 8012 assert(funcBwd(Date(2011, 3, 4)) == Date(2010, 1, 1)); 8013 } 8014 8015 { 8016 auto funcFwd = everyDuration!Date(1, 2, AllowDayOverflow.no, dur!"days"(3)); 8017 auto funcBwd = everyDuration!(Date, Direction.bwd)(1, 2, AllowDayOverflow.yes, dur!"days"(3)); 8018 8019 assert(funcFwd(Date(2009, 12, 25)) == Date(2011, 2, 28)); 8020 assert(funcFwd(Date(2009, 12, 26)) == Date(2011, 3, 1)); 8021 assert(funcFwd(Date(2009, 12, 27)) == Date(2011, 3, 2)); 8022 assert(funcFwd(Date(2009, 12, 28)) == Date(2011, 3, 3)); 8023 assert(funcFwd(Date(2009, 12, 29)) == Date(2011, 3, 3)); 8024 8025 assert(funcBwd(Date(2011, 2, 28)) == Date(2009, 12, 25)); 8026 assert(funcBwd(Date(2011, 3, 1)) == Date(2009, 12, 26)); 8027 assert(funcBwd(Date(2011, 3, 2)) == Date(2009, 12, 27)); 8028 assert(funcBwd(Date(2011, 3, 3)) == Date(2009, 12, 28)); 8029 assert(funcBwd(Date(2011, 3, 4)) == Date(2010, 1, 1)); 8030 } 8031 8032 assert(everyDuration!Date(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)) !is null); 8033 static assert(!__traits(compiles, everyDuration!TimeOfDay(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)))); 8034 assert(everyDuration!DateTime(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)) !is null); 8035 assert(everyDuration!SysTime(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)) !is null); 8036 } 8037 8038 8039 /++ 8040 A range over an $(LREF Interval). 8041 8042 $(D IntervalRange) is only ever constructed by $(LREF Interval). However, when 8043 it is constructed, it is given a function, $(D func), which is used to 8044 generate the time points which are iterated over. $(D func) takes a time 8045 point and returns a time point of the same type. For instance, 8046 to iterate over all of the days in 8047 the interval $(D Interval!Date), pass a function to $(LREF Interval)'s 8048 $(D fwdRange) where that function took a $(REF Date,std,datetime,date) and 8049 returned a $(REF Date,std,datetime,date) which was one day later. That 8050 function would then be used by $(D IntervalRange)'s $(D popFront) to iterate 8051 over the $(REF Date,std,datetime,date)s in the interval. 8052 8053 If $(D dir == Direction.fwd), then a range iterates forward in time, whereas 8054 if $(D dir == Direction.bwd), then it iterates backwards in time. So, if 8055 $(D dir == Direction.fwd) then $(D front == interval.begin), whereas if 8056 $(D dir == Direction.bwd) then $(D front == interval.end). $(D func) must 8057 generate a time point going in the proper direction of iteration, or a 8058 $(REF DateTimeException,std,datetime,date) will be thrown. So, to iterate 8059 forward in time, the time point that $(D func) generates must be later in 8060 time than the one passed to it. If it's either identical or earlier in time, 8061 then a $(REF DateTimeException,std,datetime,date) will be thrown. To 8062 iterate backwards, then the generated time point must be before the time 8063 point which was passed in. 8064 8065 If the generated time point is ever passed the edge of the range in the 8066 proper direction, then the edge of that range will be used instead. So, if 8067 iterating forward, and the generated time point is past the interval's 8068 $(D end), then $(D front) becomes $(D end). If iterating backwards, and the 8069 generated time point is before $(D begin), then $(D front) becomes 8070 $(D begin). In either case, the range would then be empty. 8071 8072 Also note that while normally the $(D begin) of an interval is included in 8073 it and its $(D end) is excluded from it, if $(D dir == Direction.bwd), then 8074 $(D begin) is treated as excluded and $(D end) is treated as included. This 8075 allows for the same behavior in both directions. This works because none of 8076 $(LREF Interval)'s functions which care about whether $(D begin) or $(D end) 8077 is included or excluded are ever called by $(D IntervalRange). $(D interval) 8078 returns a normal interval, regardless of whether $(D dir == Direction.fwd) 8079 or if $(D dir == Direction.bwd), so any $(LREF Interval) functions which are 8080 called on it which care about whether $(D begin) or $(D end) are included or 8081 excluded will treat $(D begin) as included and $(D end) as excluded. 8082 +/ 8083 struct IntervalRange(TP, Direction dir) 8084 if (isTimePoint!TP && dir != Direction.both) 8085 { 8086 public: 8087 8088 /++ 8089 Params: 8090 rhs = The $(D IntervalRange) to assign to this one. 8091 +/ 8092 ref IntervalRange opAssign(ref IntervalRange rhs) pure nothrow 8093 { 8094 _interval = rhs._interval; 8095 _func = rhs._func; 8096 return this; 8097 } 8098 8099 8100 /++ Ditto +/ 8101 ref IntervalRange opAssign(IntervalRange rhs) pure nothrow 8102 { 8103 return this = rhs; 8104 } 8105 8106 8107 /++ 8108 Whether this $(D IntervalRange) is empty. 8109 +/ 8110 @property bool empty() const pure nothrow 8111 { 8112 return _interval.empty; 8113 } 8114 8115 8116 /++ 8117 The first time point in the range. 8118 8119 Throws: 8120 $(REF DateTimeException,std,datetime,date) if the range is empty. 8121 +/ 8122 @property TP front() const pure 8123 { 8124 _enforceNotEmpty(); 8125 8126 static if (dir == Direction.fwd) 8127 return _interval.begin; 8128 else 8129 return _interval.end; 8130 } 8131 8132 8133 /++ 8134 Pops $(D front) from the range, using $(D func) to generate the next 8135 time point in the range. If the generated time point is beyond the edge 8136 of the range, then $(D front) is set to that edge, and the range is then 8137 empty. So, if iterating forwards, and the generated time point is 8138 greater than the interval's $(D end), then $(D front) is set to 8139 $(D end). If iterating backwards, and the generated time point is less 8140 than the interval's $(D begin), then $(D front) is set to $(D begin). 8141 8142 Throws: 8143 $(REF DateTimeException,std,datetime,date) if the range is empty 8144 or if the generated time point is in the wrong direction (i.e. if 8145 iterating forward and the generated time point is before $(D front), 8146 or if iterating backwards and the generated time point is after 8147 $(D front)). 8148 +/ 8149 void popFront() 8150 { 8151 _enforceNotEmpty(); 8152 8153 static if (dir == Direction.fwd) 8154 { 8155 auto begin = _func(_interval.begin); 8156 8157 if (begin > _interval.end) 8158 begin = _interval.end; 8159 8160 _enforceCorrectDirection(begin); 8161 8162 _interval.begin = begin; 8163 } 8164 else 8165 { 8166 auto end = _func(_interval.end); 8167 8168 if (end < _interval.begin) 8169 end = _interval.begin; 8170 8171 _enforceCorrectDirection(end); 8172 8173 _interval.end = end; 8174 } 8175 } 8176 8177 8178 /++ 8179 Returns a copy of $(D this). 8180 +/ 8181 @property IntervalRange save() pure nothrow 8182 { 8183 return this; 8184 } 8185 8186 8187 /++ 8188 The interval that this $(D IntervalRange) currently covers. 8189 +/ 8190 @property Interval!TP interval() const pure nothrow 8191 { 8192 return cast(Interval!TP)_interval; 8193 } 8194 8195 8196 /++ 8197 The function used to generate the next time point in the range. 8198 +/ 8199 TP delegate(in TP) func() pure nothrow @property 8200 { 8201 return _func; 8202 } 8203 8204 8205 /++ 8206 The $(D Direction) that this range iterates in. 8207 +/ 8208 @property Direction direction() const pure nothrow 8209 { 8210 return dir; 8211 } 8212 8213 8214 private: 8215 8216 /+ 8217 Params: 8218 interval = The interval that this range covers. 8219 func = The function used to generate the time points which are 8220 iterated over. 8221 +/ 8222 this(in Interval!TP interval, TP delegate(in TP) func) pure nothrow 8223 { 8224 _func = func; 8225 _interval = interval; 8226 } 8227 8228 8229 /+ 8230 Throws: 8231 $(REF DateTimeException,std,datetime,date) if this interval is 8232 empty. 8233 +/ 8234 void _enforceNotEmpty(size_t line = __LINE__) const pure 8235 { 8236 if (empty) 8237 throw new DateTimeException("Invalid operation for an empty IntervalRange.", __FILE__, line); 8238 } 8239 8240 8241 /+ 8242 Throws: 8243 $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is 8244 in the wrong direction. 8245 +/ 8246 void _enforceCorrectDirection(in TP newTP, size_t line = __LINE__) const 8247 { 8248 import std.format : format; 8249 8250 static if (dir == Direction.fwd) 8251 { 8252 enforce(newTP > _interval._begin, 8253 new DateTimeException(format("Generated time point is before previous begin: prev [%s] new [%s]", 8254 interval._begin, 8255 newTP), 8256 __FILE__, 8257 line)); 8258 } 8259 else 8260 { 8261 enforce(newTP < _interval._end, 8262 new DateTimeException(format("Generated time point is after previous end: prev [%s] new [%s]", 8263 interval._end, 8264 newTP), 8265 __FILE__, 8266 line)); 8267 } 8268 } 8269 8270 8271 Interval!TP _interval; 8272 TP delegate(in TP) _func; 8273 } 8274 8275 //Test that IntervalRange satisfies the range predicates that it's supposed to satisfy. 8276 @safe unittest 8277 { 8278 import std.datetime.date; 8279 import std.datetime.systime; 8280 import std.range.primitives; 8281 8282 static assert(isInputRange!(IntervalRange!(Date, Direction.fwd))); 8283 static assert(isForwardRange!(IntervalRange!(Date, Direction.fwd))); 8284 8285 //Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=4895 8286 //static assert(!isOutputRange!(IntervalRange!(Date, Direction.fwd), Date)); 8287 8288 static assert(!isBidirectionalRange!(IntervalRange!(Date, Direction.fwd))); 8289 static assert(!isRandomAccessRange!(IntervalRange!(Date, Direction.fwd))); 8290 static assert(!hasSwappableElements!(IntervalRange!(Date, Direction.fwd))); 8291 static assert(!hasAssignableElements!(IntervalRange!(Date, Direction.fwd))); 8292 static assert(!hasLength!(IntervalRange!(Date, Direction.fwd))); 8293 static assert(!isInfinite!(IntervalRange!(Date, Direction.fwd))); 8294 static assert(!hasSlicing!(IntervalRange!(Date, Direction.fwd))); 8295 8296 static assert(is(ElementType!(IntervalRange!(Date, Direction.fwd)) == Date)); 8297 static assert(is(ElementType!(IntervalRange!(TimeOfDay, Direction.fwd)) == TimeOfDay)); 8298 static assert(is(ElementType!(IntervalRange!(DateTime, Direction.fwd)) == DateTime)); 8299 static assert(is(ElementType!(IntervalRange!(SysTime, Direction.fwd)) == SysTime)); 8300 } 8301 8302 //Test construction of IntervalRange. 8303 @safe unittest 8304 { 8305 import std.datetime.date; 8306 import std.datetime.systime; 8307 8308 { 8309 Date dateFunc(in Date date) { return date; } 8310 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8311 auto ir = IntervalRange!(Date, Direction.fwd)(interval, &dateFunc); 8312 } 8313 8314 { 8315 TimeOfDay todFunc(in TimeOfDay tod) { return tod; } 8316 auto interval = Interval!TimeOfDay(TimeOfDay(12, 1, 7), TimeOfDay(14, 0, 0)); 8317 auto ir = IntervalRange!(TimeOfDay, Direction.fwd)(interval, &todFunc); 8318 } 8319 8320 { 8321 DateTime dtFunc(in DateTime dt) { return dt; } 8322 auto interval = Interval!DateTime(DateTime(2010, 7, 4, 12, 1, 7), DateTime(2012, 1, 7, 14, 0, 0)); 8323 auto ir = IntervalRange!(DateTime, Direction.fwd)(interval, &dtFunc); 8324 } 8325 8326 { 8327 SysTime stFunc(in SysTime st) { return cast(SysTime) st; } 8328 auto interval = Interval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)), 8329 SysTime(DateTime(2012, 1, 7, 14, 0, 0))); 8330 auto ir = IntervalRange!(SysTime, Direction.fwd)(interval, &stFunc); 8331 } 8332 } 8333 8334 //Test IntervalRange's empty(). 8335 @system unittest 8336 { 8337 import std.datetime.date; 8338 8339 //fwd 8340 { 8341 auto range = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 8342 8343 assert(!range.empty); 8344 range.popFront(); 8345 assert(range.empty); 8346 8347 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 8348 assert(!cRange.empty); 8349 8350 //Apparently, creating an immutable IntervalRange!Date doesn't work, so we can't test if 8351 //empty works with it. However, since an immutable range is pretty useless, it's no great loss. 8352 } 8353 8354 //bwd 8355 { 8356 auto range = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)).bwdRange( 8357 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 8358 8359 assert(!range.empty); 8360 range.popFront(); 8361 assert(range.empty); 8362 8363 const cRange = Interval!Date( Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( 8364 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 8365 assert(!cRange.empty); 8366 8367 //Apparently, creating an immutable IntervalRange!Date doesn't work, so we can't test if 8368 //empty works with it. However, since an immutable range is pretty useless, it's no great loss. 8369 } 8370 } 8371 8372 //Test IntervalRange's front. 8373 @system unittest 8374 { 8375 import std.datetime.date; 8376 8377 //fwd 8378 { 8379 auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).fwdRange( 8380 everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); 8381 assertThrown!DateTimeException((in IntervalRange!(Date, Direction.fwd) range){range.front;}(emptyRange)); 8382 8383 auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed)); 8384 assert(range.front == Date(2010, 7, 4)); 8385 8386 auto poppedRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange( 8387 everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); 8388 assert(poppedRange.front == Date(2010, 7, 7)); 8389 8390 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 8391 assert(cRange.front != Date.init); 8392 } 8393 8394 //bwd 8395 { 8396 auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).bwdRange( 8397 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); 8398 assertThrown!DateTimeException((in IntervalRange!(Date, Direction.bwd) range){range.front;}(emptyRange)); 8399 8400 auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( 8401 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed)); 8402 assert(range.front == Date(2012, 1, 7)); 8403 8404 auto poppedRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( 8405 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); 8406 assert(poppedRange.front == Date(2012, 1, 4)); 8407 8408 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( 8409 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 8410 assert(cRange.front != Date.init); 8411 } 8412 } 8413 8414 //Test IntervalRange's popFront(). 8415 @system unittest 8416 { 8417 import std.datetime.date; 8418 import std.range.primitives : walkLength; 8419 8420 //fwd 8421 { 8422 auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).fwdRange( 8423 everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); 8424 assertThrown!DateTimeException((IntervalRange!(Date, Direction.fwd) range){range.popFront();}(emptyRange)); 8425 8426 auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange( 8427 everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); 8428 auto expected = range.front; 8429 8430 foreach (date; range) 8431 { 8432 assert(date == expected); 8433 expected += dur!"days"(7); 8434 } 8435 8436 assert(walkLength(range) == 79); 8437 8438 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 8439 assert(cRange.front != Date.init); 8440 } 8441 8442 //bwd 8443 { 8444 auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).bwdRange( 8445 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); 8446 assertThrown!DateTimeException((IntervalRange!(Date, Direction.bwd) range){range.popFront();}(emptyRange)); 8447 8448 auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( 8449 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); 8450 auto expected = range.front; 8451 8452 foreach (date; range) 8453 { 8454 assert(date == expected); 8455 expected += dur!"days"(-7); 8456 } 8457 8458 assert(walkLength(range) == 79); 8459 8460 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( 8461 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 8462 static assert(!__traits(compiles, cRange.popFront())); 8463 } 8464 } 8465 8466 //Test IntervalRange's save. 8467 @system unittest 8468 { 8469 import std.datetime.date; 8470 8471 //fwd 8472 { 8473 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8474 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8475 auto range = interval.fwdRange(func); 8476 8477 assert(range.save == range); 8478 } 8479 8480 //bwd 8481 { 8482 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8483 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); 8484 auto range = interval.bwdRange(func); 8485 8486 assert(range.save == range); 8487 } 8488 } 8489 8490 //Test IntervalRange's interval. 8491 @system unittest 8492 { 8493 import std.datetime.date; 8494 8495 //fwd 8496 { 8497 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8498 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8499 auto range = interval.fwdRange(func); 8500 8501 assert(range.interval == interval); 8502 8503 const cRange = range; 8504 assert(!cRange.interval.empty); 8505 } 8506 8507 //bwd 8508 { 8509 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8510 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); 8511 auto range = interval.bwdRange(func); 8512 8513 assert(range.interval == interval); 8514 8515 const cRange = range; 8516 assert(!cRange.interval.empty); 8517 } 8518 } 8519 8520 //Test IntervalRange's func. 8521 @system unittest 8522 { 8523 import std.datetime.date; 8524 8525 //fwd 8526 { 8527 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8528 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8529 auto range = interval.fwdRange(func); 8530 8531 assert(range.func == func); 8532 } 8533 8534 //bwd 8535 { 8536 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8537 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); 8538 auto range = interval.bwdRange(func); 8539 8540 assert(range.func == func); 8541 } 8542 } 8543 8544 //Test IntervalRange's direction. 8545 @system unittest 8546 { 8547 import std.datetime.date; 8548 8549 //fwd 8550 { 8551 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8552 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8553 auto range = interval.fwdRange(func); 8554 8555 assert(range.direction == Direction.fwd); 8556 8557 const cRange = range; 8558 assert(cRange.direction == Direction.fwd); 8559 } 8560 8561 //bwd 8562 { 8563 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8564 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); 8565 auto range = interval.bwdRange(func); 8566 8567 assert(range.direction == Direction.bwd); 8568 8569 const cRange = range; 8570 assert(cRange.direction == Direction.bwd); 8571 } 8572 } 8573 8574 8575 /++ 8576 A range over a $(D PosInfInterval). It is an infinite range. 8577 8578 $(D PosInfIntervalRange) is only ever constructed by $(D PosInfInterval). 8579 However, when it is constructed, it is given a function, $(D func), which 8580 is used to generate the time points which are iterated over. $(D func) 8581 takes a time point and returns a time point of the same type. For 8582 instance, to iterate 8583 over all of the days in the interval $(D PosInfInterval!Date), pass a 8584 function to $(D PosInfInterval)'s $(D fwdRange) where that function took a 8585 $(REF Date,std,datetime,date) and returned a $(REF Date,std,datetime,date) 8586 which was one day later. That function would then be used by 8587 $(D PosInfIntervalRange)'s $(D popFront) to iterate over the 8588 $(REF Date,std,datetime,date)s in the interval - though obviously, since the 8589 range is infinite, use a function such as $(D std.range.take) with it rather 8590 than iterating over $(I all) of the dates. 8591 8592 As the interval goes to positive infinity, the range is always iterated over 8593 forwards, never backwards. $(D func) must generate a time point going in 8594 the proper direction of iteration, or a 8595 $(REF DateTimeException,std,datetime,date) will be thrown. So, the time 8596 points that $(D func) generates must be later in time than the one passed to 8597 it. If it's either identical or earlier in time, then a 8598 $(REF DateTimeException,std,datetime,date) will be thrown. 8599 +/ 8600 struct PosInfIntervalRange(TP) 8601 if (isTimePoint!TP) 8602 { 8603 public: 8604 8605 /++ 8606 Params: 8607 rhs = The $(D PosInfIntervalRange) to assign to this one. 8608 +/ 8609 ref PosInfIntervalRange opAssign(ref PosInfIntervalRange rhs) pure nothrow 8610 { 8611 _interval = rhs._interval; 8612 _func = rhs._func; 8613 return this; 8614 } 8615 8616 8617 /++ Ditto +/ 8618 ref PosInfIntervalRange opAssign(PosInfIntervalRange rhs) pure nothrow 8619 { 8620 return this = rhs; 8621 } 8622 8623 8624 /++ 8625 This is an infinite range, so it is never empty. 8626 +/ 8627 enum bool empty = false; 8628 8629 8630 /++ 8631 The first time point in the range. 8632 +/ 8633 @property TP front() const pure nothrow 8634 { 8635 return _interval.begin; 8636 } 8637 8638 8639 /++ 8640 Pops $(D front) from the range, using $(D func) to generate the next 8641 time point in the range. 8642 8643 Throws: 8644 $(REF DateTimeException,std,datetime,date) if the generated time 8645 point is less than $(D front). 8646 +/ 8647 void popFront() 8648 { 8649 auto begin = _func(_interval.begin); 8650 _enforceCorrectDirection(begin); 8651 _interval.begin = begin; 8652 } 8653 8654 8655 /++ 8656 Returns a copy of $(D this). 8657 +/ 8658 @property PosInfIntervalRange save() pure nothrow 8659 { 8660 return this; 8661 } 8662 8663 8664 /++ 8665 The interval that this range currently covers. 8666 +/ 8667 @property PosInfInterval!TP interval() const pure nothrow 8668 { 8669 return cast(PosInfInterval!TP)_interval; 8670 } 8671 8672 8673 /++ 8674 The function used to generate the next time point in the range. 8675 +/ 8676 TP delegate(in TP) func() pure nothrow @property 8677 { 8678 return _func; 8679 } 8680 8681 8682 private: 8683 8684 /+ 8685 Params: 8686 interval = The interval that this range covers. 8687 func = The function used to generate the time points which are 8688 iterated over. 8689 +/ 8690 this(in PosInfInterval!TP interval, TP delegate(in TP) func) pure nothrow 8691 { 8692 _func = func; 8693 _interval = interval; 8694 } 8695 8696 8697 /+ 8698 Throws: 8699 $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is 8700 in the wrong direction. 8701 +/ 8702 void _enforceCorrectDirection(in TP newTP, size_t line = __LINE__) const 8703 { 8704 import std.format : format; 8705 8706 enforce(newTP > _interval._begin, 8707 new DateTimeException(format("Generated time point is before previous begin: prev [%s] new [%s]", 8708 interval._begin, 8709 newTP), 8710 __FILE__, 8711 line)); 8712 } 8713 8714 8715 PosInfInterval!TP _interval; 8716 TP delegate(in TP) _func; 8717 } 8718 8719 //Test that PosInfIntervalRange satisfies the range predicates that it's supposed to satisfy. 8720 @safe unittest 8721 { 8722 import std.datetime.date; 8723 import std.datetime.systime; 8724 import std.range.primitives; 8725 8726 static assert(isInputRange!(PosInfIntervalRange!Date)); 8727 static assert(isForwardRange!(PosInfIntervalRange!Date)); 8728 static assert(isInfinite!(PosInfIntervalRange!Date)); 8729 8730 //Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=4895 8731 //static assert(!isOutputRange!(PosInfIntervalRange!Date, Date)); 8732 static assert(!isBidirectionalRange!(PosInfIntervalRange!Date)); 8733 static assert(!isRandomAccessRange!(PosInfIntervalRange!Date)); 8734 static assert(!hasSwappableElements!(PosInfIntervalRange!Date)); 8735 static assert(!hasAssignableElements!(PosInfIntervalRange!Date)); 8736 static assert(!hasLength!(PosInfIntervalRange!Date)); 8737 static assert(!hasSlicing!(PosInfIntervalRange!Date)); 8738 8739 static assert(is(ElementType!(PosInfIntervalRange!Date) == Date)); 8740 static assert(is(ElementType!(PosInfIntervalRange!TimeOfDay) == TimeOfDay)); 8741 static assert(is(ElementType!(PosInfIntervalRange!DateTime) == DateTime)); 8742 static assert(is(ElementType!(PosInfIntervalRange!SysTime) == SysTime)); 8743 } 8744 8745 //Test construction of PosInfIntervalRange. 8746 @safe unittest 8747 { 8748 import std.datetime.date; 8749 import std.datetime.systime; 8750 8751 { 8752 Date dateFunc(in Date date) { return date; } 8753 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 8754 auto ir = PosInfIntervalRange!Date(posInfInterval, &dateFunc); 8755 } 8756 8757 { 8758 TimeOfDay todFunc(in TimeOfDay tod) { return tod; } 8759 auto posInfInterval = PosInfInterval!TimeOfDay(TimeOfDay(12, 1, 7)); 8760 auto ir = PosInfIntervalRange!(TimeOfDay)(posInfInterval, &todFunc); 8761 } 8762 8763 { 8764 DateTime dtFunc(in DateTime dt) { return dt; } 8765 auto posInfInterval = PosInfInterval!DateTime(DateTime(2010, 7, 4, 12, 1, 7)); 8766 auto ir = PosInfIntervalRange!(DateTime)(posInfInterval, &dtFunc); 8767 } 8768 8769 { 8770 SysTime stFunc(in SysTime st) { return cast(SysTime) st; } 8771 auto posInfInterval = PosInfInterval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7))); 8772 auto ir = PosInfIntervalRange!SysTime(posInfInterval, &stFunc); 8773 } 8774 } 8775 8776 //Test PosInfIntervalRange's front. 8777 @system unittest 8778 { 8779 import std.datetime.date; 8780 8781 auto range = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed)); 8782 assert(range.front == Date(2010, 7, 4)); 8783 8784 auto poppedRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); 8785 assert(poppedRange.front == Date(2010, 7, 7)); 8786 8787 const cRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 8788 assert(cRange.front != Date.init); 8789 } 8790 8791 //Test PosInfIntervalRange's popFront(). 8792 @system unittest 8793 { 8794 import std.datetime.date; 8795 import std.range : take; 8796 8797 auto range = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); 8798 auto expected = range.front; 8799 8800 foreach (date; take(range, 79)) 8801 { 8802 assert(date == expected); 8803 expected += dur!"days"(7); 8804 } 8805 8806 const cRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 8807 static assert(!__traits(compiles, cRange.popFront())); 8808 } 8809 8810 //Test PosInfIntervalRange's save. 8811 @system unittest 8812 { 8813 import std.datetime.date; 8814 8815 auto interval = PosInfInterval!Date(Date(2010, 7, 4)); 8816 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8817 auto range = interval.fwdRange(func); 8818 8819 assert(range.save == range); 8820 } 8821 8822 //Test PosInfIntervalRange's interval. 8823 @system unittest 8824 { 8825 import std.datetime.date; 8826 8827 auto interval = PosInfInterval!Date(Date(2010, 7, 4)); 8828 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8829 auto range = interval.fwdRange(func); 8830 8831 assert(range.interval == interval); 8832 8833 const cRange = range; 8834 assert(!cRange.interval.empty); 8835 } 8836 8837 //Test PosInfIntervalRange's func. 8838 @system unittest 8839 { 8840 import std.datetime.date; 8841 8842 auto interval = PosInfInterval!Date(Date(2010, 7, 4)); 8843 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8844 auto range = interval.fwdRange(func); 8845 8846 assert(range.func == func); 8847 } 8848 8849 8850 /++ 8851 A range over a $(D NegInfInterval). It is an infinite range. 8852 8853 $(D NegInfIntervalRange) is only ever constructed by $(D NegInfInterval). 8854 However, when it is constructed, it is given a function, $(D func), which 8855 is used to generate the time points which are iterated over. $(D func) 8856 takes a time point and returns a time point of the same type. For 8857 instance, to iterate over all of the days in the interval 8858 $(D NegInfInterval!Date), pass a function to $(D NegInfInterval)'s 8859 $(D bwdRange) where that function took a $(REF Date,std,datetime,date) and 8860 returned a $(REF Date,std,datetime,date) which was one day earlier. That 8861 function would then be used by $(D NegInfIntervalRange)'s $(D popFront) to 8862 iterate over the $(REF Date,std,datetime,date)s in the interval - though 8863 obviously, since the range is infinite, use a function such as 8864 $(D std.range.take) with it rather than iterating over $(I all) of the dates. 8865 8866 As the interval goes to negative infinity, the range is always iterated over 8867 backwards, never forwards. $(D func) must generate a time point going in 8868 the proper direction of iteration, or a 8869 $(REF DateTimeException,std,datetime,date) will be thrown. So, the time 8870 points that $(D func) generates must be earlier in time than the one passed 8871 to it. If it's either identical or later in time, then a 8872 $(REF DateTimeException,std,datetime,date) will be thrown. 8873 8874 Also note that while normally the $(D end) of an interval is excluded from 8875 it, $(D NegInfIntervalRange) treats it as if it were included. This allows 8876 for the same behavior as with $(D PosInfIntervalRange). This works 8877 because none of $(D NegInfInterval)'s functions which care about whether 8878 $(D end) is included or excluded are ever called by 8879 $(D NegInfIntervalRange). $(D interval) returns a normal interval, so any 8880 $(D NegInfInterval) functions which are called on it which care about 8881 whether $(D end) is included or excluded will treat $(D end) as excluded. 8882 +/ 8883 struct NegInfIntervalRange(TP) 8884 if (isTimePoint!TP) 8885 { 8886 public: 8887 8888 /++ 8889 Params: 8890 rhs = The $(D NegInfIntervalRange) to assign to this one. 8891 +/ 8892 ref NegInfIntervalRange opAssign(ref NegInfIntervalRange rhs) pure nothrow 8893 { 8894 _interval = rhs._interval; 8895 _func = rhs._func; 8896 8897 return this; 8898 } 8899 8900 8901 /++ Ditto +/ 8902 ref NegInfIntervalRange opAssign(NegInfIntervalRange rhs) pure nothrow 8903 { 8904 return this = rhs; 8905 } 8906 8907 8908 /++ 8909 This is an infinite range, so it is never empty. 8910 +/ 8911 enum bool empty = false; 8912 8913 8914 /++ 8915 The first time point in the range. 8916 +/ 8917 @property TP front() const pure nothrow 8918 { 8919 return _interval.end; 8920 } 8921 8922 8923 /++ 8924 Pops $(D front) from the range, using $(D func) to generate the next 8925 time point in the range. 8926 8927 Throws: 8928 $(REF DateTimeException,std,datetime,date) if the generated time 8929 point is greater than $(D front). 8930 +/ 8931 void popFront() 8932 { 8933 auto end = _func(_interval.end); 8934 _enforceCorrectDirection(end); 8935 _interval.end = end; 8936 } 8937 8938 8939 /++ 8940 Returns a copy of $(D this). 8941 +/ 8942 @property NegInfIntervalRange save() pure nothrow 8943 { 8944 return this; 8945 } 8946 8947 8948 /++ 8949 The interval that this range currently covers. 8950 +/ 8951 @property NegInfInterval!TP interval() const pure nothrow 8952 { 8953 return cast(NegInfInterval!TP)_interval; 8954 } 8955 8956 8957 /++ 8958 The function used to generate the next time point in the range. 8959 +/ 8960 TP delegate(in TP) func() pure nothrow @property 8961 { 8962 return _func; 8963 } 8964 8965 8966 private: 8967 8968 /+ 8969 Params: 8970 interval = The interval that this range covers. 8971 func = The function used to generate the time points which are 8972 iterated over. 8973 +/ 8974 this(in NegInfInterval!TP interval, TP delegate(in TP) func) pure nothrow 8975 { 8976 _func = func; 8977 _interval = interval; 8978 } 8979 8980 8981 /+ 8982 Throws: 8983 $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is 8984 in the wrong direction. 8985 +/ 8986 void _enforceCorrectDirection(in TP newTP, size_t line = __LINE__) const 8987 { 8988 import std.format : format; 8989 8990 enforce(newTP < _interval._end, 8991 new DateTimeException(format("Generated time point is before previous end: prev [%s] new [%s]", 8992 interval._end, 8993 newTP), 8994 __FILE__, 8995 line)); 8996 } 8997 8998 8999 NegInfInterval!TP _interval; 9000 TP delegate(in TP) _func; 9001 } 9002 9003 //Test that NegInfIntervalRange satisfies the range predicates that it's supposed to satisfy. 9004 @safe unittest 9005 { 9006 import std.datetime.date; 9007 import std.range.primitives; 9008 9009 static assert(isInputRange!(NegInfIntervalRange!Date)); 9010 static assert(isForwardRange!(NegInfIntervalRange!Date)); 9011 static assert(isInfinite!(NegInfIntervalRange!Date)); 9012 9013 //Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=4895 9014 //static assert(!isOutputRange!(NegInfIntervalRange!Date, Date)); 9015 static assert(!isBidirectionalRange!(NegInfIntervalRange!Date)); 9016 static assert(!isRandomAccessRange!(NegInfIntervalRange!Date)); 9017 static assert(!hasSwappableElements!(NegInfIntervalRange!Date)); 9018 static assert(!hasAssignableElements!(NegInfIntervalRange!Date)); 9019 static assert(!hasLength!(NegInfIntervalRange!Date)); 9020 static assert(!hasSlicing!(NegInfIntervalRange!Date)); 9021 9022 static assert(is(ElementType!(NegInfIntervalRange!Date) == Date)); 9023 static assert(is(ElementType!(NegInfIntervalRange!TimeOfDay) == TimeOfDay)); 9024 static assert(is(ElementType!(NegInfIntervalRange!DateTime) == DateTime)); 9025 } 9026 9027 //Test construction of NegInfIntervalRange. 9028 @safe unittest 9029 { 9030 import std.datetime.date; 9031 import std.datetime.systime; 9032 9033 { 9034 Date dateFunc(in Date date) { return date; } 9035 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 9036 auto ir = NegInfIntervalRange!Date(negInfInterval, &dateFunc); 9037 } 9038 9039 { 9040 TimeOfDay todFunc(in TimeOfDay tod) { return tod; } 9041 auto negInfInterval = NegInfInterval!TimeOfDay(TimeOfDay(14, 0, 0)); 9042 auto ir = NegInfIntervalRange!(TimeOfDay)(negInfInterval, &todFunc); 9043 } 9044 9045 { 9046 DateTime dtFunc(in DateTime dt) { return dt; } 9047 auto negInfInterval = NegInfInterval!DateTime(DateTime(2012, 1, 7, 14, 0, 0)); 9048 auto ir = NegInfIntervalRange!(DateTime)(negInfInterval, &dtFunc); 9049 } 9050 9051 { 9052 SysTime stFunc(in SysTime st) { return cast(SysTime)(st); } 9053 auto negInfInterval = NegInfInterval!SysTime(SysTime(DateTime(2012, 1, 7, 14, 0, 0))); 9054 auto ir = NegInfIntervalRange!(SysTime)(negInfInterval, &stFunc); 9055 } 9056 } 9057 9058 //Test NegInfIntervalRange's front. 9059 @system unittest 9060 { 9061 import std.datetime.date; 9062 9063 auto range = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed)); 9064 assert(range.front == Date(2012, 1, 7)); 9065 9066 auto poppedRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange( 9067 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); 9068 assert(poppedRange.front == Date(2012, 1, 4)); 9069 9070 const cRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 9071 assert(cRange.front != Date.init); 9072 } 9073 9074 //Test NegInfIntervalRange's popFront(). 9075 @system unittest 9076 { 9077 import std.datetime.date; 9078 import std.range : take; 9079 9080 auto range = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange( 9081 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); 9082 auto expected = range.front; 9083 9084 foreach (date; take(range, 79)) 9085 { 9086 assert(date == expected); 9087 expected += dur!"days"(-7); 9088 } 9089 9090 const cRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 9091 static assert(!__traits(compiles, cRange.popFront())); 9092 } 9093 9094 //Test NegInfIntervalRange's save. 9095 @system unittest 9096 { 9097 import std.datetime.date; 9098 9099 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 9100 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); 9101 auto range = interval.bwdRange(func); 9102 9103 assert(range.save == range); 9104 } 9105 9106 //Test NegInfIntervalRange's interval. 9107 @system unittest 9108 { 9109 import std.datetime.date; 9110 9111 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 9112 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); 9113 auto range = interval.bwdRange(func); 9114 9115 assert(range.interval == interval); 9116 9117 const cRange = range; 9118 assert(!cRange.interval.empty); 9119 } 9120 9121 //Test NegInfIntervalRange's func. 9122 @system unittest 9123 { 9124 import std.datetime.date; 9125 9126 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 9127 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); 9128 auto range = interval.bwdRange(func); 9129 9130 assert(range.func == func); 9131 } 9132