1 // Written in the D programming language 2 3 /++ 4 $(SCRIPT inhibitQuickIndex = 1;) 5 $(DIVC quickindex, 6 $(BOOKTABLE, 7 $(TR $(TH Category) $(TH Functions)) 8 $(TR $(TD Main types) $(TD 9 $(LREF Interval) 10 $(LREF Direction) 11 )) 12 $(TR $(TD Special intervals) $(TD 13 $(LREF everyDayOfWeek) 14 $(LREF everyMonth) 15 $(LREF everyDuration) 16 )) 17 $(TR $(TD Special intervals) $(TD 18 $(LREF NegInfInterval) 19 $(LREF PosInfInterval) 20 )) 21 $(TR $(TD Underlying ranges) $(TD 22 $(LREF IntervalRange) 23 $(LREF NegInfIntervalRange) 24 $(LREF PosInfIntervalRange) 25 )) 26 $(TR $(TD Flags) $(TD 27 $(LREF PopFirst) 28 )) 29 )) 30 31 License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 32 Authors: $(HTTP jmdavisprog.com, Jonathan M Davis) 33 Source: $(PHOBOSSRC std/datetime/interval.d) 34 +/ 35 module std.datetime.interval; 36 37 import core.time : Duration, dur; 38 import std.datetime.date : AllowDayOverflow, DateTimeException, daysToDayOfWeek, 39 DayOfWeek, isTimePoint, Month; 40 import std.exception : enforce; 41 import std.range.primitives : isOutputRange; 42 import std.traits : isIntegral; 43 import std.typecons : Flag; 44 45 version (StdUnittest) import std.exception : assertThrown; 46 47 48 /++ 49 Indicates a direction in time. One example of its use is $(LREF Interval)'s 50 $(LREF expand) function which uses it to indicate whether the interval 51 should be expanded backwards (into the past), forwards (into the future), or 52 both. 53 +/ 54 enum Direction 55 { 56 /// Backward. 57 bwd, 58 59 /// Forward. 60 fwd, 61 62 /// Both backward and forward. 63 both 64 } 65 66 67 /++ 68 Used to indicate whether `popFront` should be called immediately upon 69 creating a range. The idea is that for some functions used to generate a 70 range for an interval, `front` is not necessarily a time point which 71 would ever be generated by the range (e.g. if the range were every Sunday 72 within an interval, but the interval started on a Monday), so there needs 73 to be a way to deal with that. To get the first time point in the range to 74 match what the function generates, then use `PopFirst.yes` to indicate 75 that the range should have `popFront` called on it before the range is 76 returned so that `front` is a time point which the function would 77 generate. To let the first time point not match the generator function, 78 use `PopFront.no`. 79 80 For instance, if the function used to generate a range of time points 81 generated successive Easters (i.e. you're iterating over all of the Easters 82 within the interval), the initial date probably isn't an Easter. Using 83 `PopFirst.yes` would tell the function which returned the range that 84 `popFront` was to be called so that front would then be an Easter - the 85 next one generated by the function (which when iterating forward would be 86 the Easter following the original `front`, while when iterating backward, 87 it would be the Easter prior to the original `front`). If 88 `PopFirst.no` were used, then `front` would remain the original time 89 point and it would not necessarily be a time point which would be generated 90 by the range-generating function (which in many cases is exactly what is 91 desired - e.g. if iterating over every day starting at the beginning of the 92 interval). 93 94 If set to `PopFirst.no`, then popFront is not called before returning 95 the range. 96 97 Otherwise, if set to `PopFirst.yes`, then popFront is called before 98 returning the range. 99 +/ 100 alias PopFirst = Flag!"popFirst"; 101 102 103 /++ 104 Represents an interval of time. 105 106 An `Interval` has a starting point and an end point. The interval of time 107 is therefore the time starting at the starting point up to, but not 108 including, the end point. e.g. 109 110 $(BOOKTABLE, 111 $(TR $(TD [January 5th, 2010 - March 10th, 2010$(RPAREN))) 112 $(TR $(TD [05:00:30 - 12:00:00$(RPAREN))) 113 $(TR $(TD [1982-01-04T08:59:00 - 2010-07-04T12:00:00$(RPAREN))) 114 ) 115 116 A range can be obtained from an `Interval`, allowing iteration over 117 that interval, with the exact time points which are iterated over depending 118 on the function which generates the range. 119 +/ 120 struct Interval(TP) 121 { 122 public: 123 124 /++ 125 Params: 126 begin = The time point which begins the interval. 127 end = The time point which ends (but is not included in) the 128 interval. 129 130 Throws: 131 $(REF DateTimeException,std,datetime,date) if $(D_PARAM end) is 132 before $(D_PARAM begin). 133 134 Example: 135 -------------------- 136 Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 137 -------------------- 138 +/ 139 this(U)(scope const TP begin, scope const U end) pure 140 if (is(immutable TP == immutable U)) 141 { 142 if (!_valid(begin, end)) 143 throw new DateTimeException("Arguments would result in an invalid Interval."); 144 _begin = cast(TP) begin; 145 _end = cast(TP) end; 146 } 147 148 149 /++ 150 Params: 151 begin = The time point which begins the interval. 152 duration = The duration from the starting point to the end point. 153 154 Throws: 155 $(REF DateTimeException,std,datetime,date) if the resulting 156 `end` is before `begin`. 157 158 Example: 159 -------------------- 160 assert(Interval!Date(Date(1996, 1, 2), dur!"days"(3)) == 161 Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5))); 162 -------------------- 163 +/ 164 this(D)(scope const TP begin, scope const D duration) pure 165 if (__traits(compiles, begin + duration)) 166 { 167 _begin = cast(TP) begin; 168 _end = begin + duration; 169 if (!_valid(_begin, _end)) 170 throw new DateTimeException("Arguments would result in an invalid Interval."); 171 } 172 173 174 /++ 175 Params: 176 rhs = The $(LREF Interval) to assign to this one. 177 +/ 178 ref Interval opAssign(const ref Interval rhs) pure nothrow 179 { 180 _begin = cast(TP) rhs._begin; 181 _end = cast(TP) rhs._end; 182 return this; 183 } 184 185 186 /++ 187 Params: 188 rhs = The $(LREF Interval) to assign to this one. 189 +/ 190 ref Interval opAssign(Interval rhs) pure nothrow 191 { 192 _begin = cast(TP) rhs._begin; 193 _end = cast(TP) rhs._end; 194 return this; 195 } 196 197 198 /++ 199 The starting point of the interval. It is included in the interval. 200 201 Example: 202 -------------------- 203 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == 204 Date(1996, 1, 2)); 205 -------------------- 206 +/ 207 @property TP begin() const pure nothrow 208 { 209 return cast(TP) _begin; 210 } 211 212 213 /++ 214 The starting point of the interval. It is included in the interval. 215 216 Params: 217 timePoint = The time point to set `begin` to. 218 219 Throws: 220 $(REF DateTimeException,std,datetime,date) if the resulting 221 interval would be invalid. 222 +/ 223 @property void begin(TP timePoint) pure 224 { 225 if (!_valid(timePoint, _end)) 226 throw new DateTimeException("Arguments would result in an invalid Interval."); 227 _begin = timePoint; 228 } 229 230 231 /++ 232 The end point of the interval. It is excluded from the interval. 233 234 Example: 235 -------------------- 236 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == 237 Date(2012, 3, 1)); 238 -------------------- 239 +/ 240 @property TP end() const pure nothrow 241 { 242 return cast(TP) _end; 243 } 244 245 246 /++ 247 The end point of the interval. It is excluded from the interval. 248 249 Params: 250 timePoint = The time point to set end to. 251 252 Throws: 253 $(REF DateTimeException,std,datetime,date) if the resulting 254 interval would be invalid. 255 +/ 256 @property void end(TP timePoint) pure 257 { 258 if (!_valid(_begin, timePoint)) 259 throw new DateTimeException("Arguments would result in an invalid Interval."); 260 _end = timePoint; 261 } 262 263 264 /++ 265 Returns the duration between `begin` and `end`. 266 267 Example: 268 -------------------- 269 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == 270 dur!"days"(5903)); 271 -------------------- 272 +/ 273 @property auto length() const pure nothrow 274 { 275 return _end - _begin; 276 } 277 278 279 /++ 280 Whether the interval's length is 0, that is, whether $(D begin == end). 281 282 Example: 283 -------------------- 284 assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty); 285 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty); 286 -------------------- 287 +/ 288 @property bool empty() const pure nothrow 289 { 290 return _begin == _end; 291 } 292 293 294 /++ 295 Whether the given time point is within this interval. 296 297 Params: 298 timePoint = The time point to check for inclusion in this interval. 299 300 Throws: 301 $(REF DateTimeException,std,datetime,date) if this interval is 302 empty. 303 304 Example: 305 -------------------- 306 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 307 Date(1994, 12, 24))); 308 309 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 310 Date(2000, 1, 5))); 311 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 312 Date(2012, 3, 1))); 313 -------------------- 314 +/ 315 bool contains(scope const TP timePoint) const pure 316 { 317 _enforceNotEmpty(); 318 return timePoint >= _begin && timePoint < _end; 319 } 320 321 322 /++ 323 Whether the given interval is completely within this interval. 324 325 Params: 326 interval = The interval to check for inclusion in this interval. 327 328 Throws: 329 $(REF DateTimeException,std,datetime,date) if either interval is 330 empty. 331 332 Example: 333 -------------------- 334 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 335 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 336 337 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 338 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 339 340 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 341 Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); 342 -------------------- 343 +/ 344 bool contains(scope const Interval interval) const pure 345 { 346 _enforceNotEmpty(); 347 interval._enforceNotEmpty(); 348 return interval._begin >= _begin && 349 interval._begin < _end && 350 interval._end <= _end; 351 } 352 353 354 /++ 355 Whether the given interval is completely within this interval. 356 357 Always returns false (unless this interval is empty), because an 358 interval going to positive infinity can never be contained in a finite 359 interval. 360 361 Params: 362 interval = The interval to check for inclusion in this interval. 363 364 Throws: 365 $(REF DateTimeException,std,datetime,date) if this interval is 366 empty. 367 368 Example: 369 -------------------- 370 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 371 PosInfInterval!Date(Date(1999, 5, 4)))); 372 -------------------- 373 +/ 374 bool contains(scope const PosInfInterval!TP interval) const pure 375 { 376 _enforceNotEmpty(); 377 return false; 378 } 379 380 381 /++ 382 Whether the given interval is completely within this interval. 383 384 Always returns false (unless this interval is empty), because an 385 interval beginning at negative infinity can never be contained in a 386 finite interval. 387 388 Params: 389 interval = The interval to check for inclusion in this interval. 390 391 Throws: 392 $(REF DateTimeException,std,datetime,date) if this interval is 393 empty. 394 395 Example: 396 -------------------- 397 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 398 NegInfInterval!Date(Date(1996, 5, 4)))); 399 -------------------- 400 +/ 401 bool contains(scope const NegInfInterval!TP interval) const pure 402 { 403 _enforceNotEmpty(); 404 return false; 405 } 406 407 408 /++ 409 Whether this interval is before the given time point. 410 411 Params: 412 timePoint = The time point to check whether this interval is before 413 it. 414 415 Throws: 416 $(REF DateTimeException,std,datetime,date) if this interval is 417 empty. 418 419 Example: 420 -------------------- 421 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 422 Date(1994, 12, 24))); 423 424 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 425 Date(2000, 1, 5))); 426 427 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 428 Date(2012, 3, 1))); 429 -------------------- 430 +/ 431 bool isBefore(scope const TP timePoint) const pure 432 { 433 _enforceNotEmpty(); 434 return _end <= timePoint; 435 } 436 437 438 /++ 439 Whether this interval is before the given interval and does not 440 intersect with it. 441 442 Params: 443 interval = The interval to check for against this interval. 444 445 Throws: 446 $(REF DateTimeException,std,datetime,date) if either interval is 447 empty. 448 449 Example: 450 -------------------- 451 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 452 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 453 454 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 455 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 456 457 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 458 Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1)))); 459 -------------------- 460 +/ 461 bool isBefore(scope const Interval interval) const pure 462 { 463 _enforceNotEmpty(); 464 interval._enforceNotEmpty(); 465 return _end <= interval._begin; 466 } 467 468 469 /++ 470 Whether this interval is before the given interval and does not 471 intersect with it. 472 473 Params: 474 interval = The interval to check for against this interval. 475 476 Throws: 477 $(REF DateTimeException,std,datetime,date) if this interval is 478 empty. 479 480 Example: 481 -------------------- 482 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 483 PosInfInterval!Date(Date(1999, 5, 4)))); 484 485 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 486 PosInfInterval!Date(Date(2013, 3, 7)))); 487 -------------------- 488 +/ 489 bool isBefore(scope const PosInfInterval!TP interval) const pure 490 { 491 _enforceNotEmpty(); 492 return _end <= interval._begin; 493 } 494 495 496 /++ 497 Whether this interval is before the given interval and does not 498 intersect with it. 499 500 Always returns false (unless this interval is empty) because a finite 501 interval can never be before an interval beginning at negative infinity. 502 503 Params: 504 interval = The interval to check for against this interval. 505 506 Throws: 507 $(REF DateTimeException,std,datetime,date) if this interval is 508 empty. 509 510 Example: 511 -------------------- 512 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 513 NegInfInterval!Date(Date(1996, 5, 4)))); 514 -------------------- 515 +/ 516 bool isBefore(scope const NegInfInterval!TP interval) const pure 517 { 518 _enforceNotEmpty(); 519 return false; 520 } 521 522 523 /++ 524 Whether this interval is after the given time point. 525 526 Params: 527 timePoint = The time point to check whether this interval is after 528 it. 529 530 Throws: 531 $(REF DateTimeException,std,datetime,date) if this interval is 532 empty. 533 534 Example: 535 -------------------- 536 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 537 Date(1994, 12, 24))); 538 539 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 540 Date(2000, 1, 5))); 541 542 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 543 Date(2012, 3, 1))); 544 -------------------- 545 +/ 546 bool isAfter(scope const TP timePoint) const pure 547 { 548 _enforceNotEmpty(); 549 return timePoint < _begin; 550 } 551 552 553 /++ 554 Whether this interval is after the given interval and does not intersect 555 it. 556 557 Params: 558 interval = The interval to check against this interval. 559 560 Throws: 561 $(REF DateTimeException,std,datetime,date) if either interval is 562 empty. 563 564 Example: 565 -------------------- 566 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 567 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 568 569 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 570 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 571 572 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 573 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 574 -------------------- 575 +/ 576 bool isAfter(scope const Interval interval) const pure 577 { 578 _enforceNotEmpty(); 579 interval._enforceNotEmpty(); 580 return _begin >= interval._end; 581 } 582 583 584 /++ 585 Whether this interval is after the given interval and does not intersect 586 it. 587 588 Always returns false (unless this interval is empty) because a finite 589 interval can never be after an interval going to positive infinity. 590 591 Params: 592 interval = The interval to check against this interval. 593 594 Throws: 595 $(REF DateTimeException,std,datetime,date) if this interval is 596 empty. 597 598 Example: 599 -------------------- 600 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 601 PosInfInterval!Date(Date(1999, 5, 4)))); 602 -------------------- 603 +/ 604 bool isAfter(scope const PosInfInterval!TP interval) const pure 605 { 606 _enforceNotEmpty(); 607 return false; 608 } 609 610 611 /++ 612 Whether this interval is after the given interval and does not intersect 613 it. 614 615 Params: 616 interval = The interval to check against this interval. 617 618 Throws: 619 $(REF DateTimeException,std,datetime,date) if this interval is 620 empty. 621 622 Example: 623 -------------------- 624 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 625 NegInfInterval!Date(Date(1996, 1, 2)))); 626 -------------------- 627 +/ 628 bool isAfter(scope const NegInfInterval!TP interval) const pure 629 { 630 _enforceNotEmpty(); 631 return _begin >= interval._end; 632 } 633 634 635 /++ 636 Whether the given interval overlaps this interval. 637 638 Params: 639 interval = The interval to check for intersection with this interval. 640 641 Throws: 642 $(REF DateTimeException,std,datetime,date) if either interval is 643 empty. 644 645 Example: 646 -------------------- 647 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 648 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 649 650 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 651 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 652 653 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 654 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 655 -------------------- 656 +/ 657 bool intersects(scope const Interval interval) const pure 658 { 659 _enforceNotEmpty(); 660 interval._enforceNotEmpty(); 661 return interval._begin < _end && interval._end > _begin; 662 } 663 664 665 /++ 666 Whether the given interval overlaps this interval. 667 668 Params: 669 interval = The interval to check for intersection with this interval. 670 671 Throws: 672 $(REF DateTimeException,std,datetime,date) if this interval is 673 empty. 674 675 Example: 676 -------------------- 677 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 678 PosInfInterval!Date(Date(1999, 5, 4)))); 679 680 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 681 PosInfInterval!Date(Date(2012, 3, 1)))); 682 -------------------- 683 +/ 684 bool intersects(scope const PosInfInterval!TP interval) const pure 685 { 686 _enforceNotEmpty(); 687 return _end > interval._begin; 688 } 689 690 691 /++ 692 Whether the given interval overlaps this interval. 693 694 Params: 695 interval = The interval to check for intersection with this interval. 696 697 Throws: 698 $(REF DateTimeException,std,datetime,date) if this interval is 699 empty. 700 701 Example: 702 -------------------- 703 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 704 NegInfInterval!Date(Date(1996, 1, 2)))); 705 706 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 707 NegInfInterval!Date(Date(2000, 1, 2)))); 708 -------------------- 709 +/ 710 bool intersects(scope const NegInfInterval!TP interval) const pure 711 { 712 _enforceNotEmpty(); 713 return _begin < interval._end; 714 } 715 716 717 /++ 718 Returns the intersection of two intervals 719 720 Params: 721 interval = The interval to intersect with this interval. 722 723 Throws: 724 $(REF DateTimeException,std,datetime,date) if the two intervals do 725 not intersect or if either interval is empty. 726 727 Example: 728 -------------------- 729 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 730 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 731 Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); 732 733 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 734 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 735 Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); 736 -------------------- 737 +/ 738 Interval intersection(scope const Interval interval) const 739 { 740 import std.format : format; 741 742 enforce(this.intersects(interval), 743 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 744 745 auto begin = _begin > interval._begin ? _begin : interval._begin; 746 auto end = _end < interval._end ? _end : interval._end; 747 748 return Interval(begin, end); 749 } 750 751 752 /++ 753 Returns the intersection of two intervals 754 755 Params: 756 interval = The interval to intersect with this interval. 757 758 Throws: 759 $(REF DateTimeException,std,datetime,date) if the two intervals do 760 not intersect or if this interval is empty. 761 762 Example: 763 -------------------- 764 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 765 PosInfInterval!Date(Date(1990, 7, 6))) == 766 Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); 767 768 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 769 PosInfInterval!Date(Date(1999, 1, 12))) == 770 Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); 771 -------------------- 772 +/ 773 Interval intersection(scope const PosInfInterval!TP interval) const 774 { 775 import std.format : format; 776 777 enforce(this.intersects(interval), 778 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 779 780 return Interval(_begin > interval._begin ? _begin : interval._begin, _end); 781 } 782 783 784 /++ 785 Returns the intersection of two intervals 786 787 Params: 788 interval = The interval to intersect with this interval. 789 790 Throws: 791 $(REF DateTimeException,std,datetime,date) if the two intervals do 792 not intersect or if this interval is empty. 793 794 Example: 795 -------------------- 796 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 797 NegInfInterval!Date(Date(1999, 7, 6))) == 798 Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); 799 800 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 801 NegInfInterval!Date(Date(2013, 1, 12))) == 802 Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); 803 -------------------- 804 +/ 805 Interval intersection(scope const NegInfInterval!TP interval) const 806 { 807 import std.format : format; 808 809 enforce(this.intersects(interval), 810 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 811 812 return Interval(_begin, _end < interval._end ? _end : interval._end); 813 } 814 815 816 /++ 817 Whether the given interval is adjacent to this interval. 818 819 Params: 820 interval = The interval to check whether its adjecent to this 821 interval. 822 823 Throws: 824 $(REF DateTimeException,std,datetime,date) if either interval is 825 empty. 826 827 Example: 828 -------------------- 829 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 830 Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2)))); 831 832 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 833 Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17)))); 834 835 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 836 Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1)))); 837 -------------------- 838 +/ 839 bool isAdjacent(scope const Interval interval) const pure 840 { 841 _enforceNotEmpty(); 842 interval._enforceNotEmpty(); 843 return _begin == interval._end || _end == interval._begin; 844 } 845 846 847 /++ 848 Whether the given interval is adjacent to this interval. 849 850 Params: 851 interval = The interval to check whether its adjecent to this 852 interval. 853 854 Throws: 855 $(REF DateTimeException,std,datetime,date) if this interval is 856 empty. 857 858 Example: 859 -------------------- 860 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 861 PosInfInterval!Date(Date(1999, 5, 4)))); 862 863 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 864 PosInfInterval!Date(Date(2012, 3, 1)))); 865 -------------------- 866 +/ 867 bool isAdjacent(scope const PosInfInterval!TP interval) const pure 868 { 869 _enforceNotEmpty(); 870 return _end == interval._begin; 871 } 872 873 874 /++ 875 Whether the given interval is adjacent to this interval. 876 877 Params: 878 interval = The interval to check whether its adjecent to this 879 interval. 880 881 Throws: 882 $(REF DateTimeException,std,datetime,date) if this interval is 883 empty. 884 885 Example: 886 -------------------- 887 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 888 NegInfInterval!Date(Date(1996, 1, 2)))); 889 890 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 891 NegInfInterval!Date(Date(2000, 1, 2)))); 892 -------------------- 893 +/ 894 bool isAdjacent(scope const NegInfInterval!TP interval) const pure 895 { 896 _enforceNotEmpty(); 897 return _begin == interval._end; 898 } 899 900 901 /++ 902 Returns the union of two intervals 903 904 Params: 905 interval = The interval to merge with this interval. 906 907 Throws: 908 $(REF DateTimeException,std,datetime,date) if the two intervals do 909 not intersect and are not adjacent or if either interval is empty. 910 911 Example: 912 -------------------- 913 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( 914 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 915 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); 916 917 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( 918 Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == 919 Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); 920 -------------------- 921 +/ 922 Interval merge(scope const Interval interval) const 923 { 924 import std.format : format; 925 926 enforce(this.isAdjacent(interval) || this.intersects(interval), 927 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); 928 929 auto begin = _begin < interval._begin ? _begin : interval._begin; 930 auto end = _end > interval._end ? _end : interval._end; 931 932 return Interval(begin, end); 933 } 934 935 936 /++ 937 Returns the union of two intervals 938 939 Params: 940 interval = The interval to merge with this interval. 941 942 Throws: 943 $(REF DateTimeException,std,datetime,date) if the two intervals do 944 not intersect and are not adjacent or if this interval is empty. 945 946 Example: 947 -------------------- 948 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( 949 PosInfInterval!Date(Date(1990, 7, 6))) == 950 PosInfInterval!Date(Date(1990, 7 , 6))); 951 952 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( 953 PosInfInterval!Date(Date(2012, 3, 1))) == 954 PosInfInterval!Date(Date(1996, 1 , 2))); 955 -------------------- 956 +/ 957 PosInfInterval!TP merge(scope const PosInfInterval!TP interval) const 958 { 959 import std.format : format; 960 961 enforce(this.isAdjacent(interval) || this.intersects(interval), 962 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); 963 964 return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin); 965 } 966 967 968 /++ 969 Returns the union of two intervals 970 971 Params: 972 interval = The interval to merge with this interval. 973 974 Throws: 975 $(REF DateTimeException,std,datetime,date) if the two intervals do 976 not intersect and are not adjacent or if this interval is empty. 977 978 Example: 979 -------------------- 980 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( 981 NegInfInterval!Date(Date(1996, 1, 2))) == 982 NegInfInterval!Date(Date(2012, 3 , 1))); 983 984 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( 985 NegInfInterval!Date(Date(2013, 1, 12))) == 986 NegInfInterval!Date(Date(2013, 1 , 12))); 987 -------------------- 988 +/ 989 NegInfInterval!TP merge(scope const NegInfInterval!TP interval) const 990 { 991 import std.format : format; 992 993 enforce(this.isAdjacent(interval) || this.intersects(interval), 994 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); 995 996 return NegInfInterval!TP(_end > interval._end ? _end : interval._end); 997 } 998 999 1000 /++ 1001 Returns an interval that covers from the earliest time point of two 1002 intervals up to (but not including) the latest time point of two 1003 intervals. 1004 1005 Params: 1006 interval = The interval to create a span together with this interval. 1007 1008 Throws: 1009 $(REF DateTimeException,std,datetime,date) if either interval is 1010 empty. 1011 1012 Example: 1013 -------------------- 1014 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( 1015 Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) == 1016 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); 1017 1018 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( 1019 Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == 1020 Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); 1021 -------------------- 1022 +/ 1023 Interval span(scope const Interval interval) const pure 1024 { 1025 _enforceNotEmpty(); 1026 interval._enforceNotEmpty(); 1027 1028 auto begin = _begin < interval._begin ? _begin : interval._begin; 1029 auto end = _end > interval._end ? _end : interval._end; 1030 1031 return Interval(begin, end); 1032 } 1033 1034 1035 /++ 1036 Returns an interval that covers from the earliest time point of two 1037 intervals up to (but not including) the latest time point of two 1038 intervals. 1039 1040 Params: 1041 interval = The interval to create a span together with this interval. 1042 1043 Throws: 1044 $(REF DateTimeException,std,datetime,date) if this interval is 1045 empty. 1046 1047 Example: 1048 -------------------- 1049 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( 1050 PosInfInterval!Date(Date(1990, 7, 6))) == 1051 PosInfInterval!Date(Date(1990, 7 , 6))); 1052 1053 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( 1054 PosInfInterval!Date(Date(2050, 1, 1))) == 1055 PosInfInterval!Date(Date(1996, 1 , 2))); 1056 -------------------- 1057 +/ 1058 PosInfInterval!TP span(scope const PosInfInterval!TP interval) const pure 1059 { 1060 _enforceNotEmpty(); 1061 return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin); 1062 } 1063 1064 1065 /++ 1066 Returns an interval that covers from the earliest time point of two 1067 intervals up to (but not including) the latest time point of two 1068 intervals. 1069 1070 Params: 1071 interval = The interval to create a span together with this interval. 1072 1073 Throws: 1074 $(REF DateTimeException,std,datetime,date) if this interval is 1075 empty. 1076 1077 Example: 1078 -------------------- 1079 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( 1080 NegInfInterval!Date(Date(1602, 5, 21))) == 1081 NegInfInterval!Date(Date(2012, 3 , 1))); 1082 1083 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( 1084 NegInfInterval!Date(Date(2013, 1, 12))) == 1085 NegInfInterval!Date(Date(2013, 1 , 12))); 1086 -------------------- 1087 +/ 1088 NegInfInterval!TP span(scope const NegInfInterval!TP interval) const pure 1089 { 1090 _enforceNotEmpty(); 1091 return NegInfInterval!TP(_end > interval._end ? _end : interval._end); 1092 } 1093 1094 1095 /++ 1096 Shifts the interval forward or backwards in time by the given duration 1097 (a positive duration shifts the interval forward; a negative duration 1098 shifts it backward). Effectively, it does $(D begin += duration) and 1099 $(D end += duration). 1100 1101 Params: 1102 duration = The duration to shift the interval by. 1103 1104 Throws: 1105 $(REF DateTimeException,std,datetime,date) this interval is empty 1106 or if the resulting interval would be invalid. 1107 1108 Example: 1109 -------------------- 1110 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); 1111 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); 1112 1113 interval1.shift(dur!"days"(50)); 1114 assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25))); 1115 1116 interval2.shift(dur!"days"(-50)); 1117 assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15))); 1118 -------------------- 1119 +/ 1120 void shift(D)(D duration) pure 1121 if (__traits(compiles, begin + duration)) 1122 { 1123 _enforceNotEmpty(); 1124 1125 auto begin = _begin + duration; 1126 auto end = _end + duration; 1127 1128 if (!_valid(begin, end)) 1129 throw new DateTimeException("Argument would result in an invalid Interval."); 1130 1131 _begin = begin; 1132 _end = end; 1133 } 1134 1135 1136 static if (__traits(compiles, begin.add!"months"(1)) && 1137 __traits(compiles, begin.add!"years"(1))) 1138 { 1139 /++ 1140 Shifts the interval forward or backwards in time by the given number 1141 of years and/or months (a positive number of years and months shifts 1142 the interval forward; a negative number shifts it backward). 1143 It adds the years the given years and months to both begin and end. 1144 It effectively calls `add!"years"()` and then `add!"months"()` 1145 on begin and end with the given number of years and months. 1146 1147 Params: 1148 years = The number of years to shift the interval by. 1149 months = The number of months to shift the interval by. 1150 allowOverflow = Whether the days should be allowed to overflow 1151 on `begin` and `end`, causing their month 1152 to increment. 1153 1154 Throws: 1155 $(REF DateTimeException,std,datetime,date) if this interval is 1156 empty or if the resulting interval would be invalid. 1157 1158 Example: 1159 -------------------- 1160 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1161 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1162 1163 interval1.shift(2); 1164 assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1))); 1165 1166 interval2.shift(-2); 1167 assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1))); 1168 -------------------- 1169 +/ 1170 void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) 1171 if (isIntegral!T) 1172 { 1173 _enforceNotEmpty(); 1174 1175 auto begin = _begin; 1176 auto end = _end; 1177 1178 begin.add!"years"(years, allowOverflow); 1179 begin.add!"months"(months, allowOverflow); 1180 end.add!"years"(years, allowOverflow); 1181 end.add!"months"(months, allowOverflow); 1182 1183 enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval.")); 1184 1185 _begin = begin; 1186 _end = end; 1187 } 1188 } 1189 1190 1191 /++ 1192 Expands the interval forwards and/or backwards in time. Effectively, 1193 it does $(D begin -= duration) and/or $(D end += duration). Whether 1194 it expands forwards and/or backwards in time is determined by 1195 $(D_PARAM dir). 1196 1197 Params: 1198 duration = The duration to expand the interval by. 1199 dir = The direction in time to expand the interval. 1200 1201 Throws: 1202 $(REF DateTimeException,std,datetime,date) this interval is empty 1203 or if the resulting interval would be invalid. 1204 1205 Example: 1206 -------------------- 1207 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1208 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1209 1210 interval1.expand(2); 1211 assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); 1212 1213 interval2.expand(-2); 1214 assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); 1215 -------------------- 1216 +/ 1217 void expand(D)(D duration, Direction dir = Direction.both) pure 1218 if (__traits(compiles, begin + duration)) 1219 { 1220 _enforceNotEmpty(); 1221 1222 switch (dir) 1223 { 1224 case Direction.both: 1225 { 1226 auto begin = _begin - duration; 1227 auto end = _end + duration; 1228 1229 if (!_valid(begin, end)) 1230 throw new DateTimeException("Argument would result in an invalid Interval."); 1231 1232 _begin = begin; 1233 _end = end; 1234 1235 return; 1236 } 1237 case Direction.fwd: 1238 { 1239 auto end = _end + duration; 1240 1241 if (!_valid(_begin, end)) 1242 throw new DateTimeException("Argument would result in an invalid Interval."); 1243 _end = end; 1244 1245 return; 1246 } 1247 case Direction.bwd: 1248 { 1249 auto begin = _begin - duration; 1250 1251 if (!_valid(begin, _end)) 1252 throw new DateTimeException("Argument would result in an invalid Interval."); 1253 _begin = begin; 1254 1255 return; 1256 } 1257 default: 1258 assert(0, "Invalid Direction."); 1259 } 1260 } 1261 1262 static if (__traits(compiles, begin.add!"months"(1)) && 1263 __traits(compiles, begin.add!"years"(1))) 1264 { 1265 /++ 1266 Expands the interval forwards and/or backwards in time. Effectively, 1267 it subtracts the given number of months/years from `begin` and 1268 adds them to `end`. Whether it expands forwards and/or backwards 1269 in time is determined by $(D_PARAM dir). 1270 1271 Params: 1272 years = The number of years to expand the interval by. 1273 months = The number of months to expand the interval by. 1274 allowOverflow = Whether the days should be allowed to overflow 1275 on `begin` and `end`, causing their month 1276 to increment. 1277 dir = The direction in time to expand the interval. 1278 1279 Throws: 1280 $(REF DateTimeException,std,datetime,date) if this interval is 1281 empty or if the resulting interval would be invalid. 1282 1283 Example: 1284 -------------------- 1285 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1286 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1287 1288 interval1.expand(2); 1289 assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); 1290 1291 interval2.expand(-2); 1292 assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); 1293 -------------------- 1294 +/ 1295 void expand(T)(T years, 1296 T months = 0, 1297 AllowDayOverflow allowOverflow = AllowDayOverflow.yes, 1298 Direction dir = Direction.both) 1299 if (isIntegral!T) 1300 { 1301 _enforceNotEmpty(); 1302 1303 switch (dir) 1304 { 1305 case Direction.both: 1306 { 1307 auto begin = _begin; 1308 auto end = _end; 1309 1310 begin.add!"years"(-years, allowOverflow); 1311 begin.add!"months"(-months, allowOverflow); 1312 end.add!"years"(years, allowOverflow); 1313 end.add!"months"(months, allowOverflow); 1314 1315 enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval.")); 1316 _begin = begin; 1317 _end = end; 1318 1319 return; 1320 } 1321 case Direction.fwd: 1322 { 1323 auto end = _end; 1324 1325 end.add!"years"(years, allowOverflow); 1326 end.add!"months"(months, allowOverflow); 1327 1328 enforce(_valid(_begin, end), 1329 new DateTimeException("Argument would result in an invalid Interval.")); 1330 _end = end; 1331 1332 return; 1333 } 1334 case Direction.bwd: 1335 { 1336 auto begin = _begin; 1337 1338 begin.add!"years"(-years, allowOverflow); 1339 begin.add!"months"(-months, allowOverflow); 1340 1341 enforce(_valid(begin, _end), 1342 new DateTimeException("Argument would result in an invalid Interval.")); 1343 _begin = begin; 1344 1345 return; 1346 } 1347 default: 1348 assert(0, "Invalid Direction."); 1349 } 1350 } 1351 } 1352 1353 1354 /++ 1355 Returns a range which iterates forward over the interval, starting 1356 at `begin`, using $(D_PARAM func) to generate each successive time 1357 point. 1358 1359 The range's `front` is the interval's `begin`. $(D_PARAM func) is 1360 used to generate the next `front` when `popFront` is called. If 1361 $(D_PARAM popFirst) is `PopFirst.yes`, then `popFront` is called 1362 before the range is returned (so that `front` is a time point which 1363 $(D_PARAM func) would generate). 1364 1365 If $(D_PARAM func) ever generates a time point less than or equal to the 1366 current `front` of the range, then a 1367 $(REF DateTimeException,std,datetime,date) will be thrown. The range 1368 will be empty and iteration complete when $(D_PARAM func) generates a 1369 time point equal to or beyond the `end` of the interval. 1370 1371 There are helper functions in this module which generate common 1372 delegates to pass to `fwdRange`. Their documentation starts with 1373 "Range-generating function," making them easily searchable. 1374 1375 Params: 1376 func = The function used to generate the time points of the 1377 range over the interval. 1378 popFirst = Whether `popFront` should be called on the range 1379 before returning it. 1380 1381 Throws: 1382 $(REF DateTimeException,std,datetime,date) if this interval is 1383 empty. 1384 1385 Warning: 1386 $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) 1387 would be a function pointer to a pure function, but forcing 1388 $(D_PARAM func) to be pure is far too restrictive to be useful, and 1389 in order to have the ease of use of having functions which generate 1390 functions to pass to `fwdRange`, $(D_PARAM func) must be a 1391 delegate. 1392 1393 If $(D_PARAM func) retains state which changes as it is called, then 1394 some algorithms will not work correctly, because the range's 1395 `save` will have failed to have really saved the range's state. 1396 To avoid such bugs, don't pass a delegate which is 1397 not logically pure to `fwdRange`. If $(D_PARAM func) is given the 1398 same time point with two different calls, it must return the same 1399 result both times. 1400 1401 Of course, none of the functions in this module have this problem, 1402 so it's only relevant if when creating a custom delegate. 1403 1404 Example: 1405 -------------------- 1406 auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); 1407 auto func = delegate (scope const Date date) // For iterating over even-numbered days. 1408 { 1409 if ((date.day & 1) == 0) 1410 return date + dur!"days"(2); 1411 1412 return date + dur!"days"(1); 1413 }; 1414 auto range = interval.fwdRange(func); 1415 1416 // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). 1417 assert(range.front == Date(2010, 9, 1)); 1418 1419 range.popFront(); 1420 assert(range.front == Date(2010, 9, 2)); 1421 1422 range.popFront(); 1423 assert(range.front == Date(2010, 9, 4)); 1424 1425 range.popFront(); 1426 assert(range.front == Date(2010, 9, 6)); 1427 1428 range.popFront(); 1429 assert(range.front == Date(2010, 9, 8)); 1430 1431 range.popFront(); 1432 assert(range.empty); 1433 -------------------- 1434 +/ 1435 IntervalRange!(TP, Direction.fwd) fwdRange(TP delegate(scope const TP) func, PopFirst popFirst = PopFirst.no) const 1436 { 1437 _enforceNotEmpty(); 1438 1439 auto range = IntervalRange!(TP, Direction.fwd)(this, func); 1440 1441 if (popFirst == PopFirst.yes) 1442 range.popFront(); 1443 1444 return range; 1445 } 1446 1447 1448 /++ 1449 Returns a range which iterates backwards over the interval, starting 1450 at `end`, using $(D_PARAM func) to generate each successive time 1451 point. 1452 1453 The range's `front` is the interval's `end`. $(D_PARAM func) is 1454 used to generate the next `front` when `popFront` is called. If 1455 $(D_PARAM popFirst) is `PopFirst.yes`, then `popFront` is called 1456 before the range is returned (so that `front` is a time point which 1457 $(D_PARAM func) would generate). 1458 1459 If $(D_PARAM func) ever generates a time point greater than or equal to 1460 the current `front` of the range, then a 1461 $(REF DateTimeException,std,datetime,date) will be thrown. The range 1462 will be empty and iteration complete when $(D_PARAM func) generates a 1463 time point equal to or less than the `begin` of the interval. 1464 1465 There are helper functions in this module which generate common 1466 delegates to pass to `bwdRange`. Their documentation starts with 1467 "Range-generating function," making them easily searchable. 1468 1469 Params: 1470 func = The function used to generate the time points of the 1471 range over the interval. 1472 popFirst = Whether `popFront` should be called on the range 1473 before returning it. 1474 1475 Throws: 1476 $(REF DateTimeException,std,datetime,date) if this interval is 1477 empty. 1478 1479 Warning: 1480 $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) 1481 would be a function pointer to a pure function, but forcing 1482 $(D_PARAM func) to be pure is far too restrictive to be useful, and 1483 in order to have the ease of use of having functions which generate 1484 functions to pass to `fwdRange`, $(D_PARAM func) must be a 1485 delegate. 1486 1487 If $(D_PARAM func) retains state which changes as it is called, then 1488 some algorithms will not work correctly, because the range's 1489 `save` will have failed to have really saved the range's state. 1490 To avoid such bugs, don't pass a delegate which is 1491 not logically pure to `fwdRange`. If $(D_PARAM func) is given the 1492 same time point with two different calls, it must return the same 1493 result both times. 1494 1495 Of course, none of the functions in this module have this problem, 1496 so it's only relevant for custom delegates. 1497 1498 Example: 1499 -------------------- 1500 auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); 1501 auto func = delegate (scope const Date date) // For iterating over even-numbered days. 1502 { 1503 if ((date.day & 1) == 0) 1504 return date - dur!"days"(2); 1505 1506 return date - dur!"days"(1); 1507 }; 1508 auto range = interval.bwdRange(func); 1509 1510 // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). 1511 assert(range.front == Date(2010, 9, 9)); 1512 1513 range.popFront(); 1514 assert(range.front == Date(2010, 9, 8)); 1515 1516 range.popFront(); 1517 assert(range.front == Date(2010, 9, 6)); 1518 1519 range.popFront(); 1520 assert(range.front == Date(2010, 9, 4)); 1521 1522 range.popFront(); 1523 assert(range.front == Date(2010, 9, 2)); 1524 1525 range.popFront(); 1526 assert(range.empty); 1527 -------------------- 1528 +/ 1529 IntervalRange!(TP, Direction.bwd) bwdRange(TP delegate(scope const TP) func, PopFirst popFirst = PopFirst.no) const 1530 { 1531 _enforceNotEmpty(); 1532 1533 auto range = IntervalRange!(TP, Direction.bwd)(this, func); 1534 1535 if (popFirst == PopFirst.yes) 1536 range.popFront(); 1537 1538 return range; 1539 } 1540 1541 /++ 1542 Converts this interval to a string. 1543 Params: 1544 w = A `char` accepting 1545 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 1546 Returns: 1547 A `string` when not using an output range; `void` otherwise. 1548 +/ 1549 string toString() const @safe nothrow 1550 { 1551 import std.array : appender; 1552 auto app = appender!string(); 1553 try 1554 toString(app); 1555 catch (Exception e) 1556 assert(0, "toString() threw."); 1557 return app.data; 1558 } 1559 1560 /// ditto 1561 void toString(Writer)(ref Writer w) const 1562 if (isOutputRange!(Writer, char)) 1563 { 1564 import std.range.primitives : put; 1565 put(w, '['); 1566 _begin.toString(w); 1567 put(w, " - "); 1568 _end.toString(w); 1569 put(w, ')'); 1570 } 1571 1572 private: 1573 /+ 1574 Throws: 1575 $(REF DateTimeException,std,datetime,date) if this interval is 1576 empty. 1577 +/ 1578 void _enforceNotEmpty(size_t line = __LINE__) const pure 1579 { 1580 if (empty) 1581 throw new DateTimeException("Invalid operation for an empty Interval.", __FILE__, line); 1582 } 1583 1584 1585 /+ 1586 Whether the given values form a valid time interval. 1587 1588 Params: 1589 begin = The starting point of the interval. 1590 end = The end point of the interval. 1591 +/ 1592 static bool _valid(scope const TP begin, scope const TP end) pure nothrow @trusted 1593 { 1594 return begin <= end; 1595 } 1596 1597 1598 pure invariant() 1599 { 1600 assert(_valid(_begin, _end), "Invariant Failure: begin is not before or equal to end."); 1601 } 1602 1603 1604 TP _begin; 1605 TP _end; 1606 } 1607 1608 // Test Interval's constructors. 1609 @safe unittest 1610 { 1611 import std.datetime.date; 1612 import std.datetime.systime; 1613 1614 assertThrown!DateTimeException(Interval!Date(Date(2010, 1, 1), Date(1, 1, 1))); 1615 1616 Interval!Date(Date.init, Date.init); 1617 Interval!TimeOfDay(TimeOfDay.init, TimeOfDay.init); 1618 Interval!DateTime(DateTime.init, DateTime.init); 1619 Interval!SysTime(SysTime(0), SysTime(0)); 1620 1621 Interval!DateTime(DateTime.init, dur!"days"(7)); 1622 1623 // Verify Examples. 1624 Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 1625 assert(Interval!Date(Date(1996, 1, 2), dur!"weeks"(3)) == Interval!Date(Date(1996, 1, 2), Date(1996, 1, 23))); 1626 assert(Interval!Date(Date(1996, 1, 2), dur!"days"(3)) == Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5))); 1627 assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"hours"(3)) == 1628 Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 15, 0, 0))); 1629 assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"minutes"(3)) == 1630 Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 3, 0))); 1631 assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"seconds"(3)) == 1632 Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3))); 1633 assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"msecs"(3000)) == 1634 Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3))); 1635 } 1636 1637 // Test Interval's begin. 1638 @safe unittest 1639 { 1640 import std.datetime.date; 1641 1642 assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).begin == Date(1, 1, 1)); 1643 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).begin == Date(2010, 1, 1)); 1644 assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).begin == Date(1997, 12, 31)); 1645 1646 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1647 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1648 assert(cInterval.begin == Date(2010, 7, 4)); 1649 assert(iInterval.begin == Date(2010, 7, 4)); 1650 1651 // Verify Examples. 1652 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == Date(1996, 1, 2)); 1653 } 1654 1655 // Test Interval's end. 1656 @safe unittest 1657 { 1658 import std.datetime.date; 1659 1660 assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1)); 1661 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1)); 1662 assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).end == Date(1998, 1, 1)); 1663 1664 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1665 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1666 assert(cInterval.end == Date(2012, 1, 7)); 1667 assert(iInterval.end == Date(2012, 1, 7)); 1668 1669 // Verify Examples. 1670 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == Date(2012, 3, 1)); 1671 } 1672 1673 // Test Interval's length. 1674 @safe unittest 1675 { 1676 import std.datetime.date; 1677 import std.datetime.systime; 1678 1679 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).length == dur!"days"(0)); 1680 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).length == dur!"days"(90)); 1681 assert(Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).length == dur!"seconds"(42_727)); 1682 assert(Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).length == 1683 dur!"seconds"(129_127)); 1684 assert(Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)),SysTime(DateTime(2010, 1, 2, 12, 22, 7))).length == 1685 dur!"seconds"(129_127)); 1686 1687 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1688 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1689 assert(cInterval.length != Duration.zero); 1690 assert(iInterval.length != Duration.zero); 1691 1692 // Verify Examples. 1693 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == dur!"days"(5903)); 1694 } 1695 1696 // Test Interval's empty. 1697 @safe unittest 1698 { 1699 import std.datetime.date; 1700 import std.datetime.systime; 1701 1702 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).empty); 1703 assert(!Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).empty); 1704 assert(!Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).empty); 1705 assert(!Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).empty); 1706 assert(!Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)), SysTime(DateTime(2010, 1, 2, 12, 22, 7))).empty); 1707 1708 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1709 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1710 assert(!cInterval.empty); 1711 assert(!iInterval.empty); 1712 1713 // Verify Examples. 1714 assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty); 1715 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty); 1716 } 1717 1718 // Test Interval's contains(time point). 1719 @safe unittest 1720 { 1721 import std.datetime.date; 1722 1723 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1724 1725 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(Date(2010, 7, 4))); 1726 1727 assert(!interval.contains(Date(2009, 7, 4))); 1728 assert(!interval.contains(Date(2010, 7, 3))); 1729 assert(interval.contains(Date(2010, 7, 4))); 1730 assert(interval.contains(Date(2010, 7, 5))); 1731 assert(interval.contains(Date(2011, 7, 1))); 1732 assert(interval.contains(Date(2012, 1, 6))); 1733 assert(!interval.contains(Date(2012, 1, 7))); 1734 assert(!interval.contains(Date(2012, 1, 8))); 1735 assert(!interval.contains(Date(2013, 1, 7))); 1736 1737 const cdate = Date(2010, 7, 6); 1738 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1739 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1740 assert(interval.contains(cdate)); 1741 assert(cInterval.contains(cdate)); 1742 assert(iInterval.contains(cdate)); 1743 1744 // Verify Examples. 1745 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(1994, 12, 24))); 1746 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2000, 1, 5))); 1747 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2012, 3, 1))); 1748 } 1749 1750 // Test Interval's contains(Interval). 1751 @safe unittest 1752 { 1753 import std.datetime.date; 1754 1755 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1756 1757 assertThrown!DateTimeException(interval.contains(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 1758 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(interval)); 1759 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4),dur!"days"(0)).contains( 1760 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 1761 1762 assert(interval.contains(interval)); 1763 assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 1764 assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 1765 assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 1766 assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 1767 assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 1768 assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 1769 assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 1770 assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 1771 assert(interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 1772 assert(!interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 1773 assert(!interval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 1774 assert(!interval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 1775 1776 assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).contains(interval)); 1777 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).contains(interval)); 1778 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).contains(interval)); 1779 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).contains(interval)); 1780 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).contains(interval)); 1781 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).contains(interval)); 1782 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).contains(interval)); 1783 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).contains(interval)); 1784 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).contains(interval)); 1785 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).contains(interval)); 1786 assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).contains(interval)); 1787 assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).contains(interval)); 1788 1789 assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 3)))); 1790 assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 4)))); 1791 assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 5)))); 1792 assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 6)))); 1793 assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 7)))); 1794 assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 8)))); 1795 1796 assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 3)))); 1797 assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 4)))); 1798 assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 5)))); 1799 assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 6)))); 1800 assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 7)))); 1801 assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 8)))); 1802 1803 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1804 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1805 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 1806 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 1807 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 1808 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 1809 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 1810 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 1811 assert(interval.contains(interval)); 1812 assert(interval.contains(cInterval)); 1813 assert(interval.contains(iInterval)); 1814 assert(!interval.contains(posInfInterval)); 1815 assert(!interval.contains(cPosInfInterval)); 1816 assert(!interval.contains(iPosInfInterval)); 1817 assert(!interval.contains(negInfInterval)); 1818 assert(!interval.contains(cNegInfInterval)); 1819 assert(!interval.contains(iNegInfInterval)); 1820 assert(cInterval.contains(interval)); 1821 assert(cInterval.contains(cInterval)); 1822 assert(cInterval.contains(iInterval)); 1823 assert(!cInterval.contains(posInfInterval)); 1824 assert(!cInterval.contains(cPosInfInterval)); 1825 assert(!cInterval.contains(iPosInfInterval)); 1826 assert(!cInterval.contains(negInfInterval)); 1827 assert(!cInterval.contains(cNegInfInterval)); 1828 assert(!cInterval.contains(iNegInfInterval)); 1829 assert(iInterval.contains(interval)); 1830 assert(iInterval.contains(cInterval)); 1831 assert(iInterval.contains(iInterval)); 1832 assert(!iInterval.contains(posInfInterval)); 1833 assert(!iInterval.contains(cPosInfInterval)); 1834 assert(!iInterval.contains(iPosInfInterval)); 1835 assert(!iInterval.contains(negInfInterval)); 1836 assert(!iInterval.contains(cNegInfInterval)); 1837 assert(!iInterval.contains(iNegInfInterval)); 1838 1839 // Verify Examples. 1840 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 1841 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 1842 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 1843 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 1844 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( 1845 Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); 1846 1847 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4)))); 1848 1849 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4)))); 1850 } 1851 1852 // Test Interval's isBefore(time point). 1853 @safe unittest 1854 { 1855 import std.datetime.date; 1856 1857 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1858 1859 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(Date(2010, 7, 4))); 1860 1861 assert(!interval.isBefore(Date(2009, 7, 3))); 1862 assert(!interval.isBefore(Date(2010, 7, 3))); 1863 assert(!interval.isBefore(Date(2010, 7, 4))); 1864 assert(!interval.isBefore(Date(2010, 7, 5))); 1865 assert(!interval.isBefore(Date(2011, 7, 1))); 1866 assert(!interval.isBefore(Date(2012, 1, 6))); 1867 assert(interval.isBefore(Date(2012, 1, 7))); 1868 assert(interval.isBefore(Date(2012, 1, 8))); 1869 assert(interval.isBefore(Date(2013, 1, 7))); 1870 1871 const cdate = Date(2010, 7, 6); 1872 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1873 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1874 assert(!interval.isBefore(cdate)); 1875 assert(!cInterval.isBefore(cdate)); 1876 assert(!iInterval.isBefore(cdate)); 1877 1878 // Verify Examples. 1879 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(1994, 12, 24))); 1880 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2000, 1, 5))); 1881 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2012, 3, 1))); 1882 } 1883 1884 // Test Interval's isBefore(Interval). 1885 @safe unittest 1886 { 1887 import std.datetime.date; 1888 1889 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1890 1891 assertThrown!DateTimeException(interval.isBefore(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 1892 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(interval)); 1893 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore( 1894 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 1895 1896 assert(!interval.isBefore(interval)); 1897 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 1898 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 1899 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 1900 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 1901 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 1902 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 1903 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 1904 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 1905 assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 1906 assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 1907 assert(interval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 1908 assert(interval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 1909 1910 assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isBefore(interval)); 1911 assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isBefore(interval)); 1912 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isBefore(interval)); 1913 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isBefore(interval)); 1914 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isBefore(interval)); 1915 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isBefore(interval)); 1916 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isBefore(interval)); 1917 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isBefore(interval)); 1918 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isBefore(interval)); 1919 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isBefore(interval)); 1920 assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isBefore(interval)); 1921 assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isBefore(interval)); 1922 1923 assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 3)))); 1924 assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 4)))); 1925 assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 5)))); 1926 assert(!interval.isBefore(PosInfInterval!Date(Date(2012, 1, 6)))); 1927 assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 7)))); 1928 assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 8)))); 1929 1930 assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 3)))); 1931 assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 4)))); 1932 assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 5)))); 1933 assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 6)))); 1934 assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 7)))); 1935 assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 8)))); 1936 1937 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1938 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1939 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 1940 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 1941 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 1942 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 1943 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 1944 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 1945 assert(!interval.isBefore(interval)); 1946 assert(!interval.isBefore(cInterval)); 1947 assert(!interval.isBefore(iInterval)); 1948 assert(!interval.isBefore(posInfInterval)); 1949 assert(!interval.isBefore(cPosInfInterval)); 1950 assert(!interval.isBefore(iPosInfInterval)); 1951 assert(!interval.isBefore(negInfInterval)); 1952 assert(!interval.isBefore(cNegInfInterval)); 1953 assert(!interval.isBefore(iNegInfInterval)); 1954 assert(!cInterval.isBefore(interval)); 1955 assert(!cInterval.isBefore(cInterval)); 1956 assert(!cInterval.isBefore(iInterval)); 1957 assert(!cInterval.isBefore(posInfInterval)); 1958 assert(!cInterval.isBefore(cPosInfInterval)); 1959 assert(!cInterval.isBefore(iPosInfInterval)); 1960 assert(!cInterval.isBefore(negInfInterval)); 1961 assert(!cInterval.isBefore(cNegInfInterval)); 1962 assert(!cInterval.isBefore(iNegInfInterval)); 1963 assert(!iInterval.isBefore(interval)); 1964 assert(!iInterval.isBefore(cInterval)); 1965 assert(!iInterval.isBefore(iInterval)); 1966 assert(!iInterval.isBefore(posInfInterval)); 1967 assert(!iInterval.isBefore(cPosInfInterval)); 1968 assert(!iInterval.isBefore(iPosInfInterval)); 1969 assert(!iInterval.isBefore(negInfInterval)); 1970 assert(!iInterval.isBefore(cNegInfInterval)); 1971 assert(!iInterval.isBefore(iNegInfInterval)); 1972 1973 // Verify Examples. 1974 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 1975 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 1976 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 1977 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 1978 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( 1979 Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1)))); 1980 1981 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4)))); 1982 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2013, 3, 7)))); 1983 1984 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4)))); 1985 } 1986 1987 // Test Interval's isAfter(time point). 1988 @safe unittest 1989 { 1990 import std.datetime.date; 1991 1992 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 1993 1994 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(Date(2010, 7, 4))); 1995 1996 assert(interval.isAfter(Date(2009, 7, 4))); 1997 assert(interval.isAfter(Date(2010, 7, 3))); 1998 assert(!interval.isAfter(Date(2010, 7, 4))); 1999 assert(!interval.isAfter(Date(2010, 7, 5))); 2000 assert(!interval.isAfter(Date(2011, 7, 1))); 2001 assert(!interval.isAfter(Date(2012, 1, 6))); 2002 assert(!interval.isAfter(Date(2012, 1, 7))); 2003 assert(!interval.isAfter(Date(2012, 1, 8))); 2004 assert(!interval.isAfter(Date(2013, 1, 7))); 2005 2006 const cdate = Date(2010, 7, 6); 2007 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2008 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2009 assert(!interval.isAfter(cdate)); 2010 assert(!cInterval.isAfter(cdate)); 2011 assert(!iInterval.isAfter(cdate)); 2012 2013 // Verify Examples. 2014 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(1994, 12, 24))); 2015 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2000, 1, 5))); 2016 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2012, 3, 1))); 2017 } 2018 2019 // Test Interval's isAfter(Interval). 2020 @safe unittest 2021 { 2022 import std.datetime.date; 2023 2024 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2025 2026 assertThrown!DateTimeException(interval.isAfter(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2027 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(interval)); 2028 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter( 2029 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2030 2031 assert(!interval.isAfter(interval)); 2032 assert(interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 2033 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 2034 assert(interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 2035 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 2036 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 2037 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 2038 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 2039 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 2040 assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 2041 assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 2042 assert(!interval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 2043 assert(!interval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 2044 2045 assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAfter(interval)); 2046 assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAfter(interval)); 2047 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAfter(interval)); 2048 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAfter(interval)); 2049 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAfter(interval)); 2050 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAfter(interval)); 2051 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAfter(interval)); 2052 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAfter(interval)); 2053 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAfter(interval)); 2054 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAfter(interval)); 2055 assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAfter(interval)); 2056 assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAfter(interval)); 2057 2058 assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 3)))); 2059 assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 4)))); 2060 assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 5)))); 2061 assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 6)))); 2062 assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 7)))); 2063 assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 8)))); 2064 2065 assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 3)))); 2066 assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 4)))); 2067 assert(!interval.isAfter(NegInfInterval!Date(Date(2010, 7, 5)))); 2068 assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 6)))); 2069 assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 7)))); 2070 assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 8)))); 2071 2072 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2073 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2074 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2075 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2076 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2077 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2078 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2079 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2080 assert(!interval.isAfter(interval)); 2081 assert(!interval.isAfter(cInterval)); 2082 assert(!interval.isAfter(iInterval)); 2083 assert(!interval.isAfter(posInfInterval)); 2084 assert(!interval.isAfter(cPosInfInterval)); 2085 assert(!interval.isAfter(iPosInfInterval)); 2086 assert(!interval.isAfter(negInfInterval)); 2087 assert(!interval.isAfter(cNegInfInterval)); 2088 assert(!interval.isAfter(iNegInfInterval)); 2089 assert(!cInterval.isAfter(interval)); 2090 assert(!cInterval.isAfter(cInterval)); 2091 assert(!cInterval.isAfter(iInterval)); 2092 assert(!cInterval.isAfter(posInfInterval)); 2093 assert(!cInterval.isAfter(cPosInfInterval)); 2094 assert(!cInterval.isAfter(iPosInfInterval)); 2095 assert(!cInterval.isAfter(negInfInterval)); 2096 assert(!cInterval.isAfter(cNegInfInterval)); 2097 assert(!cInterval.isAfter(iNegInfInterval)); 2098 assert(!iInterval.isAfter(interval)); 2099 assert(!iInterval.isAfter(cInterval)); 2100 assert(!iInterval.isAfter(iInterval)); 2101 assert(!iInterval.isAfter(posInfInterval)); 2102 assert(!iInterval.isAfter(cPosInfInterval)); 2103 assert(!iInterval.isAfter(iPosInfInterval)); 2104 assert(!iInterval.isAfter(negInfInterval)); 2105 assert(!iInterval.isAfter(cNegInfInterval)); 2106 assert(!iInterval.isAfter(iNegInfInterval)); 2107 2108 // Verify Examples. 2109 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 2110 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 2111 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 2112 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 2113 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( 2114 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 2115 2116 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4)))); 2117 2118 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 1, 2)))); 2119 } 2120 2121 // Test Interval's intersects(). 2122 @safe unittest 2123 { 2124 import std.datetime.date; 2125 2126 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2127 2128 assertThrown!DateTimeException(interval.intersects(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2129 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects(interval)); 2130 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects( 2131 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2132 2133 assert(interval.intersects(interval)); 2134 assert(!interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 2135 assert(interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 2136 assert(!interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 2137 assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 2138 assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 2139 assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 2140 assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 2141 assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 2142 assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 2143 assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 2144 assert(!interval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 2145 assert(!interval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 2146 2147 assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersects(interval)); 2148 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersects(interval)); 2149 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersects(interval)); 2150 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersects(interval)); 2151 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersects(interval)); 2152 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersects(interval)); 2153 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersects(interval)); 2154 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersects(interval)); 2155 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersects(interval)); 2156 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersects(interval)); 2157 assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersects(interval)); 2158 assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersects(interval)); 2159 2160 assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 3)))); 2161 assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 4)))); 2162 assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 5)))); 2163 assert(interval.intersects(PosInfInterval!Date(Date(2012, 1, 6)))); 2164 assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 7)))); 2165 assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 8)))); 2166 2167 assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 3)))); 2168 assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 4)))); 2169 assert(interval.intersects(NegInfInterval!Date(Date(2010, 7, 5)))); 2170 assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 6)))); 2171 assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 7)))); 2172 assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 8)))); 2173 2174 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2175 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2176 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2177 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2178 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2179 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2180 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2181 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2182 assert(interval.intersects(interval)); 2183 assert(interval.intersects(cInterval)); 2184 assert(interval.intersects(iInterval)); 2185 assert(interval.intersects(posInfInterval)); 2186 assert(interval.intersects(cPosInfInterval)); 2187 assert(interval.intersects(iPosInfInterval)); 2188 assert(interval.intersects(negInfInterval)); 2189 assert(interval.intersects(cNegInfInterval)); 2190 assert(interval.intersects(iNegInfInterval)); 2191 assert(cInterval.intersects(interval)); 2192 assert(cInterval.intersects(cInterval)); 2193 assert(cInterval.intersects(iInterval)); 2194 assert(cInterval.intersects(posInfInterval)); 2195 assert(cInterval.intersects(cPosInfInterval)); 2196 assert(cInterval.intersects(iPosInfInterval)); 2197 assert(cInterval.intersects(negInfInterval)); 2198 assert(cInterval.intersects(cNegInfInterval)); 2199 assert(cInterval.intersects(iNegInfInterval)); 2200 assert(iInterval.intersects(interval)); 2201 assert(iInterval.intersects(cInterval)); 2202 assert(iInterval.intersects(iInterval)); 2203 assert(iInterval.intersects(posInfInterval)); 2204 assert(iInterval.intersects(cPosInfInterval)); 2205 assert(iInterval.intersects(iPosInfInterval)); 2206 assert(iInterval.intersects(negInfInterval)); 2207 assert(iInterval.intersects(cNegInfInterval)); 2208 assert(iInterval.intersects(iNegInfInterval)); 2209 2210 // Verify Examples. 2211 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 2212 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 2213 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 2214 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 2215 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( 2216 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 2217 2218 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4)))); 2219 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1)))); 2220 2221 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 1, 2)))); 2222 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2000, 1, 2)))); 2223 } 2224 2225 // Test Interval's intersection(). 2226 @safe unittest 2227 { 2228 import std.datetime.date; 2229 2230 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2231 2232 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2233 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection(interval)); 2234 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection( 2235 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2236 2237 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 2238 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 2239 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 2240 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 2241 2242 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersection(interval)); 2243 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersection(interval)); 2244 assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersection(interval)); 2245 assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersection(interval)); 2246 2247 assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 7)))); 2248 assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 8)))); 2249 2250 assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 3)))); 2251 assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 4)))); 2252 2253 assert(interval.intersection(interval) == interval); 2254 assert(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 2255 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2256 assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 2257 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); 2258 assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 2259 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2260 assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 2261 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2262 assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 2263 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); 2264 assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 2265 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); 2266 assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 2267 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 2268 assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 2269 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 2270 2271 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersection(interval) == 2272 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2273 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersection(interval) == 2274 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); 2275 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersection(interval) == 2276 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2277 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersection(interval) == 2278 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2279 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersection(interval) == 2280 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); 2281 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersection(interval) == 2282 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); 2283 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersection(interval) == 2284 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 2285 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersection(interval) == 2286 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 2287 2288 assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == 2289 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2290 assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == 2291 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2292 assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == 2293 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); 2294 assert(interval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == 2295 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 2296 2297 assert(interval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == 2298 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); 2299 assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == 2300 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6))); 2301 assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == 2302 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2303 assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == 2304 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2305 2306 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2307 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2308 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2309 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2310 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2311 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2312 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2313 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2314 assert(!interval.intersection(interval).empty); 2315 assert(!interval.intersection(cInterval).empty); 2316 assert(!interval.intersection(iInterval).empty); 2317 assert(!interval.intersection(posInfInterval).empty); 2318 assert(!interval.intersection(cPosInfInterval).empty); 2319 assert(!interval.intersection(iPosInfInterval).empty); 2320 assert(!interval.intersection(negInfInterval).empty); 2321 assert(!interval.intersection(cNegInfInterval).empty); 2322 assert(!interval.intersection(iNegInfInterval).empty); 2323 assert(!cInterval.intersection(interval).empty); 2324 assert(!cInterval.intersection(cInterval).empty); 2325 assert(!cInterval.intersection(iInterval).empty); 2326 assert(!cInterval.intersection(posInfInterval).empty); 2327 assert(!cInterval.intersection(cPosInfInterval).empty); 2328 assert(!cInterval.intersection(iPosInfInterval).empty); 2329 assert(!cInterval.intersection(negInfInterval).empty); 2330 assert(!cInterval.intersection(cNegInfInterval).empty); 2331 assert(!cInterval.intersection(iNegInfInterval).empty); 2332 assert(!iInterval.intersection(interval).empty); 2333 assert(!iInterval.intersection(cInterval).empty); 2334 assert(!iInterval.intersection(iInterval).empty); 2335 assert(!iInterval.intersection(posInfInterval).empty); 2336 assert(!iInterval.intersection(cPosInfInterval).empty); 2337 assert(!iInterval.intersection(iPosInfInterval).empty); 2338 assert(!iInterval.intersection(negInfInterval).empty); 2339 assert(!iInterval.intersection(cNegInfInterval).empty); 2340 assert(!iInterval.intersection(iNegInfInterval).empty); 2341 2342 // Verify Examples. 2343 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 2344 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 2345 Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); 2346 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 2347 Interval!Date(Date(1999, 1, 12),Date(2011, 9, 17))) == 2348 Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); 2349 2350 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 2351 PosInfInterval!Date(Date(1990, 7, 6))) == 2352 Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); 2353 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 2354 PosInfInterval!Date(Date(1999, 1, 12))) == 2355 Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); 2356 2357 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 2358 NegInfInterval!Date(Date(1999, 7, 6))) == 2359 Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); 2360 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( 2361 NegInfInterval!Date(Date(2013, 1, 12))) == 2362 Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); 2363 } 2364 2365 // Test Interval's isAdjacent(). 2366 @safe unittest 2367 { 2368 import std.datetime.date; 2369 2370 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2371 2372 static void testInterval(scope const Interval!Date interval1, scope const Interval!Date interval2) 2373 { 2374 interval1.isAdjacent(interval2); 2375 } 2376 2377 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2378 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval)); 2379 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 2380 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2381 2382 assert(!interval.isAdjacent(interval)); 2383 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 2384 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 2385 assert(interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 2386 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 2387 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 2388 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 2389 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 2390 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 2391 assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 2392 assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 2393 assert(interval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 2394 assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 2395 2396 assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAdjacent(interval)); 2397 assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAdjacent(interval)); 2398 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAdjacent(interval)); 2399 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAdjacent(interval)); 2400 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAdjacent(interval)); 2401 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAdjacent(interval)); 2402 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAdjacent(interval)); 2403 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAdjacent(interval)); 2404 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAdjacent(interval)); 2405 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAdjacent(interval)); 2406 assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAdjacent(interval)); 2407 assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAdjacent(interval)); 2408 2409 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3)))); 2410 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4)))); 2411 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5)))); 2412 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6)))); 2413 assert(interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7)))); 2414 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8)))); 2415 2416 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3)))); 2417 assert(interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4)))); 2418 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5)))); 2419 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6)))); 2420 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7)))); 2421 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8)))); 2422 2423 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2424 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2425 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2426 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2427 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2428 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2429 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2430 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2431 assert(!interval.isAdjacent(interval)); 2432 assert(!interval.isAdjacent(cInterval)); 2433 assert(!interval.isAdjacent(iInterval)); 2434 assert(!interval.isAdjacent(posInfInterval)); 2435 assert(!interval.isAdjacent(cPosInfInterval)); 2436 assert(!interval.isAdjacent(iPosInfInterval)); 2437 assert(!interval.isAdjacent(negInfInterval)); 2438 assert(!interval.isAdjacent(cNegInfInterval)); 2439 assert(!interval.isAdjacent(iNegInfInterval)); 2440 assert(!cInterval.isAdjacent(interval)); 2441 assert(!cInterval.isAdjacent(cInterval)); 2442 assert(!cInterval.isAdjacent(iInterval)); 2443 assert(!cInterval.isAdjacent(posInfInterval)); 2444 assert(!cInterval.isAdjacent(cPosInfInterval)); 2445 assert(!cInterval.isAdjacent(iPosInfInterval)); 2446 assert(!cInterval.isAdjacent(negInfInterval)); 2447 assert(!cInterval.isAdjacent(cNegInfInterval)); 2448 assert(!cInterval.isAdjacent(iNegInfInterval)); 2449 assert(!iInterval.isAdjacent(interval)); 2450 assert(!iInterval.isAdjacent(cInterval)); 2451 assert(!iInterval.isAdjacent(iInterval)); 2452 assert(!iInterval.isAdjacent(posInfInterval)); 2453 assert(!iInterval.isAdjacent(cPosInfInterval)); 2454 assert(!iInterval.isAdjacent(iPosInfInterval)); 2455 assert(!iInterval.isAdjacent(negInfInterval)); 2456 assert(!iInterval.isAdjacent(cNegInfInterval)); 2457 assert(!iInterval.isAdjacent(iNegInfInterval)); 2458 2459 // Verify Examples. 2460 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 2461 Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2)))); 2462 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 2463 Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17)))); 2464 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( 2465 Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1)))); 2466 2467 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4)))); 2468 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1)))); 2469 2470 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2)))); 2471 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)) .isAdjacent(NegInfInterval!Date(Date(2000, 1, 2)))); 2472 } 2473 2474 // Test Interval's merge(). 2475 @safe unittest 2476 { 2477 import std.datetime.date; 2478 2479 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2480 2481 static void testInterval(I)(scope const Interval!Date interval1, scope const I interval2) 2482 { 2483 interval1.merge(interval2); 2484 } 2485 2486 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2487 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval)); 2488 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 2489 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2490 2491 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 2492 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 2493 2494 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)), interval)); 2495 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)), interval)); 2496 2497 assertThrown!DateTimeException(testInterval(interval, PosInfInterval!Date(Date(2012, 1, 8)))); 2498 2499 assertThrown!DateTimeException(testInterval(interval, NegInfInterval!Date(Date(2010, 7, 3)))); 2500 2501 assert(interval.merge(interval) == interval); 2502 assert(interval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 2503 Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); 2504 assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 2505 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2506 assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 2507 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2508 assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 2509 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2510 assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 2511 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); 2512 assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 2513 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2514 assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 2515 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2516 assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 2517 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2518 assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 2519 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2520 assert(interval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 2521 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2522 2523 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).merge(interval) == 2524 Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); 2525 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).merge(interval) == 2526 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2527 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).merge(interval) == 2528 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2529 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).merge(interval) == 2530 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2531 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).merge(interval) == 2532 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); 2533 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).merge(interval) == 2534 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2535 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).merge(interval) == 2536 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2537 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).merge(interval) == 2538 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2539 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).merge(interval) == 2540 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2541 assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).merge(interval) == 2542 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2543 2544 assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 3))) == 2545 PosInfInterval!Date(Date(2010, 7, 3))); 2546 assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 4))) == 2547 PosInfInterval!Date(Date(2010, 7, 4))); 2548 assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 5))) == 2549 PosInfInterval!Date(Date(2010, 7, 4))); 2550 assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 6))) == 2551 PosInfInterval!Date(Date(2010, 7, 4))); 2552 assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 7))) == 2553 PosInfInterval!Date(Date(2010, 7, 4))); 2554 2555 assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 4))) == 2556 NegInfInterval!Date(Date(2012, 1, 7))); 2557 assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 5))) == 2558 NegInfInterval!Date(Date(2012, 1, 7))); 2559 assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 6))) == 2560 NegInfInterval!Date(Date(2012, 1, 7))); 2561 assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 7))) == 2562 NegInfInterval!Date(Date(2012, 1, 7))); 2563 assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 8))) == 2564 NegInfInterval!Date(Date(2012, 1, 8))); 2565 2566 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2567 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2568 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2569 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2570 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2571 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2572 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2573 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2574 assert(!interval.merge(interval).empty); 2575 assert(!interval.merge(cInterval).empty); 2576 assert(!interval.merge(iInterval).empty); 2577 assert(!interval.merge(posInfInterval).empty); 2578 assert(!interval.merge(cPosInfInterval).empty); 2579 assert(!interval.merge(iPosInfInterval).empty); 2580 assert(!interval.merge(negInfInterval).empty); 2581 assert(!interval.merge(cNegInfInterval).empty); 2582 assert(!interval.merge(iNegInfInterval).empty); 2583 assert(!cInterval.merge(interval).empty); 2584 assert(!cInterval.merge(cInterval).empty); 2585 assert(!cInterval.merge(iInterval).empty); 2586 assert(!cInterval.merge(posInfInterval).empty); 2587 assert(!cInterval.merge(cPosInfInterval).empty); 2588 assert(!cInterval.merge(iPosInfInterval).empty); 2589 assert(!cInterval.merge(negInfInterval).empty); 2590 assert(!cInterval.merge(cNegInfInterval).empty); 2591 assert(!cInterval.merge(iNegInfInterval).empty); 2592 assert(!iInterval.merge(interval).empty); 2593 assert(!iInterval.merge(cInterval).empty); 2594 assert(!iInterval.merge(iInterval).empty); 2595 assert(!iInterval.merge(posInfInterval).empty); 2596 assert(!iInterval.merge(cPosInfInterval).empty); 2597 assert(!iInterval.merge(iPosInfInterval).empty); 2598 assert(!iInterval.merge(negInfInterval).empty); 2599 assert(!iInterval.merge(cNegInfInterval).empty); 2600 assert(!iInterval.merge(iNegInfInterval).empty); 2601 2602 // Verify Examples. 2603 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 2604 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); 2605 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == 2606 Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); 2607 2608 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(1990, 7, 6))) == 2609 PosInfInterval!Date(Date(1990, 7 , 6))); 2610 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(2012, 3, 1))) == 2611 PosInfInterval!Date(Date(1996, 1 , 2))); 2612 2613 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1996, 1, 2))) == 2614 NegInfInterval!Date(Date(2012, 3 , 1))); 2615 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) == 2616 NegInfInterval!Date(Date(2013, 1 , 12))); 2617 } 2618 2619 // Test Interval's span(). 2620 @safe unittest 2621 { 2622 import std.datetime.date; 2623 2624 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2625 2626 static void testInterval(scope const Interval!Date interval1, scope const Interval!Date interval2) 2627 { 2628 interval1.span(interval2); 2629 } 2630 2631 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2632 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)),interval)); 2633 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 2634 Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 2635 2636 assert(interval.span(interval) == interval); 2637 assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == 2638 Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); 2639 assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 2640 Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); 2641 assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 2642 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2643 assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 2644 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2645 assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 2646 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2647 assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 2648 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); 2649 assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 2650 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2651 assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 2652 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2653 assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 2654 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2655 assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 2656 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2657 assert(interval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 2658 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2659 assert(interval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == 2660 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9))); 2661 2662 assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).span(interval) == 2663 Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); 2664 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).span(interval) == 2665 Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); 2666 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).span(interval) == 2667 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2668 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).span(interval) == 2669 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2670 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).span(interval) == 2671 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 2672 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).span(interval) == 2673 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); 2674 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).span(interval) == 2675 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2676 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).span(interval) == 2677 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2678 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).span(interval) == 2679 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 2680 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).span(interval) == 2681 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2682 assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).span(interval) == 2683 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 2684 assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).span(interval) == 2685 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9))); 2686 2687 assert(interval.span(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3))); 2688 assert(interval.span(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4))); 2689 assert(interval.span(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4))); 2690 assert(interval.span(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4))); 2691 assert(interval.span(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4))); 2692 assert(interval.span(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4))); 2693 2694 assert(interval.span(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7))); 2695 assert(interval.span(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7))); 2696 assert(interval.span(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7))); 2697 assert(interval.span(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7))); 2698 assert(interval.span(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7))); 2699 assert(interval.span(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8))); 2700 2701 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2702 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2703 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2704 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2705 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 2706 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2707 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2708 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 2709 assert(!interval.span(interval).empty); 2710 assert(!interval.span(cInterval).empty); 2711 assert(!interval.span(iInterval).empty); 2712 assert(!interval.span(posInfInterval).empty); 2713 assert(!interval.span(cPosInfInterval).empty); 2714 assert(!interval.span(iPosInfInterval).empty); 2715 assert(!interval.span(negInfInterval).empty); 2716 assert(!interval.span(cNegInfInterval).empty); 2717 assert(!interval.span(iNegInfInterval).empty); 2718 assert(!cInterval.span(interval).empty); 2719 assert(!cInterval.span(cInterval).empty); 2720 assert(!cInterval.span(iInterval).empty); 2721 assert(!cInterval.span(posInfInterval).empty); 2722 assert(!cInterval.span(cPosInfInterval).empty); 2723 assert(!cInterval.span(iPosInfInterval).empty); 2724 assert(!cInterval.span(negInfInterval).empty); 2725 assert(!cInterval.span(cNegInfInterval).empty); 2726 assert(!cInterval.span(iNegInfInterval).empty); 2727 assert(!iInterval.span(interval).empty); 2728 assert(!iInterval.span(cInterval).empty); 2729 assert(!iInterval.span(iInterval).empty); 2730 assert(!iInterval.span(posInfInterval).empty); 2731 assert(!iInterval.span(cPosInfInterval).empty); 2732 assert(!iInterval.span(iPosInfInterval).empty); 2733 assert(!iInterval.span(negInfInterval).empty); 2734 assert(!iInterval.span(cNegInfInterval).empty); 2735 assert(!iInterval.span(iNegInfInterval).empty); 2736 2737 // Verify Examples. 2738 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) == 2739 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); 2740 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == 2741 Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); 2742 2743 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(1990, 7, 6))) == 2744 PosInfInterval!Date(Date(1990, 7 , 6))); 2745 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(2050, 1, 1))) == 2746 PosInfInterval!Date(Date(1996, 1 , 2))); 2747 2748 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1602, 5, 21))) == 2749 NegInfInterval!Date(Date(2012, 3 , 1))); 2750 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) == 2751 NegInfInterval!Date(Date(2013, 1 , 12))); 2752 } 2753 2754 // Test Interval's shift(duration). 2755 @safe unittest 2756 { 2757 import std.datetime.date; 2758 2759 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2760 2761 static void testIntervalFail(Interval!Date interval, scope const Duration duration) 2762 { 2763 interval.shift(duration); 2764 } 2765 2766 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1))); 2767 2768 static void testInterval(I)(I interval, scope const Duration duration, 2769 scope const I expected, size_t line = __LINE__) 2770 { 2771 interval.shift(duration); 2772 assert(interval == expected); 2773 } 2774 2775 testInterval(interval, dur!"days"(22), Interval!Date(Date(2010, 7, 26), Date(2012, 1, 29))); 2776 testInterval(interval, dur!"days"(-22), Interval!Date(Date(2010, 6, 12), Date(2011, 12, 16))); 2777 2778 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2779 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2780 static assert(!__traits(compiles, cInterval.shift(dur!"days"(5)))); 2781 static assert(!__traits(compiles, iInterval.shift(dur!"days"(5)))); 2782 2783 // Verify Examples. 2784 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); 2785 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); 2786 2787 interval1.shift(dur!"days"(50)); 2788 assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25))); 2789 2790 interval2.shift(dur!"days"(-50)); 2791 assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15))); 2792 } 2793 2794 // Test Interval's shift(int, int, AllowDayOverflow). 2795 @safe unittest 2796 { 2797 import std.datetime.date; 2798 2799 { 2800 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2801 2802 static void testIntervalFail(Interval!Date interval, int years, int months) 2803 { 2804 interval.shift(years, months); 2805 } 2806 2807 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0)); 2808 2809 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, 2810 in I expected, size_t line = __LINE__) 2811 { 2812 interval.shift(years, months, allow); 2813 assert(interval == expected); 2814 } 2815 2816 testInterval(interval, 5, 0, AllowDayOverflow.yes, Interval!Date(Date(2015, 7, 4), Date(2017, 1, 7))); 2817 testInterval(interval, -5, 0, AllowDayOverflow.yes, Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7))); 2818 2819 auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31)); 2820 2821 testInterval(interval2, 1, 1, AllowDayOverflow.yes, Interval!Date(Date(2001, 3, 1), Date(2011, 7, 1))); 2822 testInterval(interval2, 1, -1, AllowDayOverflow.yes, Interval!Date(Date(2000, 12, 29), Date(2011, 5, 1))); 2823 testInterval(interval2, -1, -1, AllowDayOverflow.yes, Interval!Date(Date(1998, 12, 29), Date(2009, 5, 1))); 2824 testInterval(interval2, -1, 1, AllowDayOverflow.yes, Interval!Date(Date(1999, 3, 1), Date(2009, 7, 1))); 2825 2826 testInterval(interval2, 1, 1, AllowDayOverflow.no, Interval!Date(Date(2001, 2, 28), Date(2011, 6, 30))); 2827 testInterval(interval2, 1, -1, AllowDayOverflow.no, Interval!Date(Date(2000, 12, 29), Date(2011, 4, 30))); 2828 testInterval(interval2, -1, -1, AllowDayOverflow.no, Interval!Date(Date(1998, 12, 29), Date(2009, 4, 30))); 2829 testInterval(interval2, -1, 1, AllowDayOverflow.no, Interval!Date(Date(1999, 2, 28), Date(2009, 6, 30))); 2830 } 2831 2832 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2833 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2834 static assert(!__traits(compiles, cInterval.shift(5))); 2835 static assert(!__traits(compiles, iInterval.shift(5))); 2836 2837 // Verify Examples. 2838 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 2839 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 2840 2841 interval1.shift(2); 2842 assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1))); 2843 2844 interval2.shift(-2); 2845 assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1))); 2846 } 2847 2848 // Test Interval's expand(Duration). 2849 @safe unittest 2850 { 2851 import std.datetime.date; 2852 2853 auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7)); 2854 2855 static void testIntervalFail(I)(I interval, scope const Duration duration) 2856 { 2857 interval.expand(duration); 2858 } 2859 2860 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1))); 2861 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)), dur!"days"(-5))); 2862 2863 static void testInterval(I)(I interval, scope const Duration duration, 2864 scope const I expected, size_t line = __LINE__) 2865 { 2866 interval.expand(duration); 2867 assert(interval == expected); 2868 } 2869 2870 testInterval(interval, dur!"days"(22), Interval!Date(Date(2000, 6, 12), Date(2012, 1, 29))); 2871 testInterval(interval, dur!"days"(-22), Interval!Date(Date(2000, 7, 26), Date(2011, 12, 16))); 2872 2873 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2874 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2875 static assert(!__traits(compiles, cInterval.expand(dur!"days"(5)))); 2876 static assert(!__traits(compiles, iInterval.expand(dur!"days"(5)))); 2877 2878 // Verify Examples. 2879 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 2880 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 2881 2882 interval1.expand(dur!"days"(2)); 2883 assert(interval1 == Interval!Date(Date(1995, 12, 31), Date(2012, 3, 3))); 2884 2885 interval2.expand(dur!"days"(-2)); 2886 assert(interval2 == Interval!Date(Date(1996, 1, 4), Date(2012, 2, 28))); 2887 } 2888 2889 // Test Interval's expand(int, int, AllowDayOverflow, Direction) 2890 @safe unittest 2891 { 2892 import std.datetime.date; 2893 2894 { 2895 auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7)); 2896 2897 static void testIntervalFail(Interval!Date interval, int years, int months) 2898 { 2899 interval.expand(years, months); 2900 } 2901 2902 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0)); 2903 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)), -5, 0)); 2904 2905 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, Direction dir, 2906 in I expected, size_t line = __LINE__) 2907 { 2908 interval.expand(years, months, allow, dir); 2909 assert(interval == expected); 2910 } 2911 2912 testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.both, 2913 Interval!Date(Date(1995, 7, 4), Date(2017, 1, 7))); 2914 testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.both, 2915 Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7))); 2916 2917 testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.fwd, 2918 Interval!Date(Date(2000, 7, 4), Date(2017, 1, 7))); 2919 testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.fwd, 2920 Interval!Date(Date(2000, 7, 4), Date(2007, 1, 7))); 2921 2922 testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.bwd, 2923 Interval!Date(Date(1995, 7, 4), Date(2012, 1, 7))); 2924 testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.bwd, 2925 Interval!Date(Date(2005, 7, 4), Date(2012, 1, 7))); 2926 2927 auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31)); 2928 2929 testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.both, 2930 Interval!Date(Date(1998, 12, 29), Date(2011, 7, 1))); 2931 testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.both, 2932 Interval!Date(Date(1999, 3, 1), Date(2011, 5, 1))); 2933 testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.both, 2934 Interval!Date(Date(2001, 3, 1), Date(2009, 5, 1))); 2935 testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.both, 2936 Interval!Date(Date(2000, 12, 29), Date(2009, 7, 1))); 2937 2938 testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.both, 2939 Interval!Date(Date(1998, 12, 29), Date(2011, 6, 30))); 2940 testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.both, 2941 Interval!Date(Date(1999, 2, 28), Date(2011, 4, 30))); 2942 testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.both, 2943 Interval!Date(Date(2001, 2, 28), Date(2009, 4, 30))); 2944 testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.both, 2945 Interval!Date(Date(2000, 12, 29), Date(2009, 6, 30))); 2946 2947 testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.fwd, 2948 Interval!Date(Date(2000, 1, 29), Date(2011, 7, 1))); 2949 testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.fwd, 2950 Interval!Date(Date(2000, 1, 29), Date(2011, 5, 1))); 2951 testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.fwd, 2952 Interval!Date(Date(2000, 1, 29), Date(2009, 5, 1))); 2953 testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.fwd, 2954 Interval!Date(Date(2000, 1, 29), Date(2009, 7, 1))); 2955 2956 testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.fwd, 2957 Interval!Date(Date(2000, 1, 29), Date(2011, 6, 30))); 2958 testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.fwd, 2959 Interval!Date(Date(2000, 1, 29), Date(2011, 4, 30))); 2960 testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.fwd, 2961 Interval!Date(Date(2000, 1, 29), Date(2009, 4, 30))); 2962 testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.fwd, 2963 Interval!Date(Date(2000, 1, 29), Date(2009, 6, 30))); 2964 2965 testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.bwd, 2966 Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31))); 2967 testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.bwd, 2968 Interval!Date(Date(1999, 3, 1), Date(2010, 5, 31))); 2969 testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.bwd, 2970 Interval!Date(Date(2001, 3, 1), Date(2010, 5, 31))); 2971 testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.bwd, 2972 Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31))); 2973 2974 testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.bwd, 2975 Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31))); 2976 testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.bwd, 2977 Interval!Date(Date(1999, 2, 28), Date(2010, 5, 31))); 2978 testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.bwd, 2979 Interval!Date(Date(2001, 2, 28), Date(2010, 5, 31))); 2980 testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.bwd, 2981 Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31))); 2982 } 2983 2984 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2985 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 2986 static assert(!__traits(compiles, cInterval.expand(5))); 2987 static assert(!__traits(compiles, iInterval.expand(5))); 2988 2989 // Verify Examples. 2990 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 2991 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); 2992 2993 interval1.expand(2); 2994 assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); 2995 2996 interval2.expand(-2); 2997 assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); 2998 } 2999 3000 // Test Interval's fwdRange. 3001 @system unittest 3002 { 3003 import std.datetime.date; 3004 3005 { 3006 auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)); 3007 3008 static void testInterval1(Interval!Date interval) 3009 { 3010 interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 3011 } 3012 3013 assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 3014 3015 static void testInterval2(Interval!Date interval) 3016 { 3017 interval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront(); 3018 } 3019 3020 assertThrown!DateTimeException(testInterval2(interval)); 3021 3022 assert(!interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 3023 assert(interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).empty); 3024 3025 assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front == 3026 Date(2010, 9, 12)); 3027 3028 assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange( 3029 everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 17)); 3030 } 3031 3032 // Verify Examples. 3033 { 3034 auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); 3035 auto func = delegate (scope const Date date) 3036 { 3037 if ((date.day & 1) == 0) 3038 return date + dur!"days"(2); 3039 return date + dur!"days"(1); 3040 }; 3041 auto range = interval.fwdRange(func); 3042 3043 // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). 3044 assert(range.front == Date(2010, 9, 1)); 3045 3046 range.popFront(); 3047 assert(range.front == Date(2010, 9, 2)); 3048 3049 range.popFront(); 3050 assert(range.front == Date(2010, 9, 4)); 3051 3052 range.popFront(); 3053 assert(range.front == Date(2010, 9, 6)); 3054 3055 range.popFront(); 3056 assert(range.front == Date(2010, 9, 8)); 3057 3058 range.popFront(); 3059 assert(range.empty); 3060 } 3061 3062 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 3063 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 3064 assert(!cInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 3065 assert(!iInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 3066 } 3067 3068 // Test Interval's bwdRange. 3069 @system unittest 3070 { 3071 import std.datetime.date; 3072 3073 { 3074 auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)); 3075 3076 static void testInterval1(Interval!Date interval) 3077 { 3078 interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 3079 } 3080 3081 assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 3082 3083 static void testInterval2(Interval!Date interval) 3084 { 3085 interval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront(); 3086 } 3087 3088 assertThrown!DateTimeException(testInterval2(interval)); 3089 3090 assert(!interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty); 3091 assert(interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).empty); 3092 3093 assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange( 3094 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front == Date(2010, 10, 1)); 3095 3096 assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange( 3097 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 24)); 3098 } 3099 3100 // Verify Examples. 3101 { 3102 auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); 3103 auto func = delegate (scope const Date date) 3104 { 3105 if ((date.day & 1) == 0) 3106 return date - dur!"days"(2); 3107 return date - dur!"days"(1); 3108 }; 3109 auto range = interval.bwdRange(func); 3110 3111 // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). 3112 assert(range.front == Date(2010, 9, 9)); 3113 3114 range.popFront(); 3115 assert(range.front == Date(2010, 9, 8)); 3116 3117 range.popFront(); 3118 assert(range.front == Date(2010, 9, 6)); 3119 3120 range.popFront(); 3121 assert(range.front == Date(2010, 9, 4)); 3122 3123 range.popFront(); 3124 assert(range.front == Date(2010, 9, 2)); 3125 3126 range.popFront(); 3127 assert(range.empty); 3128 } 3129 3130 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 3131 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 3132 assert(!cInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 3133 assert(!iInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 3134 } 3135 3136 // Test Interval's toString(). 3137 @safe unittest 3138 { 3139 import std.datetime.date; 3140 3141 assert(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).toString() == "[2010-Jul-04 - 2012-Jan-07)"); 3142 3143 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 3144 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 3145 assert(cInterval.toString()); 3146 assert(iInterval.toString()); 3147 } 3148 3149 3150 /++ 3151 Represents an interval of time which has positive infinity as its end point. 3152 3153 Any ranges which iterate over a `PosInfInterval` are infinite. So, the 3154 main purpose of using `PosInfInterval` is to create an infinite range 3155 which starts at a fixed point in time and goes to positive infinity. 3156 +/ 3157 struct PosInfInterval(TP) 3158 { 3159 public: 3160 3161 /++ 3162 Params: 3163 begin = The time point which begins the interval. 3164 3165 Example: 3166 -------------------- 3167 auto interval = PosInfInterval!Date(Date(1996, 1, 2)); 3168 -------------------- 3169 +/ 3170 this(scope const TP begin) pure nothrow 3171 { 3172 _begin = cast(TP) begin; 3173 } 3174 3175 3176 /++ 3177 Params: 3178 rhs = The `PosInfInterval` to assign to this one. 3179 +/ 3180 ref PosInfInterval opAssign(const ref PosInfInterval rhs) pure nothrow 3181 { 3182 _begin = cast(TP) rhs._begin; 3183 return this; 3184 } 3185 3186 3187 /++ 3188 Params: 3189 rhs = The `PosInfInterval` to assign to this one. 3190 +/ 3191 ref PosInfInterval opAssign(PosInfInterval rhs) pure nothrow 3192 { 3193 _begin = cast(TP) rhs._begin; 3194 return this; 3195 } 3196 3197 3198 /++ 3199 The starting point of the interval. It is included in the interval. 3200 3201 Example: 3202 -------------------- 3203 assert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2)); 3204 -------------------- 3205 +/ 3206 @property TP begin() const pure nothrow 3207 { 3208 return cast(TP)_begin; 3209 } 3210 3211 3212 /++ 3213 The starting point of the interval. It is included in the interval. 3214 3215 Params: 3216 timePoint = The time point to set `begin` to. 3217 +/ 3218 @property void begin(TP timePoint) pure nothrow 3219 { 3220 _begin = timePoint; 3221 } 3222 3223 3224 /++ 3225 Whether the interval's length is 0. Always returns false. 3226 3227 Example: 3228 -------------------- 3229 assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty); 3230 -------------------- 3231 +/ 3232 enum bool empty = false; 3233 3234 3235 /++ 3236 Whether the given time point is within this interval. 3237 3238 Params: 3239 timePoint = The time point to check for inclusion in this interval. 3240 3241 Example: 3242 -------------------- 3243 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24))); 3244 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5))); 3245 -------------------- 3246 +/ 3247 bool contains(TP timePoint) const pure nothrow 3248 { 3249 return timePoint >= _begin; 3250 } 3251 3252 3253 /++ 3254 Whether the given interval is completely within this interval. 3255 3256 Params: 3257 interval = The interval to check for inclusion in this interval. 3258 3259 Throws: 3260 $(REF DateTimeException,std,datetime,date) if the given interval 3261 is empty. 3262 3263 Example: 3264 -------------------- 3265 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains( 3266 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 3267 3268 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains( 3269 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 3270 3271 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains( 3272 Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); 3273 -------------------- 3274 +/ 3275 bool contains(scope const Interval!TP interval) const pure 3276 { 3277 interval._enforceNotEmpty(); 3278 return interval._begin >= _begin; 3279 } 3280 3281 3282 /++ 3283 Whether the given interval is completely within this interval. 3284 3285 Params: 3286 interval = The interval to check for inclusion in this interval. 3287 3288 Example: 3289 -------------------- 3290 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains( 3291 PosInfInterval!Date(Date(1999, 5, 4)))); 3292 3293 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains( 3294 PosInfInterval!Date(Date(1995, 7, 2)))); 3295 -------------------- 3296 +/ 3297 bool contains(scope const PosInfInterval interval) const pure nothrow 3298 { 3299 return interval._begin >= _begin; 3300 } 3301 3302 3303 /++ 3304 Whether the given interval is completely within this interval. 3305 3306 Always returns false because an interval going to positive infinity 3307 can never contain an interval beginning at negative infinity. 3308 3309 Params: 3310 interval = The interval to check for inclusion in this interval. 3311 3312 Example: 3313 -------------------- 3314 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains( 3315 NegInfInterval!Date(Date(1996, 5, 4)))); 3316 -------------------- 3317 +/ 3318 bool contains(scope const NegInfInterval!TP interval) const pure nothrow 3319 { 3320 return false; 3321 } 3322 3323 3324 /++ 3325 Whether this interval is before the given time point. 3326 3327 Always returns false because an interval going to positive infinity 3328 can never be before any time point. 3329 3330 Params: 3331 timePoint = The time point to check whether this interval is before 3332 it. 3333 3334 Example: 3335 -------------------- 3336 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24))); 3337 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5))); 3338 -------------------- 3339 +/ 3340 bool isBefore(scope const TP timePoint) const pure nothrow 3341 { 3342 return false; 3343 } 3344 3345 3346 /++ 3347 Whether this interval is before the given interval and does not 3348 intersect it. 3349 3350 Always returns false (unless the given interval is empty) because an 3351 interval going to positive infinity can never be before any other 3352 interval. 3353 3354 Params: 3355 interval = The interval to check for against this interval. 3356 3357 Throws: 3358 $(REF DateTimeException,std,datetime,date) if the given interval 3359 is empty. 3360 3361 Example: 3362 -------------------- 3363 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( 3364 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 3365 3366 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( 3367 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 3368 -------------------- 3369 +/ 3370 bool isBefore(scope const Interval!TP interval) const pure 3371 { 3372 interval._enforceNotEmpty(); 3373 return false; 3374 } 3375 3376 3377 /++ 3378 Whether this interval is before the given interval and does not 3379 intersect it. 3380 3381 Always returns false because an interval going to positive infinity can 3382 never be before any other interval. 3383 3384 Params: 3385 interval = The interval to check for against this interval. 3386 3387 Example: 3388 -------------------- 3389 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( 3390 PosInfInterval!Date(Date(1992, 5, 4)))); 3391 3392 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( 3393 PosInfInterval!Date(Date(2013, 3, 7)))); 3394 -------------------- 3395 +/ 3396 bool isBefore(scope const PosInfInterval interval) const pure nothrow 3397 { 3398 return false; 3399 } 3400 3401 3402 /++ 3403 Whether this interval is before the given interval and does not 3404 intersect it. 3405 3406 Always returns false because an interval going to positive infinity can 3407 never be before any other interval. 3408 3409 Params: 3410 interval = The interval to check for against this interval. 3411 3412 Example: 3413 -------------------- 3414 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( 3415 NegInfInterval!Date(Date(1996, 5, 4)))); 3416 -------------------- 3417 +/ 3418 bool isBefore(scope const NegInfInterval!TP interval) const pure nothrow 3419 { 3420 return false; 3421 } 3422 3423 3424 /++ 3425 Whether this interval is after the given time point. 3426 3427 Params: 3428 timePoint = The time point to check whether this interval is after 3429 it. 3430 3431 Example: 3432 -------------------- 3433 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24))); 3434 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5))); 3435 -------------------- 3436 +/ 3437 bool isAfter(scope const TP timePoint) const pure nothrow 3438 { 3439 return timePoint < _begin; 3440 } 3441 3442 3443 /++ 3444 Whether this interval is after the given interval and does not intersect 3445 it. 3446 3447 Params: 3448 interval = The interval to check against this interval. 3449 3450 Throws: 3451 $(REF DateTimeException,std,datetime,date) if the given interval 3452 is empty. 3453 3454 Example: 3455 -------------------- 3456 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3457 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 3458 3459 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3460 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 3461 3462 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3463 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 3464 -------------------- 3465 +/ 3466 bool isAfter(scope const Interval!TP interval) const pure 3467 { 3468 interval._enforceNotEmpty(); 3469 return _begin >= interval._end; 3470 } 3471 3472 3473 /++ 3474 Whether this interval is after the given interval and does not intersect 3475 it. 3476 3477 Always returns false because an interval going to positive infinity can 3478 never be after another interval going to positive infinity. 3479 3480 Params: 3481 interval = The interval to check against this interval. 3482 3483 Example: 3484 -------------------- 3485 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3486 PosInfInterval!Date(Date(1990, 1, 7)))); 3487 3488 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3489 PosInfInterval!Date(Date(1999, 5, 4)))); 3490 -------------------- 3491 +/ 3492 bool isAfter(scope const PosInfInterval interval) const pure nothrow 3493 { 3494 return false; 3495 } 3496 3497 3498 /++ 3499 Whether this interval is after the given interval and does not intersect 3500 it. 3501 3502 Params: 3503 interval = The interval to check against this interval. 3504 3505 Example: 3506 -------------------- 3507 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3508 NegInfInterval!Date(Date(1996, 1, 2)))); 3509 3510 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( 3511 NegInfInterval!Date(Date(2000, 7, 1)))); 3512 -------------------- 3513 +/ 3514 bool isAfter(scope const NegInfInterval!TP interval) const pure nothrow 3515 { 3516 return _begin >= interval._end; 3517 } 3518 3519 3520 /++ 3521 Whether the given interval overlaps this interval. 3522 3523 Params: 3524 interval = The interval to check for intersection with this interval. 3525 3526 Throws: 3527 $(REF DateTimeException,std,datetime,date) if the given interval 3528 is empty. 3529 3530 Example: 3531 -------------------- 3532 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3533 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 3534 3535 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3536 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 3537 3538 assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3539 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 3540 -------------------- 3541 +/ 3542 bool intersects(scope const Interval!TP interval) const pure 3543 { 3544 interval._enforceNotEmpty(); 3545 return interval._end > _begin; 3546 } 3547 3548 3549 /++ 3550 Whether the given interval overlaps this interval. 3551 3552 Always returns true because two intervals going to positive infinity 3553 always overlap. 3554 3555 Params: 3556 interval = The interval to check for intersection with this 3557 interval. 3558 3559 Example: 3560 -------------------- 3561 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3562 PosInfInterval!Date(Date(1990, 1, 7)))); 3563 3564 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3565 PosInfInterval!Date(Date(1999, 5, 4)))); 3566 -------------------- 3567 +/ 3568 bool intersects(scope const PosInfInterval interval) const pure nothrow 3569 { 3570 return true; 3571 } 3572 3573 3574 /++ 3575 Whether the given interval overlaps this interval. 3576 3577 Params: 3578 interval = The interval to check for intersection with this 3579 interval. 3580 3581 Example: 3582 -------------------- 3583 assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3584 NegInfInterval!Date(Date(1996, 1, 2)))); 3585 3586 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( 3587 NegInfInterval!Date(Date(2000, 7, 1)))); 3588 -------------------- 3589 +/ 3590 bool intersects(scope const NegInfInterval!TP interval) const pure nothrow 3591 { 3592 return _begin < interval._end; 3593 } 3594 3595 3596 /++ 3597 Returns the intersection of two intervals 3598 3599 Params: 3600 interval = The interval to intersect with this interval. 3601 3602 Throws: 3603 $(REF DateTimeException,std,datetime,date) if the two intervals do 3604 not intersect or if the given interval is empty. 3605 3606 Example: 3607 -------------------- 3608 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( 3609 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 3610 Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); 3611 3612 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( 3613 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 3614 Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); 3615 -------------------- 3616 +/ 3617 Interval!TP intersection(scope const Interval!TP interval) const 3618 { 3619 import std.format : format; 3620 3621 enforce(this.intersects(interval), 3622 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 3623 3624 auto begin = _begin > interval._begin ? _begin : interval._begin; 3625 3626 return Interval!TP(begin, interval._end); 3627 } 3628 3629 3630 /++ 3631 Returns the intersection of two intervals 3632 3633 Params: 3634 interval = The interval to intersect with this interval. 3635 3636 Example: 3637 -------------------- 3638 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( 3639 PosInfInterval!Date(Date(1990, 7, 6))) == 3640 PosInfInterval!Date(Date(1996, 1 , 2))); 3641 3642 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( 3643 PosInfInterval!Date(Date(1999, 1, 12))) == 3644 PosInfInterval!Date(Date(1999, 1 , 12))); 3645 -------------------- 3646 +/ 3647 PosInfInterval intersection(scope const PosInfInterval interval) const pure nothrow 3648 { 3649 return PosInfInterval(_begin < interval._begin ? interval._begin : _begin); 3650 } 3651 3652 3653 /++ 3654 Returns the intersection of two intervals 3655 3656 Params: 3657 interval = The interval to intersect with this interval. 3658 3659 Throws: 3660 $(REF DateTimeException,std,datetime,date) if the two intervals do 3661 not intersect. 3662 3663 Example: 3664 -------------------- 3665 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( 3666 NegInfInterval!Date(Date(1999, 7, 6))) == 3667 Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); 3668 3669 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( 3670 NegInfInterval!Date(Date(2013, 1, 12))) == 3671 Interval!Date(Date(1996, 1 , 2), Date(2013, 1, 12))); 3672 -------------------- 3673 +/ 3674 Interval!TP intersection(scope const NegInfInterval!TP interval) const 3675 { 3676 import std.format : format; 3677 3678 enforce(this.intersects(interval), 3679 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 3680 3681 return Interval!TP(_begin, interval._end); 3682 } 3683 3684 3685 /++ 3686 Whether the given interval is adjacent to this interval. 3687 3688 Params: 3689 interval = The interval to check whether its adjecent to this 3690 interval. 3691 3692 Throws: 3693 $(REF DateTimeException,std,datetime,date) if the given interval 3694 is empty. 3695 3696 Example: 3697 -------------------- 3698 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( 3699 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 3700 3701 assert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent( 3702 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 3703 -------------------- 3704 +/ 3705 bool isAdjacent(scope const Interval!TP interval) const pure 3706 { 3707 interval._enforceNotEmpty(); 3708 return _begin == interval._end; 3709 } 3710 3711 3712 /++ 3713 Whether the given interval is adjacent to this interval. 3714 3715 Always returns false because two intervals going to positive infinity 3716 can never be adjacent to one another. 3717 3718 Params: 3719 interval = The interval to check whether its adjecent to this 3720 interval. 3721 3722 Example: 3723 -------------------- 3724 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( 3725 PosInfInterval!Date(Date(1990, 1, 7)))); 3726 3727 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( 3728 PosInfInterval!Date(Date(1996, 1, 2)))); 3729 -------------------- 3730 +/ 3731 bool isAdjacent(scope const PosInfInterval interval) const pure nothrow 3732 { 3733 return false; 3734 } 3735 3736 3737 /++ 3738 Whether the given interval is adjacent to this interval. 3739 3740 Params: 3741 interval = The interval to check whether its adjecent to this 3742 interval. 3743 3744 Example: 3745 -------------------- 3746 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( 3747 NegInfInterval!Date(Date(1996, 1, 2)))); 3748 3749 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( 3750 NegInfInterval!Date(Date(2000, 7, 1)))); 3751 -------------------- 3752 +/ 3753 bool isAdjacent(scope const NegInfInterval!TP interval) const pure nothrow 3754 { 3755 return _begin == interval._end; 3756 } 3757 3758 3759 /++ 3760 Returns the union of two intervals 3761 3762 Params: 3763 interval = The interval to merge with this interval. 3764 3765 Throws: 3766 $(REF DateTimeException,std,datetime,date) if the two intervals do 3767 not intersect and are not adjacent or if the given interval is 3768 empty. 3769 3770 Note: 3771 There is no overload for `merge` which takes a 3772 `NegInfInterval`, because an interval 3773 going from negative infinity to positive infinity 3774 is not possible. 3775 3776 Example: 3777 -------------------- 3778 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( 3779 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 3780 PosInfInterval!Date(Date(1990, 7 , 6))); 3781 3782 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( 3783 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 3784 PosInfInterval!Date(Date(1996, 1 , 2))); 3785 -------------------- 3786 +/ 3787 PosInfInterval merge(scope const Interval!TP interval) const 3788 { 3789 import std.format : format; 3790 3791 enforce(this.isAdjacent(interval) || this.intersects(interval), 3792 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); 3793 3794 return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); 3795 } 3796 3797 3798 /++ 3799 Returns the union of two intervals 3800 3801 Params: 3802 interval = The interval to merge with this interval. 3803 3804 Note: 3805 There is no overload for `merge` which takes a 3806 `NegInfInterval`, because an interval 3807 going from negative infinity to positive infinity 3808 is not possible. 3809 3810 Example: 3811 -------------------- 3812 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( 3813 PosInfInterval!Date(Date(1990, 7, 6))) == 3814 PosInfInterval!Date(Date(1990, 7 , 6))); 3815 3816 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( 3817 PosInfInterval!Date(Date(1999, 1, 12))) == 3818 PosInfInterval!Date(Date(1996, 1 , 2))); 3819 -------------------- 3820 +/ 3821 PosInfInterval merge(scope const PosInfInterval interval) const pure nothrow 3822 { 3823 return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); 3824 } 3825 3826 3827 /++ 3828 Returns an interval that covers from the earliest time point of two 3829 intervals up to (but not including) the latest time point of two 3830 intervals. 3831 3832 Params: 3833 interval = The interval to create a span together with this 3834 interval. 3835 3836 Throws: 3837 $(REF DateTimeException,std,datetime,date) if the given interval 3838 is empty. 3839 3840 Note: 3841 There is no overload for `span` which takes a 3842 `NegInfInterval`, because an interval 3843 going from negative infinity to positive infinity 3844 is not possible. 3845 3846 Example: 3847 -------------------- 3848 assert(PosInfInterval!Date(Date(1996, 1, 2)).span( 3849 Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) == 3850 PosInfInterval!Date(Date(500, 8, 9))); 3851 3852 assert(PosInfInterval!Date(Date(1996, 1, 2)).span( 3853 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 3854 PosInfInterval!Date(Date(1990, 7 , 6))); 3855 3856 assert(PosInfInterval!Date(Date(1996, 1, 2)).span( 3857 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 3858 PosInfInterval!Date(Date(1996, 1 , 2))); 3859 -------------------- 3860 +/ 3861 PosInfInterval span(scope const Interval!TP interval) const pure 3862 { 3863 interval._enforceNotEmpty(); 3864 return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); 3865 } 3866 3867 3868 /++ 3869 Returns an interval that covers from the earliest time point of two 3870 intervals up to (but not including) the latest time point of two 3871 intervals. 3872 3873 Params: 3874 interval = The interval to create a span together with this 3875 interval. 3876 3877 Note: 3878 There is no overload for `span` which takes a 3879 `NegInfInterval`, because an interval 3880 going from negative infinity to positive infinity 3881 is not possible. 3882 3883 Example: 3884 -------------------- 3885 assert(PosInfInterval!Date(Date(1996, 1, 2)).span( 3886 PosInfInterval!Date(Date(1990, 7, 6))) == 3887 PosInfInterval!Date(Date(1990, 7 , 6))); 3888 3889 assert(PosInfInterval!Date(Date(1996, 1, 2)).span( 3890 PosInfInterval!Date(Date(1999, 1, 12))) == 3891 PosInfInterval!Date(Date(1996, 1 , 2))); 3892 -------------------- 3893 +/ 3894 PosInfInterval span(scope const PosInfInterval interval) const pure nothrow 3895 { 3896 return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); 3897 } 3898 3899 3900 /++ 3901 Shifts the `begin` of this interval forward or backwards in time by 3902 the given duration (a positive duration shifts the interval forward; a 3903 negative duration shifts it backward). Effectively, it does 3904 $(D begin += duration). 3905 3906 Params: 3907 duration = The duration to shift the interval by. 3908 3909 Example: 3910 -------------------- 3911 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 3912 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 3913 3914 interval1.shift(dur!"days"(50)); 3915 assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21))); 3916 3917 interval2.shift(dur!"days"(-50)); 3918 assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13))); 3919 -------------------- 3920 +/ 3921 void shift(D)(D duration) pure nothrow 3922 if (__traits(compiles, begin + duration)) 3923 { 3924 _begin += duration; 3925 } 3926 3927 3928 static if (__traits(compiles, begin.add!"months"(1)) && 3929 __traits(compiles, begin.add!"years"(1))) 3930 { 3931 /++ 3932 Shifts the `begin` of this interval forward or backwards in time 3933 by the given number of years and/or months (a positive number of 3934 years and months shifts the interval forward; a negative number 3935 shifts it backward). It adds the years the given years and months to 3936 `begin`. It effectively calls `add!"years"()` and then 3937 `add!"months"()` on `begin` with the given number of years and 3938 months. 3939 3940 Params: 3941 years = The number of years to shift the interval by. 3942 months = The number of months to shift the interval by. 3943 allowOverflow = Whether the days should be allowed to overflow 3944 on `begin`, causing its month to increment. 3945 3946 Throws: 3947 $(REF DateTimeException,std,datetime,date) if this interval is 3948 empty or if the resulting interval would be invalid. 3949 3950 Example: 3951 -------------------- 3952 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 3953 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 3954 3955 interval1.shift(dur!"days"(50)); 3956 assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21))); 3957 3958 interval2.shift(dur!"days"(-50)); 3959 assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13))); 3960 -------------------- 3961 +/ 3962 void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) 3963 if (isIntegral!T) 3964 { 3965 auto begin = _begin; 3966 3967 begin.add!"years"(years, allowOverflow); 3968 begin.add!"months"(months, allowOverflow); 3969 3970 _begin = begin; 3971 } 3972 } 3973 3974 3975 /++ 3976 Expands the interval backwards in time. Effectively, it does 3977 $(D begin -= duration). 3978 3979 Params: 3980 duration = The duration to expand the interval by. 3981 3982 Example: 3983 -------------------- 3984 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 3985 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 3986 3987 interval1.expand(dur!"days"(2)); 3988 assert(interval1 == PosInfInterval!Date(Date(1995, 12, 31))); 3989 3990 interval2.expand(dur!"days"(-2)); 3991 assert(interval2 == PosInfInterval!Date(Date(1996, 1, 4))); 3992 -------------------- 3993 +/ 3994 void expand(D)(D duration) pure nothrow 3995 if (__traits(compiles, begin + duration)) 3996 { 3997 _begin -= duration; 3998 } 3999 4000 4001 static if (__traits(compiles, begin.add!"months"(1)) && 4002 __traits(compiles, begin.add!"years"(1))) 4003 { 4004 /++ 4005 Expands the interval forwards and/or backwards in time. Effectively, 4006 it subtracts the given number of months/years from `begin`. 4007 4008 Params: 4009 years = The number of years to expand the interval by. 4010 months = The number of months to expand the interval by. 4011 allowOverflow = Whether the days should be allowed to overflow 4012 on `begin`, causing its month to increment. 4013 4014 Throws: 4015 $(REF DateTimeException,std,datetime,date) if this interval is 4016 empty or if the resulting interval would be invalid. 4017 4018 Example: 4019 -------------------- 4020 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 4021 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 4022 4023 interval1.expand(2); 4024 assert(interval1 == PosInfInterval!Date(Date(1994, 1, 2))); 4025 4026 interval2.expand(-2); 4027 assert(interval2 == PosInfInterval!Date(Date(1998, 1, 2))); 4028 -------------------- 4029 +/ 4030 void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) 4031 if (isIntegral!T) 4032 { 4033 auto begin = _begin; 4034 4035 begin.add!"years"(-years, allowOverflow); 4036 begin.add!"months"(-months, allowOverflow); 4037 4038 _begin = begin; 4039 } 4040 } 4041 4042 4043 /++ 4044 Returns a range which iterates forward over the interval, starting 4045 at `begin`, using $(D_PARAM func) to generate each successive time 4046 point. 4047 4048 The range's `front` is the interval's `begin`. $(D_PARAM func) is 4049 used to generate the next `front` when `popFront` is called. If 4050 $(D_PARAM popFirst) is `PopFirst.yes`, then `popFront` is called 4051 before the range is returned (so that `front` is a time point which 4052 $(D_PARAM func) would generate). 4053 4054 If $(D_PARAM func) ever generates a time point less than or equal to the 4055 current `front` of the range, then a 4056 $(REF DateTimeException,std,datetime,date) will be thrown. 4057 4058 There are helper functions in this module which generate common 4059 delegates to pass to `fwdRange`. Their documentation starts with 4060 "Range-generating function," to make them easily searchable. 4061 4062 Params: 4063 func = The function used to generate the time points of the 4064 range over the interval. 4065 popFirst = Whether `popFront` should be called on the range 4066 before returning it. 4067 4068 Throws: 4069 $(REF DateTimeException,std,datetime,date) if this interval is 4070 empty. 4071 4072 Warning: 4073 $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) 4074 would be a function pointer to a pure function, but forcing 4075 $(D_PARAM func) to be pure is far too restrictive to be useful, and 4076 in order to have the ease of use of having functions which generate 4077 functions to pass to `fwdRange`, $(D_PARAM func) must be a 4078 delegate. 4079 4080 If $(D_PARAM func) retains state which changes as it is called, then 4081 some algorithms will not work correctly, because the range's 4082 `save` will have failed to have really saved the range's state. 4083 To avoid such bugs, don't pass a delegate which is 4084 not logically pure to `fwdRange`. If $(D_PARAM func) is given the 4085 same time point with two different calls, it must return the same 4086 result both times. 4087 4088 Of course, none of the functions in this module have this problem, 4089 so it's only relevant for custom delegates. 4090 4091 Example: 4092 -------------------- 4093 auto interval = PosInfInterval!Date(Date(2010, 9, 1)); 4094 auto func = delegate (scope const Date date) //For iterating over even-numbered days. 4095 { 4096 if ((date.day & 1) == 0) 4097 return date + dur!"days"(2); 4098 4099 return date + dur!"days"(1); 4100 }; 4101 auto range = interval.fwdRange(func); 4102 4103 //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). 4104 assert(range.front == Date(2010, 9, 1)); 4105 4106 range.popFront(); 4107 assert(range.front == Date(2010, 9, 2)); 4108 4109 range.popFront(); 4110 assert(range.front == Date(2010, 9, 4)); 4111 4112 range.popFront(); 4113 assert(range.front == Date(2010, 9, 6)); 4114 4115 range.popFront(); 4116 assert(range.front == Date(2010, 9, 8)); 4117 4118 range.popFront(); 4119 assert(!range.empty); 4120 -------------------- 4121 +/ 4122 PosInfIntervalRange!(TP) fwdRange(TP delegate(scope const TP) func, PopFirst popFirst = PopFirst.no) const 4123 { 4124 auto range = PosInfIntervalRange!(TP)(this, func); 4125 4126 if (popFirst == PopFirst.yes) 4127 range.popFront(); 4128 4129 return range; 4130 } 4131 4132 4133 /+ 4134 Converts this interval to a string. 4135 +/ 4136 // Due to bug https://issues.dlang.org/show_bug.cgi?id=3715 , we can't 4137 // have versions of toString() with extra modifiers, 4138 // so we define one version with modifiers and one without. 4139 string toString() 4140 { 4141 return _toStringImpl(); 4142 } 4143 4144 4145 /++ 4146 Converts this interval to a string. 4147 +/ 4148 // Due to bug https://issues.dlang.org/show_bug.cgi?id=3715 , we can't 4149 // have versions of toString() with extra modifiers, 4150 // so we define one version with modifiers and one without. 4151 string toString() const nothrow 4152 { 4153 return _toStringImpl(); 4154 } 4155 4156 private: 4157 4158 /+ 4159 Since we have two versions of toString(), we have _toStringImpl() 4160 so that they can share implementations. 4161 +/ 4162 string _toStringImpl() const nothrow 4163 { 4164 import std.format : format; 4165 try 4166 return format("[%s - ∞)", _begin); 4167 catch (Exception e) 4168 assert(0, "format() threw."); 4169 } 4170 4171 4172 TP _begin; 4173 } 4174 4175 //Test PosInfInterval's constructor. 4176 @safe unittest 4177 { 4178 import std.datetime.date; 4179 import std.datetime.systime; 4180 4181 PosInfInterval!Date(Date.init); 4182 PosInfInterval!TimeOfDay(TimeOfDay.init); 4183 PosInfInterval!DateTime(DateTime.init); 4184 PosInfInterval!SysTime(SysTime(0)); 4185 4186 //Verify Examples. 4187 auto interval = PosInfInterval!Date(Date(1996, 1, 2)); 4188 } 4189 4190 //Test PosInfInterval's begin. 4191 @safe unittest 4192 { 4193 import std.datetime.date; 4194 4195 assert(PosInfInterval!Date(Date(1, 1, 1)).begin == Date(1, 1, 1)); 4196 assert(PosInfInterval!Date(Date(2010, 1, 1)).begin == Date(2010, 1, 1)); 4197 assert(PosInfInterval!Date(Date(1997, 12, 31)).begin == Date(1997, 12, 31)); 4198 4199 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4200 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4201 assert(cPosInfInterval.begin != Date.init); 4202 assert(iPosInfInterval.begin != Date.init); 4203 4204 //Verify Examples. 4205 assert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2)); 4206 } 4207 4208 //Test PosInfInterval's empty. 4209 @safe unittest 4210 { 4211 import std.datetime.date; 4212 import std.datetime.systime; 4213 4214 assert(!PosInfInterval!Date(Date(2010, 1, 1)).empty); 4215 assert(!PosInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty); 4216 assert(!PosInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty); 4217 assert(!PosInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty); 4218 4219 const cPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4220 immutable iPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4221 assert(!cPosInfInterval.empty); 4222 assert(!iPosInfInterval.empty); 4223 4224 //Verify Examples. 4225 assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty); 4226 } 4227 4228 //Test PosInfInterval's contains(time point). 4229 @safe unittest 4230 { 4231 import std.datetime.date; 4232 4233 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4234 4235 assert(!posInfInterval.contains(Date(2009, 7, 4))); 4236 assert(!posInfInterval.contains(Date(2010, 7, 3))); 4237 assert(posInfInterval.contains(Date(2010, 7, 4))); 4238 assert(posInfInterval.contains(Date(2010, 7, 5))); 4239 assert(posInfInterval.contains(Date(2011, 7, 1))); 4240 assert(posInfInterval.contains(Date(2012, 1, 6))); 4241 assert(posInfInterval.contains(Date(2012, 1, 7))); 4242 assert(posInfInterval.contains(Date(2012, 1, 8))); 4243 assert(posInfInterval.contains(Date(2013, 1, 7))); 4244 4245 const cdate = Date(2010, 7, 6); 4246 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4247 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4248 assert(posInfInterval.contains(cdate)); 4249 assert(cPosInfInterval.contains(cdate)); 4250 assert(iPosInfInterval.contains(cdate)); 4251 4252 //Verify Examples. 4253 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24))); 4254 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5))); 4255 } 4256 4257 //Test PosInfInterval's contains(Interval). 4258 @safe unittest 4259 { 4260 import std.datetime.date; 4261 4262 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4263 4264 static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) 4265 { 4266 posInfInterval.contains(interval); 4267 } 4268 4269 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4270 4271 assert(posInfInterval.contains(posInfInterval)); 4272 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4273 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 4274 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 4275 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 4276 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 4277 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 4278 assert(posInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 4279 assert(posInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 4280 assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 4281 assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 4282 assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 4283 assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 4284 4285 assert(!posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 3)))); 4286 assert(posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 4)))); 4287 assert(posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 5)))); 4288 assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 6)))); 4289 assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 7)))); 4290 assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 8)))); 4291 4292 assert(PosInfInterval!Date(Date(2010, 7, 3)).contains(posInfInterval)); 4293 assert(PosInfInterval!Date(Date(2010, 7, 4)).contains(posInfInterval)); 4294 assert(!PosInfInterval!Date(Date(2010, 7, 5)).contains(posInfInterval)); 4295 assert(!PosInfInterval!Date(Date(2012, 1, 6)).contains(posInfInterval)); 4296 assert(!PosInfInterval!Date(Date(2012, 1, 7)).contains(posInfInterval)); 4297 assert(!PosInfInterval!Date(Date(2012, 1, 8)).contains(posInfInterval)); 4298 4299 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 3)))); 4300 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 4)))); 4301 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 5)))); 4302 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 6)))); 4303 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 7)))); 4304 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 8)))); 4305 4306 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4307 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4308 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4309 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4310 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4311 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4312 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4313 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4314 assert(posInfInterval.contains(interval)); 4315 assert(posInfInterval.contains(cInterval)); 4316 assert(posInfInterval.contains(iInterval)); 4317 assert(posInfInterval.contains(posInfInterval)); 4318 assert(posInfInterval.contains(cPosInfInterval)); 4319 assert(posInfInterval.contains(iPosInfInterval)); 4320 assert(!posInfInterval.contains(negInfInterval)); 4321 assert(!posInfInterval.contains(cNegInfInterval)); 4322 assert(!posInfInterval.contains(iNegInfInterval)); 4323 assert(cPosInfInterval.contains(interval)); 4324 assert(cPosInfInterval.contains(cInterval)); 4325 assert(cPosInfInterval.contains(iInterval)); 4326 assert(cPosInfInterval.contains(posInfInterval)); 4327 assert(cPosInfInterval.contains(cPosInfInterval)); 4328 assert(cPosInfInterval.contains(iPosInfInterval)); 4329 assert(!cPosInfInterval.contains(negInfInterval)); 4330 assert(!cPosInfInterval.contains(cNegInfInterval)); 4331 assert(!cPosInfInterval.contains(iNegInfInterval)); 4332 assert(iPosInfInterval.contains(interval)); 4333 assert(iPosInfInterval.contains(cInterval)); 4334 assert(iPosInfInterval.contains(iInterval)); 4335 assert(iPosInfInterval.contains(posInfInterval)); 4336 assert(iPosInfInterval.contains(cPosInfInterval)); 4337 assert(iPosInfInterval.contains(iPosInfInterval)); 4338 assert(!iPosInfInterval.contains(negInfInterval)); 4339 assert(!iPosInfInterval.contains(cNegInfInterval)); 4340 assert(!iPosInfInterval.contains(iNegInfInterval)); 4341 4342 //Verify Examples. 4343 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 4344 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 4345 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); 4346 4347 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(PosInfInterval!Date(Date(1999, 5, 4)))); 4348 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(PosInfInterval!Date(Date(1995, 7, 2)))); 4349 4350 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(NegInfInterval!Date(Date(1996, 5, 4)))); 4351 } 4352 4353 //Test PosInfInterval's isBefore(time point). 4354 @safe unittest 4355 { 4356 import std.datetime.date; 4357 4358 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4359 4360 assert(!posInfInterval.isBefore(Date(2009, 7, 3))); 4361 assert(!posInfInterval.isBefore(Date(2010, 7, 3))); 4362 assert(!posInfInterval.isBefore(Date(2010, 7, 4))); 4363 assert(!posInfInterval.isBefore(Date(2010, 7, 5))); 4364 assert(!posInfInterval.isBefore(Date(2011, 7, 1))); 4365 assert(!posInfInterval.isBefore(Date(2012, 1, 6))); 4366 assert(!posInfInterval.isBefore(Date(2012, 1, 7))); 4367 assert(!posInfInterval.isBefore(Date(2012, 1, 8))); 4368 assert(!posInfInterval.isBefore(Date(2013, 1, 7))); 4369 4370 const cdate = Date(2010, 7, 6); 4371 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4372 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4373 assert(!posInfInterval.isBefore(cdate)); 4374 assert(!cPosInfInterval.isBefore(cdate)); 4375 assert(!iPosInfInterval.isBefore(cdate)); 4376 4377 //Verify Examples. 4378 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24))); 4379 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5))); 4380 } 4381 4382 //Test PosInfInterval's isBefore(Interval). 4383 @safe unittest 4384 { 4385 import std.datetime.date; 4386 4387 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4388 4389 static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) 4390 { 4391 posInfInterval.isBefore(interval); 4392 } 4393 4394 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4395 4396 assert(!posInfInterval.isBefore(posInfInterval)); 4397 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4398 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 4399 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 4400 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 4401 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 4402 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 4403 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 4404 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 4405 assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 4406 assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 4407 assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 4408 assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 4409 4410 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 3)))); 4411 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 4)))); 4412 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 5)))); 4413 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 6)))); 4414 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 7)))); 4415 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 8)))); 4416 4417 assert(!PosInfInterval!Date(Date(2010, 7, 3)).isBefore(posInfInterval)); 4418 assert(!PosInfInterval!Date(Date(2010, 7, 4)).isBefore(posInfInterval)); 4419 assert(!PosInfInterval!Date(Date(2010, 7, 5)).isBefore(posInfInterval)); 4420 assert(!PosInfInterval!Date(Date(2012, 1, 6)).isBefore(posInfInterval)); 4421 assert(!PosInfInterval!Date(Date(2012, 1, 7)).isBefore(posInfInterval)); 4422 assert(!PosInfInterval!Date(Date(2012, 1, 8)).isBefore(posInfInterval)); 4423 4424 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 3)))); 4425 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 4)))); 4426 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 5)))); 4427 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 6)))); 4428 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 7)))); 4429 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 8)))); 4430 4431 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4432 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4433 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4434 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4435 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4436 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4437 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4438 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4439 assert(!posInfInterval.isBefore(interval)); 4440 assert(!posInfInterval.isBefore(cInterval)); 4441 assert(!posInfInterval.isBefore(iInterval)); 4442 assert(!posInfInterval.isBefore(posInfInterval)); 4443 assert(!posInfInterval.isBefore(cPosInfInterval)); 4444 assert(!posInfInterval.isBefore(iPosInfInterval)); 4445 assert(!posInfInterval.isBefore(negInfInterval)); 4446 assert(!posInfInterval.isBefore(cNegInfInterval)); 4447 assert(!posInfInterval.isBefore(iNegInfInterval)); 4448 assert(!cPosInfInterval.isBefore(interval)); 4449 assert(!cPosInfInterval.isBefore(cInterval)); 4450 assert(!cPosInfInterval.isBefore(iInterval)); 4451 assert(!cPosInfInterval.isBefore(posInfInterval)); 4452 assert(!cPosInfInterval.isBefore(cPosInfInterval)); 4453 assert(!cPosInfInterval.isBefore(iPosInfInterval)); 4454 assert(!cPosInfInterval.isBefore(negInfInterval)); 4455 assert(!cPosInfInterval.isBefore(cNegInfInterval)); 4456 assert(!cPosInfInterval.isBefore(iNegInfInterval)); 4457 assert(!iPosInfInterval.isBefore(interval)); 4458 assert(!iPosInfInterval.isBefore(cInterval)); 4459 assert(!iPosInfInterval.isBefore(iInterval)); 4460 assert(!iPosInfInterval.isBefore(posInfInterval)); 4461 assert(!iPosInfInterval.isBefore(cPosInfInterval)); 4462 assert(!iPosInfInterval.isBefore(iPosInfInterval)); 4463 assert(!iPosInfInterval.isBefore(negInfInterval)); 4464 assert(!iPosInfInterval.isBefore(cNegInfInterval)); 4465 assert(!iPosInfInterval.isBefore(iNegInfInterval)); 4466 4467 //Verify Examples. 4468 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 4469 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 4470 4471 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(PosInfInterval!Date(Date(1992, 5, 4)))); 4472 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(PosInfInterval!Date(Date(2013, 3, 7)))); 4473 4474 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(NegInfInterval!Date(Date(1996, 5, 4)))); 4475 } 4476 4477 //Test PosInfInterval's isAfter(time point). 4478 @safe unittest 4479 { 4480 import std.datetime.date; 4481 4482 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4483 4484 assert(posInfInterval.isAfter(Date(2009, 7, 3))); 4485 assert(posInfInterval.isAfter(Date(2010, 7, 3))); 4486 assert(!posInfInterval.isAfter(Date(2010, 7, 4))); 4487 assert(!posInfInterval.isAfter(Date(2010, 7, 5))); 4488 assert(!posInfInterval.isAfter(Date(2011, 7, 1))); 4489 assert(!posInfInterval.isAfter(Date(2012, 1, 6))); 4490 assert(!posInfInterval.isAfter(Date(2012, 1, 7))); 4491 assert(!posInfInterval.isAfter(Date(2012, 1, 8))); 4492 assert(!posInfInterval.isAfter(Date(2013, 1, 7))); 4493 4494 const cdate = Date(2010, 7, 6); 4495 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4496 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4497 assert(!posInfInterval.isAfter(cdate)); 4498 assert(!cPosInfInterval.isAfter(cdate)); 4499 assert(!iPosInfInterval.isAfter(cdate)); 4500 4501 //Verify Examples. 4502 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24))); 4503 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5))); 4504 } 4505 4506 //Test PosInfInterval's isAfter(Interval). 4507 @safe unittest 4508 { 4509 import std.datetime.date; 4510 4511 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4512 4513 static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) 4514 { 4515 posInfInterval.isAfter(interval); 4516 } 4517 4518 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4519 4520 assert(!posInfInterval.isAfter(posInfInterval)); 4521 assert(posInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4522 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 4523 assert(posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 4524 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 4525 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 4526 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 4527 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 4528 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 4529 assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 4530 assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 4531 assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 4532 assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 4533 4534 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 3)))); 4535 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 4)))); 4536 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 5)))); 4537 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 6)))); 4538 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 7)))); 4539 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 8)))); 4540 4541 assert(!PosInfInterval!Date(Date(2010, 7, 3)).isAfter(posInfInterval)); 4542 assert(!PosInfInterval!Date(Date(2010, 7, 4)).isAfter(posInfInterval)); 4543 assert(!PosInfInterval!Date(Date(2010, 7, 5)).isAfter(posInfInterval)); 4544 assert(!PosInfInterval!Date(Date(2012, 1, 6)).isAfter(posInfInterval)); 4545 assert(!PosInfInterval!Date(Date(2012, 1, 7)).isAfter(posInfInterval)); 4546 assert(!PosInfInterval!Date(Date(2012, 1, 8)).isAfter(posInfInterval)); 4547 4548 assert(posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 3)))); 4549 assert(posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 4)))); 4550 assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 5)))); 4551 assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 6)))); 4552 assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 7)))); 4553 assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 8)))); 4554 4555 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4556 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4557 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4558 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4559 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4560 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4561 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4562 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4563 assert(!posInfInterval.isAfter(interval)); 4564 assert(!posInfInterval.isAfter(cInterval)); 4565 assert(!posInfInterval.isAfter(iInterval)); 4566 assert(!posInfInterval.isAfter(posInfInterval)); 4567 assert(!posInfInterval.isAfter(cPosInfInterval)); 4568 assert(!posInfInterval.isAfter(iPosInfInterval)); 4569 assert(!posInfInterval.isAfter(negInfInterval)); 4570 assert(!posInfInterval.isAfter(cNegInfInterval)); 4571 assert(!posInfInterval.isAfter(iNegInfInterval)); 4572 assert(!cPosInfInterval.isAfter(interval)); 4573 assert(!cPosInfInterval.isAfter(cInterval)); 4574 assert(!cPosInfInterval.isAfter(iInterval)); 4575 assert(!cPosInfInterval.isAfter(posInfInterval)); 4576 assert(!cPosInfInterval.isAfter(cPosInfInterval)); 4577 assert(!cPosInfInterval.isAfter(iPosInfInterval)); 4578 assert(!cPosInfInterval.isAfter(negInfInterval)); 4579 assert(!cPosInfInterval.isAfter(cNegInfInterval)); 4580 assert(!cPosInfInterval.isAfter(iNegInfInterval)); 4581 assert(!iPosInfInterval.isAfter(interval)); 4582 assert(!iPosInfInterval.isAfter(cInterval)); 4583 assert(!iPosInfInterval.isAfter(iInterval)); 4584 assert(!iPosInfInterval.isAfter(posInfInterval)); 4585 assert(!iPosInfInterval.isAfter(cPosInfInterval)); 4586 assert(!iPosInfInterval.isAfter(iPosInfInterval)); 4587 assert(!iPosInfInterval.isAfter(negInfInterval)); 4588 assert(!iPosInfInterval.isAfter(cNegInfInterval)); 4589 assert(!iPosInfInterval.isAfter(iNegInfInterval)); 4590 4591 //Verify Examples. 4592 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 4593 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 4594 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 4595 4596 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(PosInfInterval!Date(Date(1990, 1, 7)))); 4597 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(PosInfInterval!Date(Date(1999, 5, 4)))); 4598 4599 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(NegInfInterval!Date(Date(1996, 1, 2)))); 4600 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(NegInfInterval!Date(Date(2000, 7, 1)))); 4601 } 4602 4603 //Test PosInfInterval's intersects(). 4604 @safe unittest 4605 { 4606 import std.datetime.date; 4607 4608 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4609 4610 static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) 4611 { 4612 posInfInterval.intersects(interval); 4613 } 4614 4615 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4616 4617 assert(posInfInterval.intersects(posInfInterval)); 4618 assert(!posInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4619 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 4620 assert(!posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 4621 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 4622 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 4623 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 4624 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 4625 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 4626 assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 4627 assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 4628 assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 4629 assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 4630 4631 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 3)))); 4632 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 4)))); 4633 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 5)))); 4634 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 6)))); 4635 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 7)))); 4636 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 8)))); 4637 4638 assert(PosInfInterval!Date(Date(2010, 7, 3)).intersects(posInfInterval)); 4639 assert(PosInfInterval!Date(Date(2010, 7, 4)).intersects(posInfInterval)); 4640 assert(PosInfInterval!Date(Date(2010, 7, 5)).intersects(posInfInterval)); 4641 assert(PosInfInterval!Date(Date(2012, 1, 6)).intersects(posInfInterval)); 4642 assert(PosInfInterval!Date(Date(2012, 1, 7)).intersects(posInfInterval)); 4643 assert(PosInfInterval!Date(Date(2012, 1, 8)).intersects(posInfInterval)); 4644 4645 assert(!posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 3)))); 4646 assert(!posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 4)))); 4647 assert(posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 5)))); 4648 assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 6)))); 4649 assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 7)))); 4650 assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 8)))); 4651 4652 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4653 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4654 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4655 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4656 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4657 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4658 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4659 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4660 assert(posInfInterval.intersects(interval)); 4661 assert(posInfInterval.intersects(cInterval)); 4662 assert(posInfInterval.intersects(iInterval)); 4663 assert(posInfInterval.intersects(posInfInterval)); 4664 assert(posInfInterval.intersects(cPosInfInterval)); 4665 assert(posInfInterval.intersects(iPosInfInterval)); 4666 assert(posInfInterval.intersects(negInfInterval)); 4667 assert(posInfInterval.intersects(cNegInfInterval)); 4668 assert(posInfInterval.intersects(iNegInfInterval)); 4669 assert(cPosInfInterval.intersects(interval)); 4670 assert(cPosInfInterval.intersects(cInterval)); 4671 assert(cPosInfInterval.intersects(iInterval)); 4672 assert(cPosInfInterval.intersects(posInfInterval)); 4673 assert(cPosInfInterval.intersects(cPosInfInterval)); 4674 assert(cPosInfInterval.intersects(iPosInfInterval)); 4675 assert(cPosInfInterval.intersects(negInfInterval)); 4676 assert(cPosInfInterval.intersects(cNegInfInterval)); 4677 assert(cPosInfInterval.intersects(iNegInfInterval)); 4678 assert(iPosInfInterval.intersects(interval)); 4679 assert(iPosInfInterval.intersects(cInterval)); 4680 assert(iPosInfInterval.intersects(iInterval)); 4681 assert(iPosInfInterval.intersects(posInfInterval)); 4682 assert(iPosInfInterval.intersects(cPosInfInterval)); 4683 assert(iPosInfInterval.intersects(iPosInfInterval)); 4684 assert(iPosInfInterval.intersects(negInfInterval)); 4685 assert(iPosInfInterval.intersects(cNegInfInterval)); 4686 assert(iPosInfInterval.intersects(iNegInfInterval)); 4687 4688 //Verify Examples. 4689 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 4690 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 4691 assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 4692 4693 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(PosInfInterval!Date(Date(1990, 1, 7)))); 4694 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(PosInfInterval!Date(Date(1999, 5, 4)))); 4695 4696 assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(NegInfInterval!Date(Date(1996, 1, 2)))); 4697 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(NegInfInterval!Date(Date(2000, 7, 1)))); 4698 } 4699 4700 //Test PosInfInterval's intersection(). 4701 @safe unittest 4702 { 4703 import std.datetime.date; 4704 4705 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4706 4707 static void testInterval(I, J)(scope const I interval1, scope const J interval2) 4708 { 4709 interval1.intersection(interval2); 4710 } 4711 4712 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4713 4714 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4715 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 4716 4717 assertThrown!DateTimeException(testInterval(posInfInterval, NegInfInterval!Date(Date(2010, 7, 3)))); 4718 assertThrown!DateTimeException(testInterval(posInfInterval, NegInfInterval!Date(Date(2010, 7, 4)))); 4719 4720 assert(posInfInterval.intersection(posInfInterval) == posInfInterval); 4721 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 4722 Interval!Date(Date(2010, 7, 4), Date(2013, 7, 3))); 4723 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 4724 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); 4725 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 4726 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 4727 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 4728 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 4729 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 4730 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); 4731 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 4732 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); 4733 assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 4734 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 4735 assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 4736 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))); 4737 assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 4738 Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))); 4739 assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == 4740 Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))); 4741 4742 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 4))); 4743 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4))); 4744 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 5))); 4745 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2012, 1, 6))); 4746 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2012, 1, 7))); 4747 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2012, 1, 8))); 4748 4749 assert(PosInfInterval!Date(Date(2010, 7, 3)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4750 assert(PosInfInterval!Date(Date(2010, 7, 4)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4751 assert(PosInfInterval!Date(Date(2010, 7, 5)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 5))); 4752 assert(PosInfInterval!Date(Date(2012, 1, 6)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 6))); 4753 assert(PosInfInterval!Date(Date(2012, 1, 7)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 7))); 4754 assert(PosInfInterval!Date(Date(2012, 1, 8)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 8))); 4755 4756 assert(posInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == 4757 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); 4758 assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == 4759 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6))); 4760 assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == 4761 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); 4762 assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == 4763 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); 4764 4765 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4766 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4767 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4768 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4769 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4770 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4771 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4772 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4773 assert(!posInfInterval.intersection(interval).empty); 4774 assert(!posInfInterval.intersection(cInterval).empty); 4775 assert(!posInfInterval.intersection(iInterval).empty); 4776 assert(!posInfInterval.intersection(posInfInterval).empty); 4777 assert(!posInfInterval.intersection(cPosInfInterval).empty); 4778 assert(!posInfInterval.intersection(iPosInfInterval).empty); 4779 assert(!posInfInterval.intersection(negInfInterval).empty); 4780 assert(!posInfInterval.intersection(cNegInfInterval).empty); 4781 assert(!posInfInterval.intersection(iNegInfInterval).empty); 4782 assert(!cPosInfInterval.intersection(interval).empty); 4783 assert(!cPosInfInterval.intersection(cInterval).empty); 4784 assert(!cPosInfInterval.intersection(iInterval).empty); 4785 assert(!cPosInfInterval.intersection(posInfInterval).empty); 4786 assert(!cPosInfInterval.intersection(cPosInfInterval).empty); 4787 assert(!cPosInfInterval.intersection(iPosInfInterval).empty); 4788 assert(!cPosInfInterval.intersection(negInfInterval).empty); 4789 assert(!cPosInfInterval.intersection(cNegInfInterval).empty); 4790 assert(!cPosInfInterval.intersection(iNegInfInterval).empty); 4791 assert(!iPosInfInterval.intersection(interval).empty); 4792 assert(!iPosInfInterval.intersection(cInterval).empty); 4793 assert(!iPosInfInterval.intersection(iInterval).empty); 4794 assert(!iPosInfInterval.intersection(posInfInterval).empty); 4795 assert(!iPosInfInterval.intersection(cPosInfInterval).empty); 4796 assert(!iPosInfInterval.intersection(iPosInfInterval).empty); 4797 assert(!iPosInfInterval.intersection(negInfInterval).empty); 4798 assert(!iPosInfInterval.intersection(cNegInfInterval).empty); 4799 assert(!iPosInfInterval.intersection(iNegInfInterval).empty); 4800 4801 //Verify Examples. 4802 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 4803 Interval!Date(Date(1996, 1, 2), Date(2000, 8, 2))); 4804 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 4805 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))); 4806 4807 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) == 4808 PosInfInterval!Date(Date(1996, 1, 2))); 4809 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) == 4810 PosInfInterval!Date(Date(1999, 1, 12))); 4811 4812 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) == 4813 Interval!Date(Date(1996, 1, 2), Date(1999, 7, 6))); 4814 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) == 4815 Interval!Date(Date(1996, 1, 2), Date(2013, 1, 12))); 4816 } 4817 4818 //Test PosInfInterval's isAdjacent(). 4819 @safe unittest 4820 { 4821 import std.datetime.date; 4822 4823 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4824 4825 static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) 4826 { 4827 posInfInterval.isAdjacent(interval); 4828 } 4829 4830 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4831 4832 assert(!posInfInterval.isAdjacent(posInfInterval)); 4833 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4834 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 4835 assert(posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 4836 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 4837 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 4838 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 4839 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 4840 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 4841 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 4842 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 4843 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 4844 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 4845 4846 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3)))); 4847 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4)))); 4848 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5)))); 4849 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6)))); 4850 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7)))); 4851 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8)))); 4852 4853 assert(!PosInfInterval!Date(Date(2010, 7, 3)).isAdjacent(posInfInterval)); 4854 assert(!PosInfInterval!Date(Date(2010, 7, 4)).isAdjacent(posInfInterval)); 4855 assert(!PosInfInterval!Date(Date(2010, 7, 5)).isAdjacent(posInfInterval)); 4856 assert(!PosInfInterval!Date(Date(2012, 1, 6)).isAdjacent(posInfInterval)); 4857 assert(!PosInfInterval!Date(Date(2012, 1, 7)).isAdjacent(posInfInterval)); 4858 assert(!PosInfInterval!Date(Date(2012, 1, 8)).isAdjacent(posInfInterval)); 4859 4860 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3)))); 4861 assert(posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4)))); 4862 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5)))); 4863 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6)))); 4864 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7)))); 4865 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8)))); 4866 4867 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4868 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4869 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4870 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4871 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4872 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4873 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4874 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4875 assert(!posInfInterval.isAdjacent(interval)); 4876 assert(!posInfInterval.isAdjacent(cInterval)); 4877 assert(!posInfInterval.isAdjacent(iInterval)); 4878 assert(!posInfInterval.isAdjacent(posInfInterval)); 4879 assert(!posInfInterval.isAdjacent(cPosInfInterval)); 4880 assert(!posInfInterval.isAdjacent(iPosInfInterval)); 4881 assert(!posInfInterval.isAdjacent(negInfInterval)); 4882 assert(!posInfInterval.isAdjacent(cNegInfInterval)); 4883 assert(!posInfInterval.isAdjacent(iNegInfInterval)); 4884 assert(!cPosInfInterval.isAdjacent(interval)); 4885 assert(!cPosInfInterval.isAdjacent(cInterval)); 4886 assert(!cPosInfInterval.isAdjacent(iInterval)); 4887 assert(!cPosInfInterval.isAdjacent(posInfInterval)); 4888 assert(!cPosInfInterval.isAdjacent(cPosInfInterval)); 4889 assert(!cPosInfInterval.isAdjacent(iPosInfInterval)); 4890 assert(!cPosInfInterval.isAdjacent(negInfInterval)); 4891 assert(!cPosInfInterval.isAdjacent(cNegInfInterval)); 4892 assert(!cPosInfInterval.isAdjacent(iNegInfInterval)); 4893 assert(!iPosInfInterval.isAdjacent(interval)); 4894 assert(!iPosInfInterval.isAdjacent(cInterval)); 4895 assert(!iPosInfInterval.isAdjacent(iInterval)); 4896 assert(!iPosInfInterval.isAdjacent(posInfInterval)); 4897 assert(!iPosInfInterval.isAdjacent(cPosInfInterval)); 4898 assert(!iPosInfInterval.isAdjacent(iPosInfInterval)); 4899 assert(!iPosInfInterval.isAdjacent(negInfInterval)); 4900 assert(!iPosInfInterval.isAdjacent(cNegInfInterval)); 4901 assert(!iPosInfInterval.isAdjacent(iNegInfInterval)); 4902 4903 //Verify Examples. 4904 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); 4905 assert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 4906 4907 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(PosInfInterval!Date(Date(1990, 1, 7)))); 4908 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(PosInfInterval!Date(Date(1996, 1, 2)))); 4909 4910 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2)))); 4911 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(NegInfInterval!Date(Date(2000, 7, 1)))); 4912 } 4913 4914 //Test PosInfInterval's merge(). 4915 @safe unittest 4916 { 4917 import std.datetime.date; 4918 4919 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4920 4921 static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) 4922 { 4923 posInfInterval.merge(interval); 4924 } 4925 4926 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 4927 4928 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 4929 4930 assert(posInfInterval.merge(posInfInterval) == posInfInterval); 4931 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 4932 PosInfInterval!Date(Date(2010, 7, 1))); 4933 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 4934 PosInfInterval!Date(Date(2010, 7, 3))); 4935 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 4936 PosInfInterval!Date(Date(2010, 7, 3))); 4937 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 4938 PosInfInterval!Date(Date(2010, 7, 3))); 4939 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 4940 PosInfInterval!Date(Date(2010, 7, 3))); 4941 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 4942 PosInfInterval!Date(Date(2010, 7, 4))); 4943 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 4944 PosInfInterval!Date(Date(2010, 7, 4))); 4945 assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 4946 PosInfInterval!Date(Date(2010, 7, 4))); 4947 assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 4948 PosInfInterval!Date(Date(2010, 7, 4))); 4949 assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 4950 PosInfInterval!Date(Date(2010, 7, 4))); 4951 assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == 4952 PosInfInterval!Date(Date(2010, 7, 4))); 4953 4954 assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3))); 4955 assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4))); 4956 assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4))); 4957 assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4))); 4958 assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4))); 4959 assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4))); 4960 4961 assert(PosInfInterval!Date(Date(2010, 7, 3)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 3))); 4962 assert(PosInfInterval!Date(Date(2010, 7, 4)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4963 assert(PosInfInterval!Date(Date(2010, 7, 5)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4964 assert(PosInfInterval!Date(Date(2012, 1, 6)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4965 assert(PosInfInterval!Date(Date(2012, 1, 7)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4966 assert(PosInfInterval!Date(Date(2012, 1, 8)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 4967 4968 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 3))))); 4969 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 4))))); 4970 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 5))))); 4971 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 6))))); 4972 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 7))))); 4973 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 8))))); 4974 4975 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4976 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4977 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 4978 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4979 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 4980 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4981 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4982 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 4983 assert(!posInfInterval.merge(interval).empty); 4984 assert(!posInfInterval.merge(cInterval).empty); 4985 assert(!posInfInterval.merge(iInterval).empty); 4986 assert(!posInfInterval.merge(posInfInterval).empty); 4987 assert(!posInfInterval.merge(cPosInfInterval).empty); 4988 assert(!posInfInterval.merge(iPosInfInterval).empty); 4989 static assert(!__traits(compiles, posInfInterval.merge(negInfInterval))); 4990 static assert(!__traits(compiles, posInfInterval.merge(cNegInfInterval))); 4991 static assert(!__traits(compiles, posInfInterval.merge(iNegInfInterval))); 4992 assert(!cPosInfInterval.merge(interval).empty); 4993 assert(!cPosInfInterval.merge(cInterval).empty); 4994 assert(!cPosInfInterval.merge(iInterval).empty); 4995 assert(!cPosInfInterval.merge(posInfInterval).empty); 4996 assert(!cPosInfInterval.merge(cPosInfInterval).empty); 4997 assert(!cPosInfInterval.merge(iPosInfInterval).empty); 4998 static assert(!__traits(compiles, cPosInfInterval.merge(negInfInterval))); 4999 static assert(!__traits(compiles, cPosInfInterval.merge(cNegInfInterval))); 5000 static assert(!__traits(compiles, cPosInfInterval.merge(iNegInfInterval))); 5001 assert(!iPosInfInterval.merge(interval).empty); 5002 assert(!iPosInfInterval.merge(cInterval).empty); 5003 assert(!iPosInfInterval.merge(iInterval).empty); 5004 assert(!iPosInfInterval.merge(posInfInterval).empty); 5005 assert(!iPosInfInterval.merge(cPosInfInterval).empty); 5006 assert(!iPosInfInterval.merge(iPosInfInterval).empty); 5007 static assert(!__traits(compiles, iPosInfInterval.merge(negInfInterval))); 5008 static assert(!__traits(compiles, iPosInfInterval.merge(cNegInfInterval))); 5009 static assert(!__traits(compiles, iPosInfInterval.merge(iNegInfInterval))); 5010 5011 //Verify Examples. 5012 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 5013 PosInfInterval!Date(Date(1990, 7, 6))); 5014 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 5015 PosInfInterval!Date(Date(1996, 1, 2))); 5016 5017 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(PosInfInterval!Date(Date(1990, 7, 6))) == 5018 PosInfInterval!Date(Date(1990, 7, 6))); 5019 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(PosInfInterval!Date(Date(1999, 1, 12))) == 5020 PosInfInterval!Date(Date(1996, 1, 2))); 5021 } 5022 5023 //Test PosInfInterval's span(). 5024 @safe unittest 5025 { 5026 import std.datetime.date; 5027 5028 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5029 5030 static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) 5031 { 5032 posInfInterval.span(interval); 5033 } 5034 5035 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 5036 5037 assert(posInfInterval.span(posInfInterval) == posInfInterval); 5038 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == 5039 PosInfInterval!Date(Date(2010, 7, 1))); 5040 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 5041 PosInfInterval!Date(Date(2010, 7, 1))); 5042 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 5043 PosInfInterval!Date(Date(2010, 7, 3))); 5044 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 5045 PosInfInterval!Date(Date(2010, 7, 3))); 5046 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 5047 PosInfInterval!Date(Date(2010, 7, 3))); 5048 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 5049 PosInfInterval!Date(Date(2010, 7, 3))); 5050 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 5051 PosInfInterval!Date(Date(2010, 7, 4))); 5052 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 5053 PosInfInterval!Date(Date(2010, 7, 4))); 5054 assert(posInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 5055 PosInfInterval!Date(Date(2010, 7, 4))); 5056 assert(posInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 5057 PosInfInterval!Date(Date(2010, 7, 4))); 5058 assert(posInfInterval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 5059 PosInfInterval!Date(Date(2010, 7, 4))); 5060 assert(posInfInterval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == 5061 PosInfInterval!Date(Date(2010, 7, 4))); 5062 5063 assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3))); 5064 assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4))); 5065 assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4))); 5066 assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4))); 5067 assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4))); 5068 assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4))); 5069 5070 assert(PosInfInterval!Date(Date(2010, 7, 3)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 3))); 5071 assert(PosInfInterval!Date(Date(2010, 7, 4)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 5072 assert(PosInfInterval!Date(Date(2010, 7, 5)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 5073 assert(PosInfInterval!Date(Date(2012, 1, 6)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 5074 assert(PosInfInterval!Date(Date(2012, 1, 7)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 5075 assert(PosInfInterval!Date(Date(2012, 1, 8)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); 5076 5077 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 3))))); 5078 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 4))))); 5079 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 5))))); 5080 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 6))))); 5081 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 7))))); 5082 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 8))))); 5083 5084 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 5085 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 5086 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 5087 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5088 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5089 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 5090 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 5091 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 5092 assert(!posInfInterval.span(interval).empty); 5093 assert(!posInfInterval.span(cInterval).empty); 5094 assert(!posInfInterval.span(iInterval).empty); 5095 assert(!posInfInterval.span(posInfInterval).empty); 5096 assert(!posInfInterval.span(cPosInfInterval).empty); 5097 assert(!posInfInterval.span(iPosInfInterval).empty); 5098 static assert(!__traits(compiles, posInfInterval.span(negInfInterval))); 5099 static assert(!__traits(compiles, posInfInterval.span(cNegInfInterval))); 5100 static assert(!__traits(compiles, posInfInterval.span(iNegInfInterval))); 5101 assert(!cPosInfInterval.span(interval).empty); 5102 assert(!cPosInfInterval.span(cInterval).empty); 5103 assert(!cPosInfInterval.span(iInterval).empty); 5104 assert(!cPosInfInterval.span(posInfInterval).empty); 5105 assert(!cPosInfInterval.span(cPosInfInterval).empty); 5106 assert(!cPosInfInterval.span(iPosInfInterval).empty); 5107 static assert(!__traits(compiles, cPosInfInterval.span(negInfInterval))); 5108 static assert(!__traits(compiles, cPosInfInterval.span(cNegInfInterval))); 5109 static assert(!__traits(compiles, cPosInfInterval.span(iNegInfInterval))); 5110 assert(!iPosInfInterval.span(interval).empty); 5111 assert(!iPosInfInterval.span(cInterval).empty); 5112 assert(!iPosInfInterval.span(iInterval).empty); 5113 assert(!iPosInfInterval.span(posInfInterval).empty); 5114 assert(!iPosInfInterval.span(cPosInfInterval).empty); 5115 assert(!iPosInfInterval.span(iPosInfInterval).empty); 5116 static assert(!__traits(compiles, iPosInfInterval.span(negInfInterval))); 5117 static assert(!__traits(compiles, iPosInfInterval.span(cNegInfInterval))); 5118 static assert(!__traits(compiles, iPosInfInterval.span(iNegInfInterval))); 5119 5120 //Verify Examples. 5121 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) == 5122 PosInfInterval!Date(Date(500, 8, 9))); 5123 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 5124 PosInfInterval!Date(Date(1990, 7, 6))); 5125 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == 5126 PosInfInterval!Date(Date(1996, 1, 2))); 5127 5128 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(PosInfInterval!Date(Date(1990, 7, 6))) == 5129 PosInfInterval!Date(Date(1990, 7, 6))); 5130 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(PosInfInterval!Date(Date(1999, 1, 12))) == 5131 PosInfInterval!Date(Date(1996, 1, 2))); 5132 } 5133 5134 //Test PosInfInterval's shift(). 5135 @safe unittest 5136 { 5137 import std.datetime.date; 5138 5139 auto interval = PosInfInterval!Date(Date(2010, 7, 4)); 5140 5141 static void testInterval(I)(I interval, scope const Duration duration, 5142 scope const I expected, size_t line = __LINE__) 5143 { 5144 interval.shift(duration); 5145 assert(interval == expected); 5146 } 5147 5148 testInterval(interval, dur!"days"(22), PosInfInterval!Date(Date(2010, 7, 26))); 5149 testInterval(interval, dur!"days"(-22), PosInfInterval!Date(Date(2010, 6, 12))); 5150 5151 const cInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5152 immutable iInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5153 static assert(!__traits(compiles, cInterval.shift(dur!"days"(5)))); 5154 static assert(!__traits(compiles, iInterval.shift(dur!"days"(5)))); 5155 5156 //Verify Examples. 5157 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 5158 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 5159 5160 interval1.shift(dur!"days"(50)); 5161 assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21))); 5162 5163 interval2.shift(dur!"days"(-50)); 5164 assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13))); 5165 } 5166 5167 //Test PosInfInterval's shift(int, int, AllowDayOverflow). 5168 @safe unittest 5169 { 5170 import std.datetime.date; 5171 5172 { 5173 auto interval = PosInfInterval!Date(Date(2010, 7, 4)); 5174 5175 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, 5176 in I expected, size_t line = __LINE__) 5177 { 5178 interval.shift(years, months, allow); 5179 assert(interval == expected); 5180 } 5181 5182 testInterval(interval, 5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2015, 7, 4))); 5183 testInterval(interval, -5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2005, 7, 4))); 5184 5185 auto interval2 = PosInfInterval!Date(Date(2000, 1, 29)); 5186 5187 testInterval(interval2, 1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2001, 3, 1))); 5188 testInterval(interval2, 1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2000, 12, 29))); 5189 testInterval(interval2, -1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1998, 12, 29))); 5190 testInterval(interval2, -1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1999, 3, 1))); 5191 5192 testInterval(interval2, 1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(2001, 2, 28))); 5193 testInterval(interval2, 1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(2000, 12, 29))); 5194 testInterval(interval2, -1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(1998, 12, 29))); 5195 testInterval(interval2, -1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(1999, 2, 28))); 5196 } 5197 5198 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5199 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5200 static assert(!__traits(compiles, cPosInfInterval.shift(1))); 5201 static assert(!__traits(compiles, iPosInfInterval.shift(1))); 5202 5203 //Verify Examples. 5204 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 5205 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 5206 5207 interval1.shift(2); 5208 assert(interval1 == PosInfInterval!Date(Date(1998, 1, 2))); 5209 5210 interval2.shift(-2); 5211 assert(interval2 == PosInfInterval!Date(Date(1994, 1, 2))); 5212 } 5213 5214 //Test PosInfInterval's expand(). 5215 @safe unittest 5216 { 5217 import std.datetime.date; 5218 5219 auto interval = PosInfInterval!Date(Date(2000, 7, 4)); 5220 5221 static void testInterval(I)(I interval, scope const Duration duration, 5222 scope const I expected, size_t line = __LINE__) 5223 { 5224 interval.expand(duration); 5225 assert(interval == expected); 5226 } 5227 5228 testInterval(interval, dur!"days"(22), PosInfInterval!Date(Date(2000, 6, 12))); 5229 testInterval(interval, dur!"days"(-22), PosInfInterval!Date(Date(2000, 7, 26))); 5230 5231 const cInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5232 immutable iInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5233 static assert(!__traits(compiles, cInterval.expand(dur!"days"(5)))); 5234 static assert(!__traits(compiles, iInterval.expand(dur!"days"(5)))); 5235 5236 //Verify Examples. 5237 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 5238 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 5239 5240 interval1.expand(dur!"days"(2)); 5241 assert(interval1 == PosInfInterval!Date(Date(1995, 12, 31))); 5242 5243 interval2.expand(dur!"days"(-2)); 5244 assert(interval2 == PosInfInterval!Date(Date(1996, 1, 4))); 5245 } 5246 5247 //Test PosInfInterval's expand(int, int, AllowDayOverflow). 5248 @safe unittest 5249 { 5250 import std.datetime.date; 5251 5252 { 5253 auto interval = PosInfInterval!Date(Date(2000, 7, 4)); 5254 5255 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, 5256 in I expected, size_t line = __LINE__) 5257 { 5258 interval.expand(years, months, allow); 5259 assert(interval == expected); 5260 } 5261 5262 testInterval(interval, 5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(1995, 7, 4))); 5263 testInterval(interval, -5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2005, 7, 4))); 5264 5265 auto interval2 = PosInfInterval!Date(Date(2000, 1, 29)); 5266 5267 testInterval(interval2, 1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1998, 12, 29))); 5268 testInterval(interval2, 1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1999, 3, 1))); 5269 testInterval(interval2, -1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2001, 3, 1))); 5270 testInterval(interval2, -1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2000, 12, 29))); 5271 5272 testInterval(interval2, 1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(1998, 12, 29))); 5273 testInterval(interval2, 1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(1999, 2, 28))); 5274 testInterval(interval2, -1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(2001, 2, 28))); 5275 testInterval(interval2, -1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(2000, 12, 29))); 5276 } 5277 5278 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5279 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5280 static assert(!__traits(compiles, cPosInfInterval.expand(1))); 5281 static assert(!__traits(compiles, iPosInfInterval.expand(1))); 5282 5283 //Verify Examples. 5284 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); 5285 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); 5286 5287 interval1.expand(2); 5288 assert(interval1 == PosInfInterval!Date(Date(1994, 1, 2))); 5289 5290 interval2.expand(-2); 5291 assert(interval2 == PosInfInterval!Date(Date(1998, 1, 2))); 5292 } 5293 5294 //Test PosInfInterval's fwdRange(). 5295 @system unittest 5296 { 5297 import std.datetime.date; 5298 5299 auto posInfInterval = PosInfInterval!Date(Date(2010, 9, 19)); 5300 5301 static void testInterval(PosInfInterval!Date posInfInterval) 5302 { 5303 posInfInterval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront(); 5304 } 5305 5306 assertThrown!DateTimeException(testInterval(posInfInterval)); 5307 5308 assert(PosInfInterval!Date(Date(2010, 9, 12)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front == 5309 Date(2010, 9, 12)); 5310 5311 assert(PosInfInterval!Date(Date(2010, 9, 12)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front == 5312 Date(2010, 9, 17)); 5313 5314 //Verify Examples. 5315 auto interval = PosInfInterval!Date(Date(2010, 9, 1)); 5316 auto func = delegate (scope const Date date) 5317 { 5318 if ((date.day & 1) == 0) 5319 return date + dur!"days"(2); 5320 return date + dur!"days"(1); 5321 }; 5322 auto range = interval.fwdRange(func); 5323 5324 assert(range.front == Date(2010, 9, 1)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). 5325 5326 range.popFront(); 5327 assert(range.front == Date(2010, 9, 2)); 5328 5329 range.popFront(); 5330 assert(range.front == Date(2010, 9, 4)); 5331 5332 range.popFront(); 5333 assert(range.front == Date(2010, 9, 6)); 5334 5335 range.popFront(); 5336 assert(range.front == Date(2010, 9, 8)); 5337 5338 range.popFront(); 5339 assert(!range.empty); 5340 5341 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5342 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5343 assert(!cPosInfInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 5344 assert(!iPosInfInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); 5345 } 5346 5347 //Test PosInfInterval's toString(). 5348 @safe unittest 5349 { 5350 import std.datetime.date; 5351 assert(PosInfInterval!Date(Date(2010, 7, 4)).toString() == "[2010-Jul-04 - ∞)"); 5352 5353 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5354 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 5355 assert(cPosInfInterval.toString()); 5356 assert(iPosInfInterval.toString()); 5357 } 5358 5359 5360 /++ 5361 Represents an interval of time which has negative infinity as its starting 5362 point. 5363 5364 Any ranges which iterate over a `NegInfInterval` are infinite. So, the 5365 main purpose of using `NegInfInterval` is to create an infinite range 5366 which starts at negative infinity and goes to a fixed end point. 5367 Iterate over it in reverse. 5368 +/ 5369 struct NegInfInterval(TP) 5370 { 5371 public: 5372 5373 /++ 5374 Params: 5375 end = The time point which ends the interval. 5376 5377 Example: 5378 -------------------- 5379 auto interval = PosInfInterval!Date(Date(1996, 1, 2)); 5380 -------------------- 5381 +/ 5382 this(scope const TP end) pure nothrow 5383 { 5384 _end = cast(TP) end; 5385 } 5386 5387 5388 /++ 5389 Params: 5390 rhs = The `NegInfInterval` to assign to this one. 5391 +/ 5392 ref NegInfInterval opAssign(const ref NegInfInterval rhs) pure nothrow 5393 { 5394 _end = cast(TP) rhs._end; 5395 return this; 5396 } 5397 5398 5399 /++ 5400 Params: 5401 rhs = The `NegInfInterval` to assign to this one. 5402 +/ 5403 ref NegInfInterval opAssign(NegInfInterval rhs) pure nothrow 5404 { 5405 _end = cast(TP) rhs._end; 5406 return this; 5407 } 5408 5409 5410 /++ 5411 The end point of the interval. It is excluded from the interval. 5412 5413 Example: 5414 -------------------- 5415 assert(NegInfInterval!Date(Date(2012, 3, 1)).end == Date(2012, 3, 1)); 5416 -------------------- 5417 +/ 5418 @property TP end() const pure nothrow 5419 { 5420 return cast(TP)_end; 5421 } 5422 5423 5424 /++ 5425 The end point of the interval. It is excluded from the interval. 5426 5427 Params: 5428 timePoint = The time point to set end to. 5429 +/ 5430 @property void end(TP timePoint) pure nothrow 5431 { 5432 _end = timePoint; 5433 } 5434 5435 5436 /++ 5437 Whether the interval's length is 0. Always returns false. 5438 5439 Example: 5440 -------------------- 5441 assert(!NegInfInterval!Date(Date(1996, 1, 2)).empty); 5442 -------------------- 5443 +/ 5444 enum bool empty = false; 5445 5446 5447 /++ 5448 Whether the given time point is within this interval. 5449 5450 Params: 5451 timePoint = The time point to check for inclusion in this interval. 5452 5453 Example: 5454 -------------------- 5455 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(1994, 12, 24))); 5456 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2000, 1, 5))); 5457 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2012, 3, 1))); 5458 -------------------- 5459 +/ 5460 bool contains(TP timePoint) const pure nothrow 5461 { 5462 return timePoint < _end; 5463 } 5464 5465 5466 /++ 5467 Whether the given interval is completely within this interval. 5468 5469 Params: 5470 interval = The interval to check for inclusion in this interval. 5471 5472 Throws: 5473 $(REF DateTimeException,std,datetime,date) if the given interval 5474 is empty. 5475 5476 Example: 5477 -------------------- 5478 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains( 5479 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 5480 5481 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains( 5482 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 5483 5484 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains( 5485 Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); 5486 -------------------- 5487 +/ 5488 bool contains(scope const Interval!TP interval) const pure 5489 { 5490 interval._enforceNotEmpty(); 5491 return interval._end <= _end; 5492 } 5493 5494 5495 /++ 5496 Whether the given interval is completely within this interval. 5497 5498 Always returns false because an interval beginning at negative 5499 infinity can never contain an interval going to positive infinity. 5500 5501 Params: 5502 interval = The interval to check for inclusion in this interval. 5503 5504 Example: 5505 -------------------- 5506 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains( 5507 PosInfInterval!Date(Date(1999, 5, 4)))); 5508 -------------------- 5509 +/ 5510 bool contains(scope const PosInfInterval!TP interval) const pure nothrow 5511 { 5512 return false; 5513 } 5514 5515 5516 /++ 5517 Whether the given interval is completely within this interval. 5518 5519 Params: 5520 interval = The interval to check for inclusion in this interval. 5521 5522 Example: 5523 -------------------- 5524 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains( 5525 NegInfInterval!Date(Date(1996, 5, 4)))); 5526 5527 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains( 5528 NegInfInterval!Date(Date(2013, 7, 9)))); 5529 -------------------- 5530 +/ 5531 bool contains(scope const NegInfInterval interval) const pure nothrow 5532 { 5533 return interval._end <= _end; 5534 } 5535 5536 5537 /++ 5538 Whether this interval is before the given time point. 5539 5540 Params: 5541 timePoint = The time point to check whether this interval is 5542 before it. 5543 5544 Example: 5545 -------------------- 5546 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(1994, 12, 24))); 5547 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2000, 1, 5))); 5548 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2012, 3, 1))); 5549 -------------------- 5550 +/ 5551 bool isBefore(scope const TP timePoint) const pure nothrow 5552 { 5553 return timePoint >= _end; 5554 } 5555 5556 5557 /++ 5558 Whether this interval is before the given interval and does not 5559 intersect it. 5560 5561 Params: 5562 interval = The interval to check for against this interval. 5563 5564 Throws: 5565 $(REF DateTimeException,std,datetime,date) if the given interval 5566 is empty 5567 5568 Example: 5569 -------------------- 5570 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5571 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 5572 5573 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5574 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 5575 5576 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5577 Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 5578 -------------------- 5579 +/ 5580 bool isBefore(scope const Interval!TP interval) const pure 5581 { 5582 interval._enforceNotEmpty(); 5583 return _end <= interval._begin; 5584 } 5585 5586 5587 /++ 5588 Whether this interval is before the given interval and does not 5589 intersect it. 5590 5591 Params: 5592 interval = The interval to check for against this interval. 5593 5594 Example: 5595 -------------------- 5596 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5597 PosInfInterval!Date(Date(1999, 5, 4)))); 5598 5599 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5600 PosInfInterval!Date(Date(2012, 3, 1)))); 5601 -------------------- 5602 +/ 5603 bool isBefore(scope const PosInfInterval!TP interval) const pure nothrow 5604 { 5605 return _end <= interval._begin; 5606 } 5607 5608 5609 /++ 5610 Whether this interval is before the given interval and does not 5611 intersect it. 5612 5613 Always returns false because an interval beginning at negative 5614 infinity can never be before another interval beginning at negative 5615 infinity. 5616 5617 Params: 5618 interval = The interval to check for against this interval. 5619 5620 Example: 5621 -------------------- 5622 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5623 NegInfInterval!Date(Date(1996, 5, 4)))); 5624 5625 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( 5626 NegInfInterval!Date(Date(2013, 7, 9)))); 5627 -------------------- 5628 +/ 5629 bool isBefore(scope const NegInfInterval interval) const pure nothrow 5630 { 5631 return false; 5632 } 5633 5634 5635 /++ 5636 Whether this interval is after the given time point. 5637 5638 Always returns false because an interval beginning at negative infinity 5639 can never be after any time point. 5640 5641 Params: 5642 timePoint = The time point to check whether this interval is after 5643 it. 5644 5645 Example: 5646 -------------------- 5647 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(1994, 12, 24))); 5648 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2000, 1, 5))); 5649 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2012, 3, 1))); 5650 -------------------- 5651 +/ 5652 bool isAfter(scope const TP timePoint) const pure nothrow 5653 { 5654 return false; 5655 } 5656 5657 5658 /++ 5659 Whether this interval is after the given interval and does not 5660 intersect it. 5661 5662 Always returns false (unless the given interval is empty) because an 5663 interval beginning at negative infinity can never be after any other 5664 interval. 5665 5666 Params: 5667 interval = The interval to check against this interval. 5668 5669 Throws: 5670 $(REF DateTimeException,std,datetime,date) if the given interval 5671 is empty. 5672 5673 Example: 5674 -------------------- 5675 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5676 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 5677 5678 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5679 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 5680 5681 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5682 Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 5683 -------------------- 5684 +/ 5685 bool isAfter(scope const Interval!TP interval) const pure 5686 { 5687 interval._enforceNotEmpty(); 5688 return false; 5689 } 5690 5691 5692 /++ 5693 Whether this interval is after the given interval and does not intersect 5694 it. 5695 5696 Always returns false because an interval beginning at negative infinity 5697 can never be after any other interval. 5698 5699 Params: 5700 interval = The interval to check against this interval. 5701 5702 Example: 5703 -------------------- 5704 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5705 PosInfInterval!Date(Date(1999, 5, 4)))); 5706 5707 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5708 PosInfInterval!Date(Date(2012, 3, 1)))); 5709 -------------------- 5710 +/ 5711 bool isAfter(scope const PosInfInterval!TP interval) const pure nothrow 5712 { 5713 return false; 5714 } 5715 5716 5717 /++ 5718 Whether this interval is after the given interval and does not intersect 5719 it. 5720 5721 Always returns false because an interval beginning at negative infinity 5722 can never be after any other interval. 5723 5724 Params: 5725 interval = The interval to check against this interval. 5726 5727 Example: 5728 -------------------- 5729 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5730 NegInfInterval!Date(Date(1996, 5, 4)))); 5731 5732 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( 5733 NegInfInterval!Date(Date(2013, 7, 9)))); 5734 -------------------- 5735 +/ 5736 bool isAfter(scope const NegInfInterval interval) const pure nothrow 5737 { 5738 return false; 5739 } 5740 5741 5742 /++ 5743 Whether the given interval overlaps this interval. 5744 5745 Params: 5746 interval = The interval to check for intersection with this interval. 5747 5748 Throws: 5749 $(REF DateTimeException,std,datetime,date) if the given interval 5750 is empty. 5751 5752 Example: 5753 -------------------- 5754 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5755 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 5756 5757 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5758 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 5759 5760 assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5761 Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 5762 -------------------- 5763 +/ 5764 bool intersects(scope const Interval!TP interval) const pure 5765 { 5766 interval._enforceNotEmpty(); 5767 return interval._begin < _end; 5768 } 5769 5770 5771 /++ 5772 Whether the given interval overlaps this interval. 5773 5774 Params: 5775 interval = The interval to check for intersection with this 5776 interval. 5777 5778 Example: 5779 -------------------- 5780 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5781 PosInfInterval!Date(Date(1999, 5, 4)))); 5782 5783 assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5784 PosInfInterval!Date(Date(2012, 3, 1)))); 5785 -------------------- 5786 +/ 5787 bool intersects(scope const PosInfInterval!TP interval) const pure nothrow 5788 { 5789 return interval._begin < _end; 5790 } 5791 5792 5793 /++ 5794 Whether the given interval overlaps this interval. 5795 5796 Always returns true because two intervals beginning at negative infinity 5797 always overlap. 5798 5799 Params: 5800 interval = The interval to check for intersection with this interval. 5801 5802 Example: 5803 -------------------- 5804 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5805 NegInfInterval!Date(Date(1996, 5, 4)))); 5806 5807 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( 5808 NegInfInterval!Date(Date(2013, 7, 9)))); 5809 -------------------- 5810 +/ 5811 bool intersects(scope const NegInfInterval!TP interval) const pure nothrow 5812 { 5813 return true; 5814 } 5815 5816 5817 /++ 5818 Returns the intersection of two intervals 5819 5820 Params: 5821 interval = The interval to intersect with this interval. 5822 5823 Throws: 5824 $(REF DateTimeException,std,datetime,date) if the two intervals do 5825 not intersect or if the given interval is empty. 5826 5827 Example: 5828 -------------------- 5829 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( 5830 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 5831 Interval!Date(Date(1990, 7 , 6), Date(2000, 8, 2))); 5832 5833 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( 5834 Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == 5835 Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); 5836 -------------------- 5837 +/ 5838 Interval!TP intersection(scope const Interval!TP interval) const 5839 { 5840 import std.format : format; 5841 5842 enforce(this.intersects(interval), 5843 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 5844 5845 auto end = _end < interval._end ? _end : interval._end; 5846 5847 return Interval!TP(interval._begin, end); 5848 } 5849 5850 5851 /++ 5852 Returns the intersection of two intervals 5853 5854 Params: 5855 interval = The interval to intersect with this interval. 5856 5857 Throws: 5858 $(REF DateTimeException,std,datetime,date) if the two intervals do 5859 not intersect. 5860 5861 Example: 5862 -------------------- 5863 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( 5864 PosInfInterval!Date(Date(1990, 7, 6))) == 5865 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); 5866 5867 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( 5868 PosInfInterval!Date(Date(1999, 1, 12))) == 5869 Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); 5870 -------------------- 5871 +/ 5872 Interval!TP intersection(scope const PosInfInterval!TP interval) const 5873 { 5874 import std.format : format; 5875 5876 enforce(this.intersects(interval), 5877 new DateTimeException(format("%s and %s do not intersect.", this, interval))); 5878 5879 return Interval!TP(interval._begin, _end); 5880 } 5881 5882 5883 /++ 5884 Returns the intersection of two intervals 5885 5886 Params: 5887 interval = The interval to intersect with this interval. 5888 5889 Example: 5890 -------------------- 5891 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( 5892 NegInfInterval!Date(Date(1999, 7, 6))) == 5893 NegInfInterval!Date(Date(1999, 7 , 6))); 5894 5895 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( 5896 NegInfInterval!Date(Date(2013, 1, 12))) == 5897 NegInfInterval!Date(Date(2012, 3 , 1))); 5898 -------------------- 5899 +/ 5900 NegInfInterval intersection(scope const NegInfInterval interval) const nothrow 5901 { 5902 return NegInfInterval(_end < interval._end ? _end : interval._end); 5903 } 5904 5905 5906 /++ 5907 Whether the given interval is adjacent to this interval. 5908 5909 Params: 5910 interval = The interval to check whether its adjecent to this 5911 interval. 5912 5913 Throws: 5914 $(REF DateTimeException,std,datetime,date) if the given interval 5915 is empty. 5916 5917 Example: 5918 -------------------- 5919 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5920 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 5921 5922 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5923 Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1)))); 5924 5925 assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5926 Interval!Date(Date(2012, 3, 1), Date(2019, 2, 2)))); 5927 5928 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5929 Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 5930 -------------------- 5931 +/ 5932 bool isAdjacent(scope const Interval!TP interval) const pure 5933 { 5934 interval._enforceNotEmpty(); 5935 return interval._begin == _end; 5936 } 5937 5938 5939 /++ 5940 Whether the given interval is adjacent to this interval. 5941 5942 Params: 5943 interval = The interval to check whether its adjecent to this 5944 interval. 5945 5946 Example: 5947 -------------------- 5948 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5949 PosInfInterval!Date(Date(1999, 5, 4)))); 5950 5951 assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5952 PosInfInterval!Date(Date(2012, 3, 1)))); 5953 -------------------- 5954 +/ 5955 bool isAdjacent(scope const PosInfInterval!TP interval) const pure nothrow 5956 { 5957 return interval._begin == _end; 5958 } 5959 5960 5961 /++ 5962 Whether the given interval is adjacent to this interval. 5963 5964 Always returns false because two intervals beginning at negative 5965 infinity can never be adjacent to one another. 5966 5967 Params: 5968 interval = The interval to check whether its adjecent to this 5969 interval. 5970 5971 Example: 5972 -------------------- 5973 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5974 NegInfInterval!Date(Date(1996, 5, 4)))); 5975 5976 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( 5977 NegInfInterval!Date(Date(2012, 3, 1)))); 5978 -------------------- 5979 +/ 5980 bool isAdjacent(scope const NegInfInterval interval) const pure nothrow 5981 { 5982 return false; 5983 } 5984 5985 5986 /++ 5987 Returns the union of two intervals 5988 5989 Params: 5990 interval = The interval to merge with this interval. 5991 5992 Throws: 5993 $(REF DateTimeException,std,datetime,date) if the two intervals do 5994 not intersect and are not adjacent or if the given interval is empty. 5995 5996 Note: 5997 There is no overload for `merge` which takes a 5998 `PosInfInterval`, because an interval 5999 going from negative infinity to positive infinity 6000 is not possible. 6001 6002 Example: 6003 -------------------- 6004 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge( 6005 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 6006 NegInfInterval!Date(Date(2012, 3 , 1))); 6007 6008 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge( 6009 Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == 6010 NegInfInterval!Date(Date(2015, 9 , 2))); 6011 -------------------- 6012 +/ 6013 NegInfInterval merge(scope const Interval!TP interval) const 6014 { 6015 import std.format : format; 6016 6017 enforce(this.isAdjacent(interval) || this.intersects(interval), 6018 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); 6019 6020 return NegInfInterval(_end > interval._end ? _end : interval._end); 6021 } 6022 6023 6024 /++ 6025 Returns the union of two intervals 6026 6027 Params: 6028 interval = The interval to merge with this interval. 6029 6030 Note: 6031 There is no overload for `merge` which takes a 6032 `PosInfInterval`, because an interval 6033 going from negative infinity to positive infinity 6034 is not possible. 6035 6036 Example: 6037 -------------------- 6038 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge( 6039 NegInfInterval!Date(Date(1999, 7, 6))) == 6040 NegInfInterval!Date(Date(2012, 3 , 1))); 6041 6042 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge( 6043 NegInfInterval!Date(Date(2013, 1, 12))) == 6044 NegInfInterval!Date(Date(2013, 1 , 12))); 6045 -------------------- 6046 +/ 6047 NegInfInterval merge(scope const NegInfInterval interval) const pure nothrow 6048 { 6049 return NegInfInterval(_end > interval._end ? _end : interval._end); 6050 } 6051 6052 6053 /++ 6054 Returns an interval that covers from the earliest time point of two 6055 intervals up to (but not including) the latest time point of two 6056 intervals. 6057 6058 Params: 6059 interval = The interval to create a span together with this 6060 interval. 6061 6062 Throws: 6063 $(REF DateTimeException,std,datetime,date) if the given interval 6064 is empty. 6065 6066 Note: 6067 There is no overload for `span` which takes a 6068 `PosInfInterval`, because an interval 6069 going from negative infinity to positive infinity 6070 is not possible. 6071 6072 Example: 6073 -------------------- 6074 assert(NegInfInterval!Date(Date(2012, 3, 1)).span( 6075 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 6076 NegInfInterval!Date(Date(2012, 3 , 1))); 6077 6078 assert(NegInfInterval!Date(Date(2012, 3, 1)).span( 6079 Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == 6080 NegInfInterval!Date(Date(2015, 9 , 2))); 6081 6082 assert(NegInfInterval!Date(Date(1600, 1, 7)).span( 6083 Interval!Date(Date(2012, 3, 11), Date(2017, 7, 1))) == 6084 NegInfInterval!Date(Date(2017, 7 , 1))); 6085 -------------------- 6086 +/ 6087 NegInfInterval span(scope const Interval!TP interval) const pure 6088 { 6089 interval._enforceNotEmpty(); 6090 return NegInfInterval(_end > interval._end ? _end : interval._end); 6091 } 6092 6093 6094 /++ 6095 Returns an interval that covers from the earliest time point of two 6096 intervals up to (but not including) the latest time point of two 6097 intervals. 6098 6099 Params: 6100 interval = The interval to create a span together with this 6101 interval. 6102 6103 Note: 6104 There is no overload for `span` which takes a 6105 `PosInfInterval`, because an interval 6106 going from negative infinity to positive infinity 6107 is not possible. 6108 6109 Example: 6110 -------------------- 6111 assert(NegInfInterval!Date(Date(2012, 3, 1)).span( 6112 NegInfInterval!Date(Date(1999, 7, 6))) == 6113 NegInfInterval!Date(Date(2012, 3 , 1))); 6114 6115 assert(NegInfInterval!Date(Date(2012, 3, 1)).span( 6116 NegInfInterval!Date(Date(2013, 1, 12))) == 6117 NegInfInterval!Date(Date(2013, 1 , 12))); 6118 -------------------- 6119 +/ 6120 NegInfInterval span(scope const NegInfInterval interval) const pure nothrow 6121 { 6122 return NegInfInterval(_end > interval._end ? _end : interval._end); 6123 } 6124 6125 6126 /++ 6127 Shifts the `end` of this interval forward or backwards in time by the 6128 given duration (a positive duration shifts the interval forward; a 6129 negative duration shifts it backward). Effectively, it does 6130 $(D end += duration). 6131 6132 Params: 6133 duration = The duration to shift the interval by. 6134 6135 Example: 6136 -------------------- 6137 auto interval1 = NegInfInterval!Date(Date(2012, 4, 5)); 6138 auto interval2 = NegInfInterval!Date(Date(2012, 4, 5)); 6139 6140 interval1.shift(dur!"days"(50)); 6141 assert(interval1 == NegInfInterval!Date(Date(2012, 5, 25))); 6142 6143 interval2.shift(dur!"days"(-50)); 6144 assert(interval2 == NegInfInterval!Date( Date(2012, 2, 15))); 6145 -------------------- 6146 +/ 6147 void shift(D)(D duration) pure nothrow 6148 if (__traits(compiles, end + duration)) 6149 { 6150 _end += duration; 6151 } 6152 6153 6154 static if (__traits(compiles, end.add!"months"(1)) && 6155 __traits(compiles, end.add!"years"(1))) 6156 { 6157 /++ 6158 Shifts the `end` of this interval forward or backwards in time by 6159 the given number of years and/or months (a positive number of years 6160 and months shifts the interval forward; a negative number shifts it 6161 backward). It adds the years the given years and months to end. It 6162 effectively calls `add!"years"()` and then `add!"months"()` 6163 on end with the given number of years and months. 6164 6165 Params: 6166 years = The number of years to shift the interval by. 6167 months = The number of months to shift the interval by. 6168 allowOverflow = Whether the days should be allowed to overflow 6169 on `end`, causing its month to increment. 6170 6171 Throws: 6172 $(REF DateTimeException,std,datetime,date) if empty is true or 6173 if the resulting interval would be invalid. 6174 6175 Example: 6176 -------------------- 6177 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); 6178 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); 6179 6180 interval1.shift(2); 6181 assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1))); 6182 6183 interval2.shift(-2); 6184 assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1))); 6185 -------------------- 6186 +/ 6187 void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) 6188 if (isIntegral!T) 6189 { 6190 auto end = _end; 6191 6192 end.add!"years"(years, allowOverflow); 6193 end.add!"months"(months, allowOverflow); 6194 6195 _end = end; 6196 } 6197 } 6198 6199 6200 /++ 6201 Expands the interval forwards in time. Effectively, it does 6202 $(D end += duration). 6203 6204 Params: 6205 duration = The duration to expand the interval by. 6206 6207 Example: 6208 -------------------- 6209 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); 6210 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); 6211 6212 interval1.expand(dur!"days"(2)); 6213 assert(interval1 == NegInfInterval!Date(Date(2012, 3, 3))); 6214 6215 interval2.expand(dur!"days"(-2)); 6216 assert(interval2 == NegInfInterval!Date(Date(2012, 2, 28))); 6217 -------------------- 6218 +/ 6219 void expand(D)(D duration) pure nothrow 6220 if (__traits(compiles, end + duration)) 6221 { 6222 _end += duration; 6223 } 6224 6225 6226 static if (__traits(compiles, end.add!"months"(1)) && 6227 __traits(compiles, end.add!"years"(1))) 6228 { 6229 /++ 6230 Expands the interval forwards and/or backwards in time. Effectively, 6231 it adds the given number of months/years to end. 6232 6233 Params: 6234 years = The number of years to expand the interval by. 6235 months = The number of months to expand the interval by. 6236 allowOverflow = Whether the days should be allowed to overflow 6237 on `end`, causing their month to increment. 6238 6239 Throws: 6240 $(REF DateTimeException,std,datetime,date) if empty is true or 6241 if the resulting interval would be invalid. 6242 6243 Example: 6244 -------------------- 6245 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); 6246 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); 6247 6248 interval1.expand(2); 6249 assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1))); 6250 6251 interval2.expand(-2); 6252 assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1))); 6253 -------------------- 6254 +/ 6255 void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) 6256 if (isIntegral!T) 6257 { 6258 auto end = _end; 6259 6260 end.add!"years"(years, allowOverflow); 6261 end.add!"months"(months, allowOverflow); 6262 6263 _end = end; 6264 } 6265 } 6266 6267 6268 /++ 6269 Returns a range which iterates backwards over the interval, starting 6270 at `end`, using $(D_PARAM func) to generate each successive time 6271 point. 6272 6273 The range's `front` is the interval's `end`. $(D_PARAM func) is 6274 used to generate the next `front` when `popFront` is called. If 6275 $(D_PARAM popFirst) is `PopFirst.yes`, then `popFront` is called 6276 before the range is returned (so that `front` is a time point which 6277 $(D_PARAM func) would generate). 6278 6279 If $(D_PARAM func) ever generates a time point greater than or equal to 6280 the current `front` of the range, then a 6281 $(REF DateTimeException,std,datetime,date) will be thrown. 6282 6283 There are helper functions in this module which generate common 6284 delegates to pass to `bwdRange`. Their documentation starts with 6285 "Range-generating function," to make them easily searchable. 6286 6287 Params: 6288 func = The function used to generate the time points of the 6289 range over the interval. 6290 popFirst = Whether `popFront` should be called on the range 6291 before returning it. 6292 6293 Throws: 6294 $(REF DateTimeException,std,datetime,date) if this interval is 6295 empty. 6296 6297 Warning: 6298 $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) 6299 would be a function pointer to a pure function, but forcing 6300 $(D_PARAM func) to be pure is far too restrictive to be useful, and 6301 in order to have the ease of use of having functions which generate 6302 functions to pass to `fwdRange`, $(D_PARAM func) must be a 6303 delegate. 6304 6305 If $(D_PARAM func) retains state which changes as it is called, then 6306 some algorithms will not work correctly, because the range's 6307 `save` will have failed to have really saved the range's state. 6308 To avoid such bugs, don't pass a delegate which is 6309 not logically pure to `fwdRange`. If $(D_PARAM func) is given the 6310 same time point with two different calls, it must return the same 6311 result both times. 6312 6313 Of course, none of the functions in this module have this problem, 6314 so it's only relevant for custom delegates. 6315 6316 Example: 6317 -------------------- 6318 auto interval = NegInfInterval!Date(Date(2010, 9, 9)); 6319 auto func = delegate (scope const Date date) //For iterating over even-numbered days. 6320 { 6321 if ((date.day & 1) == 0) 6322 return date - dur!"days"(2); 6323 6324 return date - dur!"days"(1); 6325 }; 6326 auto range = interval.bwdRange(func); 6327 6328 assert(range.front == Date(2010, 9, 9)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). 6329 6330 range.popFront(); 6331 assert(range.front == Date(2010, 9, 8)); 6332 6333 range.popFront(); 6334 assert(range.front == Date(2010, 9, 6)); 6335 6336 range.popFront(); 6337 assert(range.front == Date(2010, 9, 4)); 6338 6339 range.popFront(); 6340 assert(range.front == Date(2010, 9, 2)); 6341 6342 range.popFront(); 6343 assert(!range.empty); 6344 -------------------- 6345 +/ 6346 NegInfIntervalRange!(TP) bwdRange(TP delegate(scope const TP) func, PopFirst popFirst = PopFirst.no) const 6347 { 6348 auto range = NegInfIntervalRange!(TP)(this, func); 6349 6350 if (popFirst == PopFirst.yes) 6351 range.popFront(); 6352 6353 return range; 6354 } 6355 6356 6357 /+ 6358 Converts this interval to a string. 6359 +/ 6360 // Due to bug https://issues.dlang.org/show_bug.cgi?id=3715 , we can't 6361 // have versions of toString() with extra modifiers, 6362 // so we define one version with modifiers and one without. 6363 string toString() 6364 { 6365 return _toStringImpl(); 6366 } 6367 6368 6369 /++ 6370 Converts this interval to a string. 6371 +/ 6372 // Due to bug https://issues.dlang.org/show_bug.cgi?id=3715 , we can't 6373 // have versions of toString() with extra modifiers, 6374 // so we define one version with modifiers and one without. 6375 string toString() const nothrow 6376 { 6377 return _toStringImpl(); 6378 } 6379 6380 private: 6381 6382 /+ 6383 Since we have two versions of toString(), we have _toStringImpl() 6384 so that they can share implementations. 6385 +/ 6386 string _toStringImpl() const nothrow 6387 { 6388 import std.format : format; 6389 try 6390 return format("[-∞ - %s)", _end); 6391 catch (Exception e) 6392 assert(0, "format() threw."); 6393 } 6394 6395 6396 TP _end; 6397 } 6398 6399 //Test NegInfInterval's constructor. 6400 @safe unittest 6401 { 6402 import std.datetime.date; 6403 import std.datetime.systime; 6404 6405 NegInfInterval!Date(Date.init); 6406 NegInfInterval!TimeOfDay(TimeOfDay.init); 6407 NegInfInterval!DateTime(DateTime.init); 6408 NegInfInterval!SysTime(SysTime(0)); 6409 } 6410 6411 //Test NegInfInterval's end. 6412 @safe unittest 6413 { 6414 import std.datetime.date; 6415 6416 assert(NegInfInterval!Date(Date(2010, 1, 1)).end == Date(2010, 1, 1)); 6417 assert(NegInfInterval!Date(Date(2010, 1, 1)).end == Date(2010, 1, 1)); 6418 assert(NegInfInterval!Date(Date(1998, 1, 1)).end == Date(1998, 1, 1)); 6419 6420 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6421 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6422 assert(cNegInfInterval.end != Date.init); 6423 assert(iNegInfInterval.end != Date.init); 6424 6425 //Verify Examples. 6426 assert(NegInfInterval!Date(Date(2012, 3, 1)).end == Date(2012, 3, 1)); 6427 } 6428 6429 //Test NegInfInterval's empty. 6430 @safe unittest 6431 { 6432 import std.datetime.date; 6433 import std.datetime.systime; 6434 6435 assert(!NegInfInterval!Date(Date(2010, 1, 1)).empty); 6436 assert(!NegInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty); 6437 assert(!NegInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty); 6438 assert(!NegInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty); 6439 6440 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6441 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6442 assert(!cNegInfInterval.empty); 6443 assert(!iNegInfInterval.empty); 6444 6445 //Verify Examples. 6446 assert(!NegInfInterval!Date(Date(1996, 1, 2)).empty); 6447 } 6448 6449 //Test NegInfInterval's contains(time point). 6450 @safe unittest 6451 { 6452 import std.datetime.date; 6453 6454 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6455 6456 assert(negInfInterval.contains(Date(2009, 7, 4))); 6457 assert(negInfInterval.contains(Date(2010, 7, 3))); 6458 assert(negInfInterval.contains(Date(2010, 7, 4))); 6459 assert(negInfInterval.contains(Date(2010, 7, 5))); 6460 assert(negInfInterval.contains(Date(2011, 7, 1))); 6461 assert(negInfInterval.contains(Date(2012, 1, 6))); 6462 assert(!negInfInterval.contains(Date(2012, 1, 7))); 6463 assert(!negInfInterval.contains(Date(2012, 1, 8))); 6464 assert(!negInfInterval.contains(Date(2013, 1, 7))); 6465 6466 const cdate = Date(2010, 7, 6); 6467 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6468 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6469 assert(negInfInterval.contains(cdate)); 6470 assert(cNegInfInterval.contains(cdate)); 6471 assert(iNegInfInterval.contains(cdate)); 6472 6473 //Verify Examples. 6474 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(1994, 12, 24))); 6475 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2000, 1, 5))); 6476 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2012, 3, 1))); 6477 } 6478 6479 //Test NegInfInterval's contains(Interval). 6480 @safe unittest 6481 { 6482 import std.datetime.date; 6483 6484 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6485 6486 static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval) 6487 { 6488 negInfInterval.contains(interval); 6489 } 6490 6491 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 6492 6493 assert(negInfInterval.contains(negInfInterval)); 6494 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 6495 assert(!negInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 6496 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 6497 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 6498 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 6499 assert(!negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 6500 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 6501 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 6502 assert(negInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 6503 assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 6504 assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 6505 assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 6506 6507 assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 3)))); 6508 assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 4)))); 6509 assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 5)))); 6510 assert(negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 6)))); 6511 assert(negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 7)))); 6512 assert(!negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 8)))); 6513 6514 assert(!NegInfInterval!Date(Date(2010, 7, 3)).contains(negInfInterval)); 6515 assert(!NegInfInterval!Date(Date(2010, 7, 4)).contains(negInfInterval)); 6516 assert(!NegInfInterval!Date(Date(2010, 7, 5)).contains(negInfInterval)); 6517 assert(!NegInfInterval!Date(Date(2012, 1, 6)).contains(negInfInterval)); 6518 assert(NegInfInterval!Date(Date(2012, 1, 7)).contains(negInfInterval)); 6519 assert(NegInfInterval!Date(Date(2012, 1, 8)).contains(negInfInterval)); 6520 6521 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 3)))); 6522 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 4)))); 6523 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 5)))); 6524 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 6)))); 6525 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 7)))); 6526 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 8)))); 6527 6528 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6529 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6530 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6531 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6532 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6533 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6534 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6535 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6536 assert(negInfInterval.contains(interval)); 6537 assert(negInfInterval.contains(cInterval)); 6538 assert(negInfInterval.contains(iInterval)); 6539 assert(!negInfInterval.contains(posInfInterval)); 6540 assert(!negInfInterval.contains(cPosInfInterval)); 6541 assert(!negInfInterval.contains(iPosInfInterval)); 6542 assert(negInfInterval.contains(negInfInterval)); 6543 assert(negInfInterval.contains(cNegInfInterval)); 6544 assert(negInfInterval.contains(iNegInfInterval)); 6545 assert(cNegInfInterval.contains(interval)); 6546 assert(cNegInfInterval.contains(cInterval)); 6547 assert(cNegInfInterval.contains(iInterval)); 6548 assert(!cNegInfInterval.contains(posInfInterval)); 6549 assert(!cNegInfInterval.contains(cPosInfInterval)); 6550 assert(!cNegInfInterval.contains(iPosInfInterval)); 6551 assert(cNegInfInterval.contains(negInfInterval)); 6552 assert(cNegInfInterval.contains(cNegInfInterval)); 6553 assert(cNegInfInterval.contains(iNegInfInterval)); 6554 assert(iNegInfInterval.contains(interval)); 6555 assert(iNegInfInterval.contains(cInterval)); 6556 assert(iNegInfInterval.contains(iInterval)); 6557 assert(!iNegInfInterval.contains(posInfInterval)); 6558 assert(!iNegInfInterval.contains(cPosInfInterval)); 6559 assert(!iNegInfInterval.contains(iPosInfInterval)); 6560 assert(iNegInfInterval.contains(negInfInterval)); 6561 assert(iNegInfInterval.contains(cNegInfInterval)); 6562 assert(iNegInfInterval.contains(iNegInfInterval)); 6563 6564 //Verify Examples. 6565 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 6566 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 6567 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); 6568 6569 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4)))); 6570 6571 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4)))); 6572 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(2013, 7, 9)))); 6573 } 6574 6575 //Test NegInfInterval's isBefore(time point). 6576 @safe unittest 6577 { 6578 import std.datetime.date; 6579 6580 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6581 6582 assert(!negInfInterval.isBefore(Date(2009, 7, 4))); 6583 assert(!negInfInterval.isBefore(Date(2010, 7, 3))); 6584 assert(!negInfInterval.isBefore(Date(2010, 7, 4))); 6585 assert(!negInfInterval.isBefore(Date(2010, 7, 5))); 6586 assert(!negInfInterval.isBefore(Date(2011, 7, 1))); 6587 assert(!negInfInterval.isBefore(Date(2012, 1, 6))); 6588 assert(negInfInterval.isBefore(Date(2012, 1, 7))); 6589 assert(negInfInterval.isBefore(Date(2012, 1, 8))); 6590 assert(negInfInterval.isBefore(Date(2013, 1, 7))); 6591 6592 const cdate = Date(2010, 7, 6); 6593 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6594 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6595 assert(!negInfInterval.isBefore(cdate)); 6596 assert(!cNegInfInterval.isBefore(cdate)); 6597 assert(!iNegInfInterval.isBefore(cdate)); 6598 6599 //Verify Examples. 6600 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(1994, 12, 24))); 6601 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2000, 1, 5))); 6602 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2012, 3, 1))); 6603 } 6604 6605 //Test NegInfInterval's isBefore(Interval). 6606 @safe unittest 6607 { 6608 import std.datetime.date; 6609 6610 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6611 6612 static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval) 6613 { 6614 negInfInterval.isBefore(interval); 6615 } 6616 6617 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 6618 6619 assert(!negInfInterval.isBefore(negInfInterval)); 6620 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 6621 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 6622 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 6623 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 6624 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 6625 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 6626 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 6627 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 6628 assert(!negInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 6629 assert(!negInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 6630 assert(negInfInterval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 6631 assert(negInfInterval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 6632 6633 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 3)))); 6634 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 4)))); 6635 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 5)))); 6636 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 6)))); 6637 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 7)))); 6638 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 8)))); 6639 6640 assert(!NegInfInterval!Date(Date(2010, 7, 3)).isBefore(negInfInterval)); 6641 assert(!NegInfInterval!Date(Date(2010, 7, 4)).isBefore(negInfInterval)); 6642 assert(!NegInfInterval!Date(Date(2010, 7, 5)).isBefore(negInfInterval)); 6643 assert(!NegInfInterval!Date(Date(2012, 1, 6)).isBefore(negInfInterval)); 6644 assert(!NegInfInterval!Date(Date(2012, 1, 7)).isBefore(negInfInterval)); 6645 assert(!NegInfInterval!Date(Date(2012, 1, 8)).isBefore(negInfInterval)); 6646 6647 assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 3)))); 6648 assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 4)))); 6649 assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 5)))); 6650 assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 6)))); 6651 assert(negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 7)))); 6652 assert(negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 8)))); 6653 6654 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6655 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6656 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6657 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6658 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6659 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6660 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6661 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6662 assert(!negInfInterval.isBefore(interval)); 6663 assert(!negInfInterval.isBefore(cInterval)); 6664 assert(!negInfInterval.isBefore(iInterval)); 6665 assert(!negInfInterval.isBefore(posInfInterval)); 6666 assert(!negInfInterval.isBefore(cPosInfInterval)); 6667 assert(!negInfInterval.isBefore(iPosInfInterval)); 6668 assert(!negInfInterval.isBefore(negInfInterval)); 6669 assert(!negInfInterval.isBefore(cNegInfInterval)); 6670 assert(!negInfInterval.isBefore(iNegInfInterval)); 6671 assert(!cNegInfInterval.isBefore(interval)); 6672 assert(!cNegInfInterval.isBefore(cInterval)); 6673 assert(!cNegInfInterval.isBefore(iInterval)); 6674 assert(!cNegInfInterval.isBefore(posInfInterval)); 6675 assert(!cNegInfInterval.isBefore(cPosInfInterval)); 6676 assert(!cNegInfInterval.isBefore(iPosInfInterval)); 6677 assert(!cNegInfInterval.isBefore(negInfInterval)); 6678 assert(!cNegInfInterval.isBefore(cNegInfInterval)); 6679 assert(!cNegInfInterval.isBefore(iNegInfInterval)); 6680 assert(!iNegInfInterval.isBefore(interval)); 6681 assert(!iNegInfInterval.isBefore(cInterval)); 6682 assert(!iNegInfInterval.isBefore(iInterval)); 6683 assert(!iNegInfInterval.isBefore(posInfInterval)); 6684 assert(!iNegInfInterval.isBefore(cPosInfInterval)); 6685 assert(!iNegInfInterval.isBefore(iPosInfInterval)); 6686 assert(!iNegInfInterval.isBefore(negInfInterval)); 6687 assert(!iNegInfInterval.isBefore(cNegInfInterval)); 6688 assert(!iNegInfInterval.isBefore(iNegInfInterval)); 6689 6690 //Verify Examples. 6691 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 6692 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 6693 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 6694 6695 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4)))); 6696 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2012, 3, 1)))); 6697 6698 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4)))); 6699 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(2013, 7, 9)))); 6700 } 6701 6702 //Test NegInfInterval's isAfter(time point). 6703 @safe unittest 6704 { 6705 import std.datetime.date; 6706 6707 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6708 6709 assert(!negInfInterval.isAfter(Date(2009, 7, 4))); 6710 assert(!negInfInterval.isAfter(Date(2010, 7, 3))); 6711 assert(!negInfInterval.isAfter(Date(2010, 7, 4))); 6712 assert(!negInfInterval.isAfter(Date(2010, 7, 5))); 6713 assert(!negInfInterval.isAfter(Date(2011, 7, 1))); 6714 assert(!negInfInterval.isAfter(Date(2012, 1, 6))); 6715 assert(!negInfInterval.isAfter(Date(2012, 1, 7))); 6716 assert(!negInfInterval.isAfter(Date(2012, 1, 8))); 6717 assert(!negInfInterval.isAfter(Date(2013, 1, 7))); 6718 6719 const cdate = Date(2010, 7, 6); 6720 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6721 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6722 assert(!negInfInterval.isAfter(cdate)); 6723 assert(!cNegInfInterval.isAfter(cdate)); 6724 assert(!iNegInfInterval.isAfter(cdate)); 6725 } 6726 6727 //Test NegInfInterval's isAfter(Interval). 6728 @safe unittest 6729 { 6730 import std.datetime.date; 6731 6732 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6733 6734 static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval) 6735 { 6736 negInfInterval.isAfter(interval); 6737 } 6738 6739 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 6740 6741 assert(!negInfInterval.isAfter(negInfInterval)); 6742 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 6743 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 6744 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 6745 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 6746 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 6747 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 6748 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 6749 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 6750 assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 6751 assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 6752 assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 6753 assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 6754 6755 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 3)))); 6756 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 4)))); 6757 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 5)))); 6758 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 6)))); 6759 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 7)))); 6760 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 8)))); 6761 6762 assert(!NegInfInterval!Date(Date(2010, 7, 3)).isAfter(negInfInterval)); 6763 assert(!NegInfInterval!Date(Date(2010, 7, 4)).isAfter(negInfInterval)); 6764 assert(!NegInfInterval!Date(Date(2010, 7, 5)).isAfter(negInfInterval)); 6765 assert(!NegInfInterval!Date(Date(2012, 1, 6)).isAfter(negInfInterval)); 6766 assert(!NegInfInterval!Date(Date(2012, 1, 7)).isAfter(negInfInterval)); 6767 assert(!NegInfInterval!Date(Date(2012, 1, 8)).isAfter(negInfInterval)); 6768 6769 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 3)))); 6770 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 4)))); 6771 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 5)))); 6772 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 6)))); 6773 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 7)))); 6774 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 8)))); 6775 6776 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6777 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6778 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6779 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6780 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6781 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6782 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6783 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6784 assert(!negInfInterval.isAfter(interval)); 6785 assert(!negInfInterval.isAfter(cInterval)); 6786 assert(!negInfInterval.isAfter(iInterval)); 6787 assert(!negInfInterval.isAfter(posInfInterval)); 6788 assert(!negInfInterval.isAfter(cPosInfInterval)); 6789 assert(!negInfInterval.isAfter(iPosInfInterval)); 6790 assert(!negInfInterval.isAfter(negInfInterval)); 6791 assert(!negInfInterval.isAfter(cNegInfInterval)); 6792 assert(!negInfInterval.isAfter(iNegInfInterval)); 6793 assert(!cNegInfInterval.isAfter(interval)); 6794 assert(!cNegInfInterval.isAfter(cInterval)); 6795 assert(!cNegInfInterval.isAfter(iInterval)); 6796 assert(!cNegInfInterval.isAfter(posInfInterval)); 6797 assert(!cNegInfInterval.isAfter(cPosInfInterval)); 6798 assert(!cNegInfInterval.isAfter(iPosInfInterval)); 6799 assert(!cNegInfInterval.isAfter(negInfInterval)); 6800 assert(!cNegInfInterval.isAfter(cNegInfInterval)); 6801 assert(!cNegInfInterval.isAfter(iNegInfInterval)); 6802 assert(!iNegInfInterval.isAfter(interval)); 6803 assert(!iNegInfInterval.isAfter(cInterval)); 6804 assert(!iNegInfInterval.isAfter(iInterval)); 6805 assert(!iNegInfInterval.isAfter(posInfInterval)); 6806 assert(!iNegInfInterval.isAfter(cPosInfInterval)); 6807 assert(!iNegInfInterval.isAfter(iPosInfInterval)); 6808 assert(!iNegInfInterval.isAfter(negInfInterval)); 6809 assert(!iNegInfInterval.isAfter(cNegInfInterval)); 6810 assert(!iNegInfInterval.isAfter(iNegInfInterval)); 6811 6812 //Verify Examples. 6813 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(1994, 12, 24))); 6814 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2000, 1, 5))); 6815 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2012, 3, 1))); 6816 6817 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 6818 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 6819 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 6820 6821 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4)))); 6822 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(2012, 3, 1)))); 6823 6824 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 5, 4)))); 6825 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(2013, 7, 9)))); 6826 } 6827 6828 //Test NegInfInterval's intersects(). 6829 @safe unittest 6830 { 6831 import std.datetime.date; 6832 6833 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6834 6835 static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval) 6836 { 6837 negInfInterval.intersects(interval); 6838 } 6839 6840 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 6841 6842 assert(negInfInterval.intersects(negInfInterval)); 6843 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 6844 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 6845 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 6846 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 6847 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 6848 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 6849 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 6850 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 6851 assert(negInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 6852 assert(negInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 6853 assert(!negInfInterval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 6854 assert(!negInfInterval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 6855 6856 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 3)))); 6857 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 4)))); 6858 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 5)))); 6859 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 6)))); 6860 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 7)))); 6861 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 8)))); 6862 6863 assert(NegInfInterval!Date(Date(2010, 7, 3)).intersects(negInfInterval)); 6864 assert(NegInfInterval!Date(Date(2010, 7, 4)).intersects(negInfInterval)); 6865 assert(NegInfInterval!Date(Date(2010, 7, 5)).intersects(negInfInterval)); 6866 assert(NegInfInterval!Date(Date(2012, 1, 6)).intersects(negInfInterval)); 6867 assert(NegInfInterval!Date(Date(2012, 1, 7)).intersects(negInfInterval)); 6868 assert(NegInfInterval!Date(Date(2012, 1, 8)).intersects(negInfInterval)); 6869 6870 assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 3)))); 6871 assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 4)))); 6872 assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 5)))); 6873 assert(negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 6)))); 6874 assert(!negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 7)))); 6875 assert(!negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 8)))); 6876 6877 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6878 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6879 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6880 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6881 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6882 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6883 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6884 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6885 assert(negInfInterval.intersects(interval)); 6886 assert(negInfInterval.intersects(cInterval)); 6887 assert(negInfInterval.intersects(iInterval)); 6888 assert(negInfInterval.intersects(posInfInterval)); 6889 assert(negInfInterval.intersects(cPosInfInterval)); 6890 assert(negInfInterval.intersects(iPosInfInterval)); 6891 assert(negInfInterval.intersects(negInfInterval)); 6892 assert(negInfInterval.intersects(cNegInfInterval)); 6893 assert(negInfInterval.intersects(iNegInfInterval)); 6894 assert(cNegInfInterval.intersects(interval)); 6895 assert(cNegInfInterval.intersects(cInterval)); 6896 assert(cNegInfInterval.intersects(iInterval)); 6897 assert(cNegInfInterval.intersects(posInfInterval)); 6898 assert(cNegInfInterval.intersects(cPosInfInterval)); 6899 assert(cNegInfInterval.intersects(iPosInfInterval)); 6900 assert(cNegInfInterval.intersects(negInfInterval)); 6901 assert(cNegInfInterval.intersects(cNegInfInterval)); 6902 assert(cNegInfInterval.intersects(iNegInfInterval)); 6903 assert(iNegInfInterval.intersects(interval)); 6904 assert(iNegInfInterval.intersects(cInterval)); 6905 assert(iNegInfInterval.intersects(iInterval)); 6906 assert(iNegInfInterval.intersects(posInfInterval)); 6907 assert(iNegInfInterval.intersects(cPosInfInterval)); 6908 assert(iNegInfInterval.intersects(iPosInfInterval)); 6909 assert(iNegInfInterval.intersects(negInfInterval)); 6910 assert(iNegInfInterval.intersects(cNegInfInterval)); 6911 assert(iNegInfInterval.intersects(iNegInfInterval)); 6912 6913 //Verify Examples. 6914 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 6915 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); 6916 assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 6917 6918 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4)))); 6919 assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1)))); 6920 6921 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 5, 4)))); 6922 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2013, 7, 9)))); 6923 } 6924 6925 //Test NegInfInterval's intersection(). 6926 @safe unittest 6927 { 6928 import std.datetime.date; 6929 6930 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6931 6932 static void testInterval(I, J)(scope const I interval1, scope const J interval2) 6933 { 6934 interval1.intersection(interval2); 6935 } 6936 6937 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 6938 6939 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 6940 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 6941 6942 assertThrown!DateTimeException(testInterval(negInfInterval, PosInfInterval!Date(Date(2012, 1, 7)))); 6943 assertThrown!DateTimeException(testInterval(negInfInterval, PosInfInterval!Date(Date(2012, 1, 8)))); 6944 6945 assert(negInfInterval.intersection(negInfInterval) == negInfInterval); 6946 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == 6947 Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))); 6948 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 6949 Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); 6950 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 6951 Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))); 6952 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 6953 Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))); 6954 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 6955 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 6956 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 6957 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); 6958 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 6959 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); 6960 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 6961 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); 6962 assert(negInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 6963 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 6964 assert(negInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 6965 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); 6966 6967 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2010, 7, 3))); 6968 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2010, 7, 4))); 6969 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2010, 7, 5))); 6970 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 6))); 6971 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7))); 6972 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 7))); 6973 6974 assert(NegInfInterval!Date(Date(2010, 7, 3)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 3))); 6975 assert(NegInfInterval!Date(Date(2010, 7, 4)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 4))); 6976 assert(NegInfInterval!Date(Date(2010, 7, 5)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 5))); 6977 assert(NegInfInterval!Date(Date(2012, 1, 6)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 6))); 6978 assert(NegInfInterval!Date(Date(2012, 1, 7)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 6979 assert(NegInfInterval!Date(Date(2012, 1, 8)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 6980 6981 assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == 6982 Interval!Date(Date(2010, 7, 3), Date(2012, 1 ,7))); 6983 assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == 6984 Interval!Date(Date(2010, 7, 4), Date(2012, 1 ,7))); 6985 assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == 6986 Interval!Date(Date(2010, 7, 5), Date(2012, 1 ,7))); 6987 assert(negInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == 6988 Interval!Date(Date(2012, 1, 6), Date(2012, 1 ,7))); 6989 6990 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6991 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6992 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 6993 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6994 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6995 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 6996 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6997 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 6998 assert(!negInfInterval.intersection(interval).empty); 6999 assert(!negInfInterval.intersection(cInterval).empty); 7000 assert(!negInfInterval.intersection(iInterval).empty); 7001 assert(!negInfInterval.intersection(posInfInterval).empty); 7002 assert(!negInfInterval.intersection(cPosInfInterval).empty); 7003 assert(!negInfInterval.intersection(iPosInfInterval).empty); 7004 assert(!negInfInterval.intersection(negInfInterval).empty); 7005 assert(!negInfInterval.intersection(cNegInfInterval).empty); 7006 assert(!negInfInterval.intersection(iNegInfInterval).empty); 7007 assert(!cNegInfInterval.intersection(interval).empty); 7008 assert(!cNegInfInterval.intersection(cInterval).empty); 7009 assert(!cNegInfInterval.intersection(iInterval).empty); 7010 assert(!cNegInfInterval.intersection(posInfInterval).empty); 7011 assert(!cNegInfInterval.intersection(cPosInfInterval).empty); 7012 assert(!cNegInfInterval.intersection(iPosInfInterval).empty); 7013 assert(!cNegInfInterval.intersection(negInfInterval).empty); 7014 assert(!cNegInfInterval.intersection(cNegInfInterval).empty); 7015 assert(!cNegInfInterval.intersection(iNegInfInterval).empty); 7016 assert(!iNegInfInterval.intersection(interval).empty); 7017 assert(!iNegInfInterval.intersection(cInterval).empty); 7018 assert(!iNegInfInterval.intersection(iInterval).empty); 7019 assert(!iNegInfInterval.intersection(posInfInterval).empty); 7020 assert(!iNegInfInterval.intersection(cPosInfInterval).empty); 7021 assert(!iNegInfInterval.intersection(iPosInfInterval).empty); 7022 assert(!iNegInfInterval.intersection(negInfInterval).empty); 7023 assert(!iNegInfInterval.intersection(cNegInfInterval).empty); 7024 assert(!iNegInfInterval.intersection(iNegInfInterval).empty); 7025 7026 //Verify Examples. 7027 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 7028 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))); 7029 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == 7030 Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1))); 7031 7032 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) == 7033 Interval!Date(Date(1990, 7, 6), Date(2012, 3, 1))); 7034 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) == 7035 Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1))); 7036 7037 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) == 7038 NegInfInterval!Date(Date(1999, 7, 6))); 7039 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) == 7040 NegInfInterval!Date(Date(2012, 3, 1))); 7041 } 7042 7043 //Test NegInfInterval's isAdjacent(). 7044 @safe unittest 7045 { 7046 import std.datetime.date; 7047 7048 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7049 7050 static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval) 7051 { 7052 negInfInterval.isAdjacent(interval); 7053 } 7054 7055 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 7056 7057 assert(!negInfInterval.isAdjacent(negInfInterval)); 7058 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); 7059 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); 7060 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); 7061 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); 7062 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); 7063 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); 7064 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); 7065 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); 7066 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); 7067 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); 7068 assert(negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); 7069 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 7070 7071 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3)))); 7072 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4)))); 7073 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5)))); 7074 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6)))); 7075 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7)))); 7076 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8)))); 7077 7078 assert(!NegInfInterval!Date(Date(2010, 7, 3)).isAdjacent(negInfInterval)); 7079 assert(!NegInfInterval!Date(Date(2010, 7, 4)).isAdjacent(negInfInterval)); 7080 assert(!NegInfInterval!Date(Date(2010, 7, 5)).isAdjacent(negInfInterval)); 7081 assert(!NegInfInterval!Date(Date(2012, 1, 6)).isAdjacent(negInfInterval)); 7082 assert(!NegInfInterval!Date(Date(2012, 1, 7)).isAdjacent(negInfInterval)); 7083 assert(!NegInfInterval!Date(Date(2012, 1, 8)).isAdjacent(negInfInterval)); 7084 7085 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3)))); 7086 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4)))); 7087 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5)))); 7088 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6)))); 7089 assert(negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7)))); 7090 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8)))); 7091 7092 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7093 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7094 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7095 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7096 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7097 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7098 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7099 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7100 assert(!negInfInterval.isAdjacent(interval)); 7101 assert(!negInfInterval.isAdjacent(cInterval)); 7102 assert(!negInfInterval.isAdjacent(iInterval)); 7103 assert(!negInfInterval.isAdjacent(posInfInterval)); 7104 assert(!negInfInterval.isAdjacent(cPosInfInterval)); 7105 assert(!negInfInterval.isAdjacent(iPosInfInterval)); 7106 assert(!negInfInterval.isAdjacent(negInfInterval)); 7107 assert(!negInfInterval.isAdjacent(cNegInfInterval)); 7108 assert(!negInfInterval.isAdjacent(iNegInfInterval)); 7109 assert(!cNegInfInterval.isAdjacent(interval)); 7110 assert(!cNegInfInterval.isAdjacent(cInterval)); 7111 assert(!cNegInfInterval.isAdjacent(iInterval)); 7112 assert(!cNegInfInterval.isAdjacent(posInfInterval)); 7113 assert(!cNegInfInterval.isAdjacent(cPosInfInterval)); 7114 assert(!cNegInfInterval.isAdjacent(iPosInfInterval)); 7115 assert(!cNegInfInterval.isAdjacent(negInfInterval)); 7116 assert(!cNegInfInterval.isAdjacent(cNegInfInterval)); 7117 assert(!cNegInfInterval.isAdjacent(iNegInfInterval)); 7118 assert(!iNegInfInterval.isAdjacent(interval)); 7119 assert(!iNegInfInterval.isAdjacent(cInterval)); 7120 assert(!iNegInfInterval.isAdjacent(iInterval)); 7121 assert(!iNegInfInterval.isAdjacent(posInfInterval)); 7122 assert(!iNegInfInterval.isAdjacent(cPosInfInterval)); 7123 assert(!iNegInfInterval.isAdjacent(iPosInfInterval)); 7124 assert(!iNegInfInterval.isAdjacent(negInfInterval)); 7125 assert(!iNegInfInterval.isAdjacent(cNegInfInterval)); 7126 assert(!iNegInfInterval.isAdjacent(iNegInfInterval)); 7127 7128 //Verify Examples. 7129 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); 7130 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1)))); 7131 assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2012, 3, 1), Date(2019, 2, 2)))); 7132 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); 7133 7134 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4)))); 7135 assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1)))); 7136 7137 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 5, 4)))); 7138 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(2012, 3, 1)))); 7139 } 7140 7141 //Test NegInfInterval's merge(). 7142 @safe unittest 7143 { 7144 import std.datetime.date; 7145 7146 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7147 7148 static void testInterval(I, J)(scope const I interval1, scope const J interval2) 7149 { 7150 interval1.merge(interval2); 7151 } 7152 7153 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 7154 7155 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); 7156 7157 assert(negInfInterval.merge(negInfInterval) == negInfInterval); 7158 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == 7159 NegInfInterval!Date(Date(2012, 1, 7))); 7160 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 7161 NegInfInterval!Date(Date(2013, 7, 3))); 7162 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 7163 NegInfInterval!Date(Date(2012, 1, 7))); 7164 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 7165 NegInfInterval!Date(Date(2012, 1, 7))); 7166 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 7167 NegInfInterval!Date(Date(2012, 1, 7))); 7168 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 7169 NegInfInterval!Date(Date(2012, 1, 8))); 7170 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 7171 NegInfInterval!Date(Date(2012, 1, 7))); 7172 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 7173 NegInfInterval!Date(Date(2012, 1, 7))); 7174 assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 7175 NegInfInterval!Date(Date(2012, 1, 7))); 7176 assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 7177 NegInfInterval!Date(Date(2012, 1, 8))); 7178 assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 7179 NegInfInterval!Date(Date(2012, 1, 8))); 7180 7181 assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7))); 7182 assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7))); 7183 assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7))); 7184 assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7))); 7185 assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7))); 7186 assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8))); 7187 7188 assert(NegInfInterval!Date(Date(2010, 7, 3)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7189 assert(NegInfInterval!Date(Date(2010, 7, 4)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7190 assert(NegInfInterval!Date(Date(2010, 7, 5)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7191 assert(NegInfInterval!Date(Date(2012, 1, 6)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7192 assert(NegInfInterval!Date(Date(2012, 1, 7)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7193 assert(NegInfInterval!Date(Date(2012, 1, 8)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 8))); 7194 7195 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 3))))); 7196 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 4))))); 7197 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 5))))); 7198 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 6))))); 7199 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 7))))); 7200 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 8))))); 7201 7202 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7203 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7204 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7205 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7206 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7207 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7208 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7209 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7210 assert(!negInfInterval.merge(interval).empty); 7211 assert(!negInfInterval.merge(cInterval).empty); 7212 assert(!negInfInterval.merge(iInterval).empty); 7213 static assert(!__traits(compiles, negInfInterval.merge(posInfInterval))); 7214 static assert(!__traits(compiles, negInfInterval.merge(cPosInfInterval))); 7215 static assert(!__traits(compiles, negInfInterval.merge(iPosInfInterval))); 7216 assert(!negInfInterval.merge(negInfInterval).empty); 7217 assert(!negInfInterval.merge(cNegInfInterval).empty); 7218 assert(!negInfInterval.merge(iNegInfInterval).empty); 7219 assert(!cNegInfInterval.merge(interval).empty); 7220 assert(!cNegInfInterval.merge(cInterval).empty); 7221 assert(!cNegInfInterval.merge(iInterval).empty); 7222 static assert(!__traits(compiles, cNegInfInterval.merge(posInfInterval))); 7223 static assert(!__traits(compiles, cNegInfInterval.merge(cPosInfInterval))); 7224 static assert(!__traits(compiles, cNegInfInterval.merge(iPosInfInterval))); 7225 assert(!cNegInfInterval.merge(negInfInterval).empty); 7226 assert(!cNegInfInterval.merge(cNegInfInterval).empty); 7227 assert(!cNegInfInterval.merge(iNegInfInterval).empty); 7228 assert(!iNegInfInterval.merge(interval).empty); 7229 assert(!iNegInfInterval.merge(cInterval).empty); 7230 assert(!iNegInfInterval.merge(iInterval).empty); 7231 static assert(!__traits(compiles, iNegInfInterval.merge(posInfInterval))); 7232 static assert(!__traits(compiles, iNegInfInterval.merge(cPosInfInterval))); 7233 static assert(!__traits(compiles, iNegInfInterval.merge(iPosInfInterval))); 7234 assert(!iNegInfInterval.merge(negInfInterval).empty); 7235 assert(!iNegInfInterval.merge(cNegInfInterval).empty); 7236 assert(!iNegInfInterval.merge(iNegInfInterval).empty); 7237 7238 //Verify Examples. 7239 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 7240 NegInfInterval!Date(Date(2012, 3, 1))); 7241 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == 7242 NegInfInterval!Date(Date(2015, 9, 2))); 7243 7244 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1999, 7, 6))) == 7245 NegInfInterval!Date(Date(2012, 3, 1))); 7246 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) == 7247 NegInfInterval!Date(Date(2013, 1, 12))); 7248 } 7249 7250 //Test NegInfInterval's span(). 7251 @safe unittest 7252 { 7253 import std.datetime.date; 7254 7255 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7256 7257 static void testInterval(I, J)(scope const I interval1, scope const J interval2) 7258 { 7259 interval1.span(interval2); 7260 } 7261 7262 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); 7263 7264 assert(negInfInterval.span(negInfInterval) == negInfInterval); 7265 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == 7266 NegInfInterval!Date(Date(2012, 1, 7))); 7267 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == 7268 NegInfInterval!Date(Date(2013, 7, 3))); 7269 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == 7270 NegInfInterval!Date(Date(2012, 1, 7))); 7271 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == 7272 NegInfInterval!Date(Date(2012, 1, 7))); 7273 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == 7274 NegInfInterval!Date(Date(2012, 1, 7))); 7275 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == 7276 NegInfInterval!Date(Date(2012, 1, 8))); 7277 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == 7278 NegInfInterval!Date(Date(2012, 1, 7))); 7279 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == 7280 NegInfInterval!Date(Date(2012, 1, 7))); 7281 assert(negInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == 7282 NegInfInterval!Date(Date(2012, 1, 7))); 7283 assert(negInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == 7284 NegInfInterval!Date(Date(2012, 1, 8))); 7285 assert(negInfInterval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == 7286 NegInfInterval!Date(Date(2012, 1, 8))); 7287 assert(negInfInterval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == 7288 NegInfInterval!Date(Date(2012, 1, 9))); 7289 7290 assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7))); 7291 assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7))); 7292 assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7))); 7293 assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7))); 7294 assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7))); 7295 assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8))); 7296 7297 assert(NegInfInterval!Date(Date(2010, 7, 3)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7298 assert(NegInfInterval!Date(Date(2010, 7, 4)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7299 assert(NegInfInterval!Date(Date(2010, 7, 5)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7300 assert(NegInfInterval!Date(Date(2012, 1, 6)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7301 assert(NegInfInterval!Date(Date(2012, 1, 7)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); 7302 assert(NegInfInterval!Date(Date(2012, 1, 8)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 8))); 7303 7304 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 3))))); 7305 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 4))))); 7306 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 5))))); 7307 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 6))))); 7308 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 7))))); 7309 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 8))))); 7310 7311 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7312 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7313 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 7314 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7315 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7316 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 7317 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7318 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7319 assert(!negInfInterval.span(interval).empty); 7320 assert(!negInfInterval.span(cInterval).empty); 7321 assert(!negInfInterval.span(iInterval).empty); 7322 static assert(!__traits(compiles, negInfInterval.span(posInfInterval))); 7323 static assert(!__traits(compiles, negInfInterval.span(cPosInfInterval))); 7324 static assert(!__traits(compiles, negInfInterval.span(iPosInfInterval))); 7325 assert(!negInfInterval.span(negInfInterval).empty); 7326 assert(!negInfInterval.span(cNegInfInterval).empty); 7327 assert(!negInfInterval.span(iNegInfInterval).empty); 7328 assert(!cNegInfInterval.span(interval).empty); 7329 assert(!cNegInfInterval.span(cInterval).empty); 7330 assert(!cNegInfInterval.span(iInterval).empty); 7331 static assert(!__traits(compiles, cNegInfInterval.span(posInfInterval))); 7332 static assert(!__traits(compiles, cNegInfInterval.span(cPosInfInterval))); 7333 static assert(!__traits(compiles, cNegInfInterval.span(iPosInfInterval))); 7334 assert(!cNegInfInterval.span(negInfInterval).empty); 7335 assert(!cNegInfInterval.span(cNegInfInterval).empty); 7336 assert(!cNegInfInterval.span(iNegInfInterval).empty); 7337 assert(!iNegInfInterval.span(interval).empty); 7338 assert(!iNegInfInterval.span(cInterval).empty); 7339 assert(!iNegInfInterval.span(iInterval).empty); 7340 static assert(!__traits(compiles, iNegInfInterval.span(posInfInterval))); 7341 static assert(!__traits(compiles, iNegInfInterval.span(cPosInfInterval))); 7342 static assert(!__traits(compiles, iNegInfInterval.span(iPosInfInterval))); 7343 assert(!iNegInfInterval.span(negInfInterval).empty); 7344 assert(!iNegInfInterval.span(cNegInfInterval).empty); 7345 assert(!iNegInfInterval.span(iNegInfInterval).empty); 7346 7347 //Verify Examples. 7348 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == 7349 NegInfInterval!Date(Date(2012, 3, 1))); 7350 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == 7351 NegInfInterval!Date(Date(2015, 9, 2))); 7352 assert(NegInfInterval!Date(Date(1600, 1, 7)).span(Interval!Date(Date(2012, 3, 11), Date(2017, 7, 1))) == 7353 NegInfInterval!Date(Date(2017, 7, 1))); 7354 7355 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1999, 7, 6))) == 7356 NegInfInterval!Date(Date(2012, 3, 1))); 7357 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) == 7358 NegInfInterval!Date(Date(2013, 1, 12))); 7359 } 7360 7361 //Test NegInfInterval's shift(). 7362 @safe unittest 7363 { 7364 import std.datetime.date; 7365 7366 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 7367 7368 static void testInterval(I)(I interval, scope const Duration duration, 7369 scope const I expected, size_t line = __LINE__) 7370 { 7371 interval.shift(duration); 7372 assert(interval == expected); 7373 } 7374 7375 testInterval(interval, dur!"days"(22), NegInfInterval!Date(Date(2012, 1, 29))); 7376 testInterval(interval, dur!"days"(-22), NegInfInterval!Date(Date(2011, 12, 16))); 7377 7378 const cInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7379 immutable iInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7380 static assert(!__traits(compiles, cInterval.shift(dur!"days"(5)))); 7381 static assert(!__traits(compiles, iInterval.shift(dur!"days"(5)))); 7382 7383 //Verify Examples. 7384 auto interval1 = NegInfInterval!Date(Date(2012, 4, 5)); 7385 auto interval2 = NegInfInterval!Date(Date(2012, 4, 5)); 7386 7387 interval1.shift(dur!"days"(50)); 7388 assert(interval1 == NegInfInterval!Date(Date(2012, 5, 25))); 7389 7390 interval2.shift(dur!"days"(-50)); 7391 assert(interval2 == NegInfInterval!Date( Date(2012, 2, 15))); 7392 } 7393 7394 //Test NegInfInterval's shift(int, int, AllowDayOverflow). 7395 @safe unittest 7396 { 7397 import std.datetime.date; 7398 7399 { 7400 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 7401 7402 static void testIntervalFail(I)(I interval, int years, int months) 7403 { 7404 interval.shift(years, months); 7405 } 7406 7407 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, 7408 in I expected, size_t line = __LINE__) 7409 { 7410 interval.shift(years, months, allow); 7411 assert(interval == expected); 7412 } 7413 7414 testInterval(interval, 5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2017, 1, 7))); 7415 testInterval(interval, -5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2007, 1, 7))); 7416 7417 auto interval2 = NegInfInterval!Date(Date(2010, 5, 31)); 7418 7419 testInterval(interval2, 1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 7, 1))); 7420 testInterval(interval2, 1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 5, 1))); 7421 testInterval(interval2, -1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 5, 1))); 7422 testInterval(interval2, -1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 7, 1))); 7423 7424 testInterval(interval2, 1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 6, 30))); 7425 testInterval(interval2, 1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 4, 30))); 7426 testInterval(interval2, -1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 4, 30))); 7427 testInterval(interval2, -1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 6, 30))); 7428 } 7429 7430 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7431 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7432 static assert(!__traits(compiles, cNegInfInterval.shift(1))); 7433 static assert(!__traits(compiles, iNegInfInterval.shift(1))); 7434 7435 //Verify Examples. 7436 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); 7437 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); 7438 7439 interval1.shift(2); 7440 assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1))); 7441 7442 interval2.shift(-2); 7443 assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1))); 7444 } 7445 7446 //Test NegInfInterval's expand(). 7447 @safe unittest 7448 { 7449 import std.datetime.date; 7450 7451 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 7452 7453 static void testInterval(I)(I interval, 7454 scope const Duration duration, scope const I expected, size_t line = __LINE__) 7455 { 7456 interval.expand(duration); 7457 assert(interval == expected); 7458 } 7459 7460 testInterval(interval, dur!"days"(22), NegInfInterval!Date(Date(2012, 1, 29))); 7461 testInterval(interval, dur!"days"(-22), NegInfInterval!Date(Date(2011, 12, 16))); 7462 7463 const cInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7464 immutable iInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7465 static assert(!__traits(compiles, cInterval.expand(dur!"days"(5)))); 7466 static assert(!__traits(compiles, iInterval.expand(dur!"days"(5)))); 7467 7468 //Verify Examples. 7469 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); 7470 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); 7471 7472 interval1.expand(dur!"days"(2)); 7473 assert(interval1 == NegInfInterval!Date(Date(2012, 3, 3))); 7474 7475 interval2.expand(dur!"days"(-2)); 7476 assert(interval2 == NegInfInterval!Date(Date(2012, 2, 28))); 7477 } 7478 7479 //Test NegInfInterval's expand(int, int, AllowDayOverflow). 7480 @safe unittest 7481 { 7482 import std.datetime.date; 7483 7484 { 7485 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 7486 7487 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, 7488 in I expected, size_t line = __LINE__) 7489 { 7490 interval.expand(years, months, allow); 7491 assert(interval == expected); 7492 } 7493 7494 testInterval(interval, 5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2017, 1, 7))); 7495 testInterval(interval, -5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2007, 1, 7))); 7496 7497 auto interval2 = NegInfInterval!Date(Date(2010, 5, 31)); 7498 7499 testInterval(interval2, 1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 7, 1))); 7500 testInterval(interval2, 1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 5, 1))); 7501 testInterval(interval2, -1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 5, 1))); 7502 testInterval(interval2, -1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 7, 1))); 7503 7504 testInterval(interval2, 1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 6, 30))); 7505 testInterval(interval2, 1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 4, 30))); 7506 testInterval(interval2, -1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 4, 30))); 7507 testInterval(interval2, -1, 1, AllowDayOverflow.no, NegInfInterval!Date( Date(2009, 6, 30))); 7508 } 7509 7510 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7511 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7512 static assert(!__traits(compiles, cNegInfInterval.expand(1))); 7513 static assert(!__traits(compiles, iNegInfInterval.expand(1))); 7514 7515 //Verify Examples. 7516 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); 7517 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); 7518 7519 interval1.expand(2); 7520 assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1))); 7521 7522 interval2.expand(-2); 7523 assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1))); 7524 } 7525 7526 //Test NegInfInterval's bwdRange(). 7527 @system unittest 7528 { 7529 import std.datetime.date; 7530 7531 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7532 7533 static void testInterval(NegInfInterval!Date negInfInterval) 7534 { 7535 negInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront(); 7536 } 7537 7538 assertThrown!DateTimeException(testInterval(negInfInterval)); 7539 7540 assert(NegInfInterval!Date(Date(2010, 10, 1)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front == 7541 Date(2010, 10, 1)); 7542 7543 assert(NegInfInterval!Date(Date(2010, 10, 1)).bwdRange( 7544 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 24)); 7545 7546 //Verify Examples. 7547 auto interval = NegInfInterval!Date(Date(2010, 9, 9)); 7548 auto func = delegate (scope const Date date) 7549 { 7550 if ((date.day & 1) == 0) 7551 return date - dur!"days"(2); 7552 return date - dur!"days"(1); 7553 }; 7554 auto range = interval.bwdRange(func); 7555 7556 //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). 7557 assert(range.front == Date(2010, 9, 9)); 7558 7559 range.popFront(); 7560 assert(range.front == Date(2010, 9, 8)); 7561 7562 range.popFront(); 7563 assert(range.front == Date(2010, 9, 6)); 7564 7565 range.popFront(); 7566 assert(range.front == Date(2010, 9, 4)); 7567 7568 range.popFront(); 7569 assert(range.front == Date(2010, 9, 2)); 7570 7571 range.popFront(); 7572 assert(!range.empty); 7573 7574 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7575 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7576 assert(!cNegInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty); 7577 assert(!iNegInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty); 7578 } 7579 7580 //Test NegInfInterval's toString(). 7581 @safe unittest 7582 { 7583 import std.datetime.date; 7584 7585 assert(NegInfInterval!Date(Date(2012, 1, 7)).toString() == "[-∞ - 2012-Jan-07)"); 7586 7587 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7588 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 7589 assert(cNegInfInterval.toString()); 7590 assert(iNegInfInterval.toString()); 7591 } 7592 7593 7594 /++ 7595 Range-generating function. 7596 7597 Returns a delegate which returns the next time point with the given 7598 `DayOfWeek` in a range. 7599 7600 Using this delegate allows iteration over successive time points which 7601 are all the same day of the week. e.g. passing `DayOfWeek.mon` to 7602 `everyDayOfWeek` would result in a delegate which could be used to 7603 iterate over all of the Mondays in a range. 7604 7605 Params: 7606 dir = The direction to iterate in. If passing the return value to 7607 `fwdRange`, use `Direction.fwd`. If passing it to 7608 `bwdRange`, use `Direction.bwd`. 7609 dayOfWeek = The week that each time point in the range will be. 7610 +/ 7611 TP delegate(scope const TP) everyDayOfWeek(TP, Direction dir = Direction.fwd)(DayOfWeek dayOfWeek) nothrow 7612 if (isTimePoint!TP && 7613 (dir == Direction.fwd || dir == Direction.bwd) && 7614 __traits(hasMember, TP, "dayOfWeek") && 7615 !__traits(isStaticFunction, TP.dayOfWeek) && 7616 is(typeof(TP.dayOfWeek) == DayOfWeek)) 7617 { 7618 TP func(scope const TP tp) 7619 { 7620 TP retval = cast(TP) tp; 7621 immutable days = daysToDayOfWeek(retval.dayOfWeek, dayOfWeek); 7622 7623 static if (dir == Direction.fwd) 7624 immutable adjustedDays = days == 0 ? 7 : days; 7625 else 7626 immutable adjustedDays = days == 0 ? -7 : days - 7; 7627 7628 return retval += dur!"days"(adjustedDays); 7629 } 7630 7631 return &func; 7632 } 7633 7634 /// 7635 @system unittest 7636 { 7637 import std.datetime.date : Date, DayOfWeek; 7638 7639 auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27)); 7640 auto func = everyDayOfWeek!Date(DayOfWeek.mon); 7641 auto range = interval.fwdRange(func); 7642 7643 // A Thursday. Using PopFirst.yes would have made this Date(2010, 9, 6). 7644 assert(range.front == Date(2010, 9, 2)); 7645 7646 range.popFront(); 7647 assert(range.front == Date(2010, 9, 6)); 7648 7649 range.popFront(); 7650 assert(range.front == Date(2010, 9, 13)); 7651 7652 range.popFront(); 7653 assert(range.front == Date(2010, 9, 20)); 7654 7655 range.popFront(); 7656 assert(range.empty); 7657 } 7658 7659 @system unittest 7660 { 7661 import std.datetime.date; 7662 import std.datetime.systime; 7663 7664 auto funcFwd = everyDayOfWeek!Date(DayOfWeek.mon); 7665 auto funcBwd = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.mon); 7666 7667 assert(funcFwd(Date(2010, 8, 28)) == Date(2010, 8, 30)); 7668 assert(funcFwd(Date(2010, 8, 29)) == Date(2010, 8, 30)); 7669 assert(funcFwd(Date(2010, 8, 30)) == Date(2010, 9, 6)); 7670 assert(funcFwd(Date(2010, 8, 31)) == Date(2010, 9, 6)); 7671 assert(funcFwd(Date(2010, 9, 1)) == Date(2010, 9, 6)); 7672 assert(funcFwd(Date(2010, 9, 2)) == Date(2010, 9, 6)); 7673 assert(funcFwd(Date(2010, 9, 3)) == Date(2010, 9, 6)); 7674 assert(funcFwd(Date(2010, 9, 4)) == Date(2010, 9, 6)); 7675 assert(funcFwd(Date(2010, 9, 5)) == Date(2010, 9, 6)); 7676 assert(funcFwd(Date(2010, 9, 6)) == Date(2010, 9, 13)); 7677 assert(funcFwd(Date(2010, 9, 7)) == Date(2010, 9, 13)); 7678 7679 assert(funcBwd(Date(2010, 8, 28)) == Date(2010, 8, 23)); 7680 assert(funcBwd(Date(2010, 8, 29)) == Date(2010, 8, 23)); 7681 assert(funcBwd(Date(2010, 8, 30)) == Date(2010, 8, 23)); 7682 assert(funcBwd(Date(2010, 8, 31)) == Date(2010, 8, 30)); 7683 assert(funcBwd(Date(2010, 9, 1)) == Date(2010, 8, 30)); 7684 assert(funcBwd(Date(2010, 9, 2)) == Date(2010, 8, 30)); 7685 assert(funcBwd(Date(2010, 9, 3)) == Date(2010, 8, 30)); 7686 assert(funcBwd(Date(2010, 9, 4)) == Date(2010, 8, 30)); 7687 assert(funcBwd(Date(2010, 9, 5)) == Date(2010, 8, 30)); 7688 assert(funcBwd(Date(2010, 9, 6)) == Date(2010, 8, 30)); 7689 assert(funcBwd(Date(2010, 9, 7)) == Date(2010, 9, 6)); 7690 7691 static assert(!__traits(compiles, everyDayOfWeek!TimeOfDay(DayOfWeek.mon))); 7692 assert(everyDayOfWeek!DateTime(DayOfWeek.mon) !is null); 7693 assert(everyDayOfWeek!SysTime(DayOfWeek.mon) !is null); 7694 } 7695 7696 7697 /++ 7698 Range-generating function. 7699 7700 Returns a delegate which returns the next time point with the given month 7701 which would be reached by adding months to the given time point. 7702 7703 So, using this delegate allows iteration over successive time points 7704 which are in the same month but different years. For example, 7705 iterate over each successive December 25th in an interval by starting with a 7706 date which had the 25th as its day and passed `Month.dec` to 7707 `everyMonth` to create the delegate. 7708 7709 Since it wouldn't really make sense to be iterating over a specific month 7710 and end up with some of the time points in the succeeding month or two years 7711 after the previous time point, `AllowDayOverflow.no` is always used when 7712 calculating the next time point. 7713 7714 Params: 7715 dir = The direction to iterate in. If passing the return value to 7716 `fwdRange`, use `Direction.fwd`. If passing it to 7717 `bwdRange`, use `Direction.bwd`. 7718 month = The month that each time point in the range will be in 7719 (January is 1). 7720 +/ 7721 TP delegate(scope const TP) everyMonth(TP, Direction dir = Direction.fwd)(int month) 7722 if (isTimePoint!TP && 7723 (dir == Direction.fwd || dir == Direction.bwd) && 7724 __traits(hasMember, TP, "month") && 7725 !__traits(isStaticFunction, TP.month) && 7726 is(typeof(TP.month) == Month)) 7727 { 7728 import std.datetime.date : enforceValid, monthsToMonth; 7729 7730 enforceValid!"months"(month); 7731 7732 TP func(scope const TP tp) 7733 { 7734 TP retval = cast(TP) tp; 7735 immutable months = monthsToMonth(retval.month, month); 7736 7737 static if (dir == Direction.fwd) 7738 immutable adjustedMonths = months == 0 ? 12 : months; 7739 else 7740 immutable adjustedMonths = months == 0 ? -12 : months - 12; 7741 7742 retval.add!"months"(adjustedMonths, AllowDayOverflow.no); 7743 7744 if (retval.month != month) 7745 { 7746 retval.add!"months"(-1); 7747 assert(retval.month == month); 7748 } 7749 7750 return retval; 7751 } 7752 7753 return &func; 7754 } 7755 7756 /// 7757 @system unittest 7758 { 7759 import std.datetime.date : Date, Month; 7760 7761 auto interval = Interval!Date(Date(2000, 1, 30), Date(2004, 8, 5)); 7762 auto func = everyMonth!Date(Month.feb); 7763 auto range = interval.fwdRange(func); 7764 7765 // Using PopFirst.yes would have made this Date(2010, 2, 29). 7766 assert(range.front == Date(2000, 1, 30)); 7767 7768 range.popFront(); 7769 assert(range.front == Date(2000, 2, 29)); 7770 7771 range.popFront(); 7772 assert(range.front == Date(2001, 2, 28)); 7773 7774 range.popFront(); 7775 assert(range.front == Date(2002, 2, 28)); 7776 7777 range.popFront(); 7778 assert(range.front == Date(2003, 2, 28)); 7779 7780 range.popFront(); 7781 assert(range.front == Date(2004, 2, 28)); 7782 7783 range.popFront(); 7784 assert(range.empty); 7785 } 7786 7787 @system unittest 7788 { 7789 import std.datetime.date; 7790 import std.datetime.systime; 7791 7792 auto funcFwd = everyMonth!Date(Month.jun); 7793 auto funcBwd = everyMonth!(Date, Direction.bwd)(Month.jun); 7794 7795 assert(funcFwd(Date(2010, 5, 31)) == Date(2010, 6, 30)); 7796 assert(funcFwd(Date(2010, 6, 30)) == Date(2011, 6, 30)); 7797 assert(funcFwd(Date(2010, 7, 31)) == Date(2011, 6, 30)); 7798 assert(funcFwd(Date(2010, 8, 31)) == Date(2011, 6, 30)); 7799 assert(funcFwd(Date(2010, 9, 30)) == Date(2011, 6, 30)); 7800 assert(funcFwd(Date(2010, 10, 31)) == Date(2011, 6, 30)); 7801 assert(funcFwd(Date(2010, 11, 30)) == Date(2011, 6, 30)); 7802 assert(funcFwd(Date(2010, 12, 31)) == Date(2011, 6, 30)); 7803 assert(funcFwd(Date(2011, 1, 31)) == Date(2011, 6, 30)); 7804 assert(funcFwd(Date(2011, 2, 28)) == Date(2011, 6, 28)); 7805 assert(funcFwd(Date(2011, 3, 31)) == Date(2011, 6, 30)); 7806 assert(funcFwd(Date(2011, 4, 30)) == Date(2011, 6, 30)); 7807 assert(funcFwd(Date(2011, 5, 31)) == Date(2011, 6, 30)); 7808 assert(funcFwd(Date(2011, 6, 30)) == Date(2012, 6, 30)); 7809 assert(funcFwd(Date(2011, 7, 31)) == Date(2012, 6, 30)); 7810 7811 assert(funcBwd(Date(2010, 5, 31)) == Date(2009, 6, 30)); 7812 assert(funcBwd(Date(2010, 6, 30)) == Date(2009, 6, 30)); 7813 assert(funcBwd(Date(2010, 7, 31)) == Date(2010, 6, 30)); 7814 assert(funcBwd(Date(2010, 8, 31)) == Date(2010, 6, 30)); 7815 assert(funcBwd(Date(2010, 9, 30)) == Date(2010, 6, 30)); 7816 assert(funcBwd(Date(2010, 10, 31)) == Date(2010, 6, 30)); 7817 assert(funcBwd(Date(2010, 11, 30)) == Date(2010, 6, 30)); 7818 assert(funcBwd(Date(2010, 12, 31)) == Date(2010, 6, 30)); 7819 assert(funcBwd(Date(2011, 1, 31)) == Date(2010, 6, 30)); 7820 assert(funcBwd(Date(2011, 2, 28)) == Date(2010, 6, 28)); 7821 assert(funcBwd(Date(2011, 3, 31)) == Date(2010, 6, 30)); 7822 assert(funcBwd(Date(2011, 4, 30)) == Date(2010, 6, 30)); 7823 assert(funcBwd(Date(2011, 5, 31)) == Date(2010, 6, 30)); 7824 assert(funcBwd(Date(2011, 6, 30)) == Date(2010, 6, 30)); 7825 assert(funcBwd(Date(2011, 7, 30)) == Date(2011, 6, 30)); 7826 7827 static assert(!__traits(compiles, everyMonth!TimeOfDay(Month.jan))); 7828 assert(everyMonth!DateTime(Month.jan) !is null); 7829 assert(everyMonth!SysTime(Month.jan) !is null); 7830 } 7831 7832 7833 /++ 7834 Range-generating function. 7835 7836 Returns a delegate which returns the next time point which is the given 7837 duration later. 7838 7839 Using this delegate allows iteration over successive time points which 7840 are apart by the given duration e.g. passing `dur!"days"(3)` to 7841 `everyDuration` would result in a delegate which could be used to iterate 7842 over a range of days which are each 3 days apart. 7843 7844 Params: 7845 dir = The direction to iterate in. If passing the return value to 7846 `fwdRange`, use `Direction.fwd`. If passing it to 7847 `bwdRange`, use `Direction.bwd`. 7848 duration = The duration which separates each successive time point in 7849 the range. 7850 +/ 7851 TP delegate(return scope const TP) everyDuration(TP, Direction dir = Direction.fwd, D)(D duration) nothrow 7852 if (isTimePoint!TP && 7853 __traits(compiles, TP.init + duration) && 7854 (dir == Direction.fwd || dir == Direction.bwd)) 7855 { 7856 TP func(return scope const TP tp) 7857 { 7858 static if (dir == Direction.fwd) 7859 return tp + duration; 7860 else 7861 return tp - duration; 7862 } 7863 7864 return &func; 7865 } 7866 7867 /// 7868 @system unittest 7869 { 7870 import core.time : dur; 7871 import std.datetime.date : Date; 7872 7873 auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27)); 7874 auto func = everyDuration!Date(dur!"days"(8)); 7875 auto range = interval.fwdRange(func); 7876 7877 // Using PopFirst.yes would have made this Date(2010, 9, 10). 7878 assert(range.front == Date(2010, 9, 2)); 7879 7880 range.popFront(); 7881 assert(range.front == Date(2010, 9, 10)); 7882 7883 range.popFront(); 7884 assert(range.front == Date(2010, 9, 18)); 7885 7886 range.popFront(); 7887 assert(range.front == Date(2010, 9, 26)); 7888 7889 range.popFront(); 7890 assert(range.empty); 7891 } 7892 7893 @system unittest 7894 { 7895 import std.datetime.date; 7896 import std.datetime.systime; 7897 7898 auto funcFwd = everyDuration!Date(dur!"days"(27)); 7899 auto funcBwd = everyDuration!(Date, Direction.bwd)(dur!"days"(27)); 7900 7901 assert(funcFwd(Date(2009, 12, 25)) == Date(2010, 1, 21)); 7902 assert(funcFwd(Date(2009, 12, 26)) == Date(2010, 1, 22)); 7903 assert(funcFwd(Date(2009, 12, 27)) == Date(2010, 1, 23)); 7904 assert(funcFwd(Date(2009, 12, 28)) == Date(2010, 1, 24)); 7905 7906 assert(funcBwd(Date(2010, 1, 21)) == Date(2009, 12, 25)); 7907 assert(funcBwd(Date(2010, 1, 22)) == Date(2009, 12, 26)); 7908 assert(funcBwd(Date(2010, 1, 23)) == Date(2009, 12, 27)); 7909 assert(funcBwd(Date(2010, 1, 24)) == Date(2009, 12, 28)); 7910 7911 assert(everyDuration!Date(dur!"hnsecs"(1)) !is null); 7912 assert(everyDuration!TimeOfDay(dur!"hnsecs"(1)) !is null); 7913 assert(everyDuration!DateTime(dur!"hnsecs"(1)) !is null); 7914 assert(everyDuration!SysTime(dur!"hnsecs"(1)) !is null); 7915 } 7916 7917 7918 /++ 7919 Range-generating function. 7920 7921 Returns a delegate which returns the next time point which is the given 7922 number of years, month, and duration later. 7923 7924 The difference between this version of `everyDuration` and the version 7925 which just takes a $(REF Duration, core,time) is that this one also takes 7926 the number of years and months (along with an `AllowDayOverflow` to 7927 indicate whether adding years and months should allow the days to overflow). 7928 7929 Note that if iterating forward, `add!"years"()` is called on the given 7930 time point, then `add!"months"()`, and finally the duration is added 7931 to it. However, if iterating backwards, the duration is added first, then 7932 `add!"months"()` is called, and finally `add!"years"()` is called. 7933 That way, going backwards generates close to the same time points that 7934 iterating forward does, but since adding years and months is not entirely 7935 reversible (due to possible day overflow, regardless of whether 7936 `AllowDayOverflow.yes` or `AllowDayOverflow.no` is used), it can't be 7937 guaranteed that iterating backwards will give the same time points as 7938 iterating forward would have (even assuming that the end of the range is a 7939 time point which would be returned by the delegate when iterating forward 7940 from `begin`). 7941 7942 Params: 7943 dir = The direction to iterate in. If passing the return 7944 value to `fwdRange`, use `Direction.fwd`. If 7945 passing it to `bwdRange`, use `Direction.bwd`. 7946 years = The number of years to add to the time point passed to 7947 the delegate. 7948 months = The number of months to add to the time point passed to 7949 the delegate. 7950 allowOverflow = Whether the days should be allowed to overflow on 7951 `begin` and `end`, causing their month to 7952 increment. 7953 duration = The duration to add to the time point passed to the 7954 delegate. 7955 +/ 7956 TP delegate(scope const TP) everyDuration(TP, Direction dir = Direction.fwd, D) 7957 (int years, 7958 int months = 0, 7959 AllowDayOverflow allowOverflow = AllowDayOverflow.yes, 7960 D duration = dur!"days"(0)) nothrow 7961 if (isTimePoint!TP && 7962 __traits(compiles, TP.init + duration) && 7963 __traits(compiles, TP.init.add!"years"(years)) && 7964 __traits(compiles, TP.init.add!"months"(months)) && 7965 (dir == Direction.fwd || dir == Direction.bwd)) 7966 { 7967 TP func(scope const TP tp) 7968 { 7969 static if (dir == Direction.fwd) 7970 { 7971 TP retval = cast(TP) tp; 7972 7973 retval.add!"years"(years, allowOverflow); 7974 retval.add!"months"(months, allowOverflow); 7975 7976 return retval + duration; 7977 } 7978 else 7979 { 7980 TP retval = tp - duration; 7981 7982 retval.add!"months"(-months, allowOverflow); 7983 retval.add!"years"(-years, allowOverflow); 7984 7985 return retval; 7986 } 7987 } 7988 7989 return &func; 7990 } 7991 7992 /// 7993 @system unittest 7994 { 7995 import core.time : dur; 7996 import std.datetime.date : AllowDayOverflow, Date; 7997 7998 auto interval = Interval!Date(Date(2010, 9, 2), Date(2025, 9, 27)); 7999 auto func = everyDuration!Date(4, 1, AllowDayOverflow.yes, dur!"days"(2)); 8000 auto range = interval.fwdRange(func); 8001 8002 // Using PopFirst.yes would have made this Date(2014, 10, 12). 8003 assert(range.front == Date(2010, 9, 2)); 8004 8005 range.popFront(); 8006 assert(range.front == Date(2014, 10, 4)); 8007 8008 range.popFront(); 8009 assert(range.front == Date(2018, 11, 6)); 8010 8011 range.popFront(); 8012 assert(range.front == Date(2022, 12, 8)); 8013 8014 range.popFront(); 8015 assert(range.empty); 8016 } 8017 8018 @system unittest 8019 { 8020 import std.datetime.date; 8021 import std.datetime.systime; 8022 8023 { 8024 auto funcFwd = everyDuration!Date(1, 2, AllowDayOverflow.yes, dur!"days"(3)); 8025 auto funcBwd = everyDuration!(Date, Direction.bwd)(1, 2, AllowDayOverflow.yes, dur!"days"(3)); 8026 8027 assert(funcFwd(Date(2009, 12, 25)) == Date(2011, 2, 28)); 8028 assert(funcFwd(Date(2009, 12, 26)) == Date(2011, 3, 1)); 8029 assert(funcFwd(Date(2009, 12, 27)) == Date(2011, 3, 2)); 8030 assert(funcFwd(Date(2009, 12, 28)) == Date(2011, 3, 3)); 8031 assert(funcFwd(Date(2009, 12, 29)) == Date(2011, 3, 4)); 8032 8033 assert(funcBwd(Date(2011, 2, 28)) == Date(2009, 12, 25)); 8034 assert(funcBwd(Date(2011, 3, 1)) == Date(2009, 12, 26)); 8035 assert(funcBwd(Date(2011, 3, 2)) == Date(2009, 12, 27)); 8036 assert(funcBwd(Date(2011, 3, 3)) == Date(2009, 12, 28)); 8037 assert(funcBwd(Date(2011, 3, 4)) == Date(2010, 1, 1)); 8038 } 8039 8040 { 8041 auto funcFwd = everyDuration!Date(1, 2, AllowDayOverflow.no, dur!"days"(3)); 8042 auto funcBwd = everyDuration!(Date, Direction.bwd)(1, 2, AllowDayOverflow.yes, dur!"days"(3)); 8043 8044 assert(funcFwd(Date(2009, 12, 25)) == Date(2011, 2, 28)); 8045 assert(funcFwd(Date(2009, 12, 26)) == Date(2011, 3, 1)); 8046 assert(funcFwd(Date(2009, 12, 27)) == Date(2011, 3, 2)); 8047 assert(funcFwd(Date(2009, 12, 28)) == Date(2011, 3, 3)); 8048 assert(funcFwd(Date(2009, 12, 29)) == Date(2011, 3, 3)); 8049 8050 assert(funcBwd(Date(2011, 2, 28)) == Date(2009, 12, 25)); 8051 assert(funcBwd(Date(2011, 3, 1)) == Date(2009, 12, 26)); 8052 assert(funcBwd(Date(2011, 3, 2)) == Date(2009, 12, 27)); 8053 assert(funcBwd(Date(2011, 3, 3)) == Date(2009, 12, 28)); 8054 assert(funcBwd(Date(2011, 3, 4)) == Date(2010, 1, 1)); 8055 } 8056 8057 assert(everyDuration!Date(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)) !is null); 8058 static assert(!__traits(compiles, everyDuration!TimeOfDay(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)))); 8059 assert(everyDuration!DateTime(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)) !is null); 8060 assert(everyDuration!SysTime(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)) !is null); 8061 } 8062 8063 8064 /++ 8065 A range over an $(LREF Interval). 8066 8067 `IntervalRange` is only ever constructed by $(LREF Interval). However, when 8068 it is constructed, it is given a function, `func`, which is used to 8069 generate the time points which are iterated over. `func` takes a time 8070 point and returns a time point of the same type. For instance, 8071 to iterate over all of the days in 8072 the interval `Interval!Date`, pass a function to $(LREF Interval)'s 8073 `fwdRange` where that function took a $(REF Date,std,datetime,date) and 8074 returned a $(REF Date,std,datetime,date) which was one day later. That 8075 function would then be used by `IntervalRange`'s `popFront` to iterate 8076 over the $(REF Date,std,datetime,date)s in the interval. 8077 8078 If $(D dir == Direction.fwd), then a range iterates forward in time, whereas 8079 if $(D dir == Direction.bwd), then it iterates backwards in time. So, if 8080 $(D dir == Direction.fwd) then $(D front == interval.begin), whereas if 8081 $(D dir == Direction.bwd) then $(D front == interval.end). `func` must 8082 generate a time point going in the proper direction of iteration, or a 8083 $(REF DateTimeException,std,datetime,date) will be thrown. So, to iterate 8084 forward in time, the time point that `func` generates must be later in 8085 time than the one passed to it. If it's either identical or earlier in time, 8086 then a $(REF DateTimeException,std,datetime,date) will be thrown. To 8087 iterate backwards, then the generated time point must be before the time 8088 point which was passed in. 8089 8090 If the generated time point is ever passed the edge of the range in the 8091 proper direction, then the edge of that range will be used instead. So, if 8092 iterating forward, and the generated time point is past the interval's 8093 `end`, then `front` becomes `end`. If iterating backwards, and the 8094 generated time point is before `begin`, then `front` becomes 8095 `begin`. In either case, the range would then be empty. 8096 8097 Also note that while normally the `begin` of an interval is included in 8098 it and its `end` is excluded from it, if $(D dir == Direction.bwd), then 8099 `begin` is treated as excluded and `end` is treated as included. This 8100 allows for the same behavior in both directions. This works because none of 8101 $(LREF Interval)'s functions which care about whether `begin` or `end` 8102 is included or excluded are ever called by `IntervalRange`. `interval` 8103 returns a normal interval, regardless of whether $(D dir == Direction.fwd) 8104 or if $(D dir == Direction.bwd), so any $(LREF Interval) functions which are 8105 called on it which care about whether `begin` or `end` are included or 8106 excluded will treat `begin` as included and `end` as excluded. 8107 +/ 8108 struct IntervalRange(TP, Direction dir) 8109 if (isTimePoint!TP && dir != Direction.both) 8110 { 8111 public: 8112 8113 /++ 8114 Params: 8115 rhs = The `IntervalRange` to assign to this one. 8116 +/ 8117 ref IntervalRange opAssign(ref IntervalRange rhs) pure nothrow 8118 { 8119 _interval = rhs._interval; 8120 _func = rhs._func; 8121 return this; 8122 } 8123 8124 8125 /++ Ditto +/ 8126 ref IntervalRange opAssign(IntervalRange rhs) pure nothrow 8127 { 8128 return this = rhs; 8129 } 8130 8131 8132 /++ 8133 Whether this `IntervalRange` is empty. 8134 +/ 8135 @property bool empty() const pure nothrow 8136 { 8137 return _interval.empty; 8138 } 8139 8140 8141 /++ 8142 The first time point in the range. 8143 8144 Throws: 8145 $(REF DateTimeException,std,datetime,date) if the range is empty. 8146 +/ 8147 @property TP front() const pure 8148 { 8149 _enforceNotEmpty(); 8150 8151 static if (dir == Direction.fwd) 8152 return _interval.begin; 8153 else 8154 return _interval.end; 8155 } 8156 8157 8158 /++ 8159 Pops `front` from the range, using `func` to generate the next 8160 time point in the range. If the generated time point is beyond the edge 8161 of the range, then `front` is set to that edge, and the range is then 8162 empty. So, if iterating forwards, and the generated time point is 8163 greater than the interval's `end`, then `front` is set to 8164 `end`. If iterating backwards, and the generated time point is less 8165 than the interval's `begin`, then `front` is set to `begin`. 8166 8167 Throws: 8168 $(REF DateTimeException,std,datetime,date) if the range is empty 8169 or if the generated time point is in the wrong direction (i.e. if 8170 iterating forward and the generated time point is before `front`, 8171 or if iterating backwards and the generated time point is after 8172 `front`). 8173 +/ 8174 void popFront() 8175 { 8176 _enforceNotEmpty(); 8177 8178 static if (dir == Direction.fwd) 8179 { 8180 auto begin = _func(_interval.begin); 8181 8182 if (begin > _interval.end) 8183 begin = _interval.end; 8184 8185 _enforceCorrectDirection(begin); 8186 8187 _interval.begin = begin; 8188 } 8189 else 8190 { 8191 auto end = _func(_interval.end); 8192 8193 if (end < _interval.begin) 8194 end = _interval.begin; 8195 8196 _enforceCorrectDirection(end); 8197 8198 _interval.end = end; 8199 } 8200 } 8201 8202 8203 /++ 8204 Returns a copy of `this`. 8205 +/ 8206 @property IntervalRange save() pure nothrow 8207 { 8208 return this; 8209 } 8210 8211 8212 /++ 8213 The interval that this `IntervalRange` currently covers. 8214 +/ 8215 @property Interval!TP interval() const pure nothrow 8216 { 8217 return cast(Interval!TP)_interval; 8218 } 8219 8220 8221 /++ 8222 The function used to generate the next time point in the range. 8223 +/ 8224 TP delegate(scope const TP) func() pure nothrow @property 8225 { 8226 return _func; 8227 } 8228 8229 8230 /++ 8231 The `Direction` that this range iterates in. 8232 +/ 8233 @property Direction direction() const pure nothrow 8234 { 8235 return dir; 8236 } 8237 8238 8239 private: 8240 8241 /+ 8242 Params: 8243 interval = The interval that this range covers. 8244 func = The function used to generate the time points which are 8245 iterated over. 8246 +/ 8247 this(const Interval!TP interval, TP delegate(scope const TP) func) pure nothrow @safe 8248 { 8249 _func = func; 8250 _interval = interval; 8251 } 8252 8253 8254 /+ 8255 Throws: 8256 $(REF DateTimeException,std,datetime,date) if this interval is 8257 empty. 8258 +/ 8259 void _enforceNotEmpty(size_t line = __LINE__) const pure 8260 { 8261 if (empty) 8262 throw new DateTimeException("Invalid operation for an empty IntervalRange.", __FILE__, line); 8263 } 8264 8265 8266 /+ 8267 Throws: 8268 $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is 8269 in the wrong direction. 8270 +/ 8271 void _enforceCorrectDirection(scope const TP newTP, size_t line = __LINE__) const 8272 { 8273 import std.format : format; 8274 8275 static if (dir == Direction.fwd) 8276 { 8277 enforce(newTP > _interval._begin, 8278 new DateTimeException(format("Generated time point is before previous begin: prev [%s] new [%s]", 8279 interval._begin, 8280 newTP), 8281 __FILE__, 8282 line)); 8283 } 8284 else 8285 { 8286 enforce(newTP < _interval._end, 8287 new DateTimeException(format("Generated time point is after previous end: prev [%s] new [%s]", 8288 interval._end, 8289 newTP), 8290 __FILE__, 8291 line)); 8292 } 8293 } 8294 8295 8296 Interval!TP _interval; 8297 TP delegate(scope const TP) _func; 8298 } 8299 8300 //Test that IntervalRange satisfies the range predicates that it's supposed to satisfy. 8301 @safe unittest 8302 { 8303 import std.datetime.date; 8304 import std.datetime.systime; 8305 import std.range.primitives; 8306 8307 static assert(isInputRange!(IntervalRange!(Date, Direction.fwd))); 8308 static assert(isForwardRange!(IntervalRange!(Date, Direction.fwd))); 8309 8310 // Commented out due to bug https://issues.dlang.org/show_bug.cgi?id=4895 8311 // static assert(!isOutputRange!(IntervalRange!(Date, Direction.fwd), Date)); 8312 8313 static assert(!isBidirectionalRange!(IntervalRange!(Date, Direction.fwd))); 8314 static assert(!isRandomAccessRange!(IntervalRange!(Date, Direction.fwd))); 8315 static assert(!hasSwappableElements!(IntervalRange!(Date, Direction.fwd))); 8316 static assert(!hasAssignableElements!(IntervalRange!(Date, Direction.fwd))); 8317 static assert(!hasLength!(IntervalRange!(Date, Direction.fwd))); 8318 static assert(!isInfinite!(IntervalRange!(Date, Direction.fwd))); 8319 static assert(!hasSlicing!(IntervalRange!(Date, Direction.fwd))); 8320 8321 static assert(is(ElementType!(IntervalRange!(Date, Direction.fwd)) == Date)); 8322 static assert(is(ElementType!(IntervalRange!(TimeOfDay, Direction.fwd)) == TimeOfDay)); 8323 static assert(is(ElementType!(IntervalRange!(DateTime, Direction.fwd)) == DateTime)); 8324 static assert(is(ElementType!(IntervalRange!(SysTime, Direction.fwd)) == SysTime)); 8325 } 8326 8327 //Test construction of IntervalRange. 8328 @safe unittest 8329 { 8330 import std.datetime.date; 8331 import std.datetime.systime; 8332 8333 { 8334 Date dateFunc(scope const Date date) { return date; } 8335 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8336 auto ir = IntervalRange!(Date, Direction.fwd)(interval, &dateFunc); 8337 } 8338 8339 { 8340 TimeOfDay todFunc(scope const TimeOfDay tod) { return tod; } 8341 auto interval = Interval!TimeOfDay(TimeOfDay(12, 1, 7), TimeOfDay(14, 0, 0)); 8342 auto ir = IntervalRange!(TimeOfDay, Direction.fwd)(interval, &todFunc); 8343 } 8344 8345 { 8346 DateTime dtFunc(scope const DateTime dt) { return dt; } 8347 auto interval = Interval!DateTime(DateTime(2010, 7, 4, 12, 1, 7), DateTime(2012, 1, 7, 14, 0, 0)); 8348 auto ir = IntervalRange!(DateTime, Direction.fwd)(interval, &dtFunc); 8349 } 8350 8351 { 8352 SysTime stFunc(scope const SysTime st) { return SysTime.init; } 8353 auto interval = Interval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)), 8354 SysTime(DateTime(2012, 1, 7, 14, 0, 0))); 8355 auto ir = IntervalRange!(SysTime, Direction.fwd)(interval, &stFunc); 8356 } 8357 } 8358 8359 //Test IntervalRange's empty(). 8360 @system unittest 8361 { 8362 import std.datetime.date; 8363 8364 //fwd 8365 { 8366 auto range = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 8367 8368 assert(!range.empty); 8369 range.popFront(); 8370 assert(range.empty); 8371 8372 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 8373 assert(!cRange.empty); 8374 8375 //Apparently, creating an immutable IntervalRange!Date doesn't work, so we can't test if 8376 //empty works with it. However, since an immutable range is pretty useless, it's no great loss. 8377 } 8378 8379 //bwd 8380 { 8381 auto range = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)).bwdRange( 8382 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 8383 8384 assert(!range.empty); 8385 range.popFront(); 8386 assert(range.empty); 8387 8388 const cRange = Interval!Date( Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( 8389 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 8390 assert(!cRange.empty); 8391 8392 //Apparently, creating an immutable IntervalRange!Date doesn't work, so we can't test if 8393 //empty works with it. However, since an immutable range is pretty useless, it's no great loss. 8394 } 8395 } 8396 8397 //Test IntervalRange's front. 8398 @system unittest 8399 { 8400 import std.datetime.date; 8401 8402 //fwd 8403 { 8404 auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).fwdRange( 8405 everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); 8406 assertThrown!DateTimeException( 8407 (scope const IntervalRange!(Date, Direction.fwd) range){range.front;}(emptyRange)); 8408 8409 auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed)); 8410 assert(range.front == Date(2010, 7, 4)); 8411 8412 auto poppedRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange( 8413 everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); 8414 assert(poppedRange.front == Date(2010, 7, 7)); 8415 8416 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 8417 assert(cRange.front != Date.init); 8418 } 8419 8420 //bwd 8421 { 8422 auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).bwdRange( 8423 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); 8424 assertThrown!DateTimeException( 8425 (scope const IntervalRange!(Date, Direction.bwd) range){range.front;}(emptyRange)); 8426 8427 auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( 8428 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed)); 8429 assert(range.front == Date(2012, 1, 7)); 8430 8431 auto poppedRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( 8432 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); 8433 assert(poppedRange.front == Date(2012, 1, 4)); 8434 8435 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( 8436 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 8437 assert(cRange.front != Date.init); 8438 } 8439 } 8440 8441 //Test IntervalRange's popFront(). 8442 @system unittest 8443 { 8444 import std.datetime.date; 8445 import std.range.primitives : walkLength; 8446 8447 //fwd 8448 { 8449 auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).fwdRange( 8450 everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); 8451 assertThrown!DateTimeException((IntervalRange!(Date, Direction.fwd) range){range.popFront();}(emptyRange)); 8452 8453 auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange( 8454 everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); 8455 auto expected = range.front; 8456 8457 foreach (date; range) 8458 { 8459 assert(date == expected); 8460 expected += dur!"days"(7); 8461 } 8462 8463 assert(walkLength(range) == 79); 8464 8465 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 8466 assert(cRange.front != Date.init); 8467 } 8468 8469 //bwd 8470 { 8471 auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).bwdRange( 8472 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); 8473 assertThrown!DateTimeException((IntervalRange!(Date, Direction.bwd) range){range.popFront();}(emptyRange)); 8474 8475 auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( 8476 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); 8477 auto expected = range.front; 8478 8479 foreach (date; range) 8480 { 8481 assert(date == expected); 8482 expected += dur!"days"(-7); 8483 } 8484 8485 assert(walkLength(range) == 79); 8486 8487 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( 8488 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 8489 static assert(!__traits(compiles, cRange.popFront())); 8490 } 8491 } 8492 8493 //Test IntervalRange's save. 8494 @system unittest 8495 { 8496 import std.datetime.date; 8497 8498 //fwd 8499 { 8500 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8501 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8502 auto range = interval.fwdRange(func); 8503 8504 assert(range.save == range); 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.save == range); 8514 } 8515 } 8516 8517 //Test IntervalRange's interval. 8518 @system unittest 8519 { 8520 import std.datetime.date; 8521 8522 //fwd 8523 { 8524 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8525 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8526 auto range = interval.fwdRange(func); 8527 8528 assert(range.interval == interval); 8529 8530 const cRange = range; 8531 assert(!cRange.interval.empty); 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.interval == interval); 8541 8542 const cRange = range; 8543 assert(!cRange.interval.empty); 8544 } 8545 } 8546 8547 //Test IntervalRange's func. 8548 @system unittest 8549 { 8550 import std.datetime.date; 8551 8552 //fwd 8553 { 8554 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8555 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8556 auto range = interval.fwdRange(func); 8557 8558 assert(range.func == func); 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.func == func); 8568 } 8569 } 8570 8571 //Test IntervalRange's direction. 8572 @system unittest 8573 { 8574 import std.datetime.date; 8575 8576 //fwd 8577 { 8578 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8579 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8580 auto range = interval.fwdRange(func); 8581 8582 assert(range.direction == Direction.fwd); 8583 8584 const cRange = range; 8585 assert(cRange.direction == Direction.fwd); 8586 } 8587 8588 //bwd 8589 { 8590 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); 8591 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); 8592 auto range = interval.bwdRange(func); 8593 8594 assert(range.direction == Direction.bwd); 8595 8596 const cRange = range; 8597 assert(cRange.direction == Direction.bwd); 8598 } 8599 } 8600 8601 8602 /++ 8603 A range over a `PosInfInterval`. It is an infinite range. 8604 8605 `PosInfIntervalRange` is only ever constructed by `PosInfInterval`. 8606 However, when it is constructed, it is given a function, `func`, which 8607 is used to generate the time points which are iterated over. `func` 8608 takes a time point and returns a time point of the same type. For 8609 instance, to iterate 8610 over all of the days in the interval `PosInfInterval!Date`, pass a 8611 function to `PosInfInterval`'s `fwdRange` where that function took a 8612 $(REF Date,std,datetime,date) and returned a $(REF Date,std,datetime,date) 8613 which was one day later. That function would then be used by 8614 `PosInfIntervalRange`'s `popFront` to iterate over the 8615 $(REF Date,std,datetime,date)s in the interval - though obviously, since the 8616 range is infinite, use a function such as `std.range.take` with it rather 8617 than iterating over $(I all) of the dates. 8618 8619 As the interval goes to positive infinity, the range is always iterated over 8620 forwards, never backwards. `func` must generate a time point going in 8621 the proper direction of iteration, or a 8622 $(REF DateTimeException,std,datetime,date) will be thrown. So, the time 8623 points that `func` generates must be later in time than the one passed to 8624 it. If it's either identical or earlier in time, then a 8625 $(REF DateTimeException,std,datetime,date) will be thrown. 8626 +/ 8627 struct PosInfIntervalRange(TP) 8628 if (isTimePoint!TP) 8629 { 8630 public: 8631 8632 /++ 8633 Params: 8634 rhs = The `PosInfIntervalRange` to assign to this one. 8635 +/ 8636 ref PosInfIntervalRange opAssign(ref PosInfIntervalRange rhs) pure nothrow 8637 { 8638 _interval = rhs._interval; 8639 _func = rhs._func; 8640 return this; 8641 } 8642 8643 8644 /++ Ditto +/ 8645 ref PosInfIntervalRange opAssign(PosInfIntervalRange rhs) pure nothrow 8646 { 8647 return this = rhs; 8648 } 8649 8650 8651 /++ 8652 This is an infinite range, so it is never empty. 8653 +/ 8654 enum bool empty = false; 8655 8656 8657 /++ 8658 The first time point in the range. 8659 +/ 8660 @property TP front() const pure nothrow 8661 { 8662 return _interval.begin; 8663 } 8664 8665 8666 /++ 8667 Pops `front` from the range, using `func` to generate the next 8668 time point in the range. 8669 8670 Throws: 8671 $(REF DateTimeException,std,datetime,date) if the generated time 8672 point is less than `front`. 8673 +/ 8674 void popFront() 8675 { 8676 auto begin = _func(_interval.begin); 8677 _enforceCorrectDirection(begin); 8678 _interval.begin = begin; 8679 } 8680 8681 8682 /++ 8683 Returns a copy of `this`. 8684 +/ 8685 @property PosInfIntervalRange save() pure nothrow 8686 { 8687 return this; 8688 } 8689 8690 8691 /++ 8692 The interval that this range currently covers. 8693 +/ 8694 @property PosInfInterval!TP interval() const pure nothrow 8695 { 8696 return cast(PosInfInterval!TP)_interval; 8697 } 8698 8699 8700 /++ 8701 The function used to generate the next time point in the range. 8702 +/ 8703 TP delegate(scope const TP) func() pure nothrow @property 8704 { 8705 return _func; 8706 } 8707 8708 8709 private: 8710 8711 /+ 8712 Params: 8713 interval = The interval that this range covers. 8714 func = The function used to generate the time points which are 8715 iterated over. 8716 +/ 8717 this(const PosInfInterval!TP interval, TP delegate(scope const TP) func) pure nothrow 8718 { 8719 _func = func; 8720 _interval = interval; 8721 } 8722 8723 8724 /+ 8725 Throws: 8726 $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is 8727 in the wrong direction. 8728 +/ 8729 void _enforceCorrectDirection(scope const TP newTP, size_t line = __LINE__) const 8730 { 8731 import std.format : format; 8732 8733 enforce(newTP > _interval._begin, 8734 new DateTimeException(format("Generated time point is before previous begin: prev [%s] new [%s]", 8735 interval._begin, 8736 newTP), 8737 __FILE__, 8738 line)); 8739 } 8740 8741 8742 PosInfInterval!TP _interval; 8743 TP delegate(scope const TP) _func; 8744 } 8745 8746 //Test that PosInfIntervalRange satisfies the range predicates that it's supposed to satisfy. 8747 @safe unittest 8748 { 8749 import std.datetime.date; 8750 import std.datetime.systime; 8751 import std.range.primitives; 8752 8753 static assert(isInputRange!(PosInfIntervalRange!Date)); 8754 static assert(isForwardRange!(PosInfIntervalRange!Date)); 8755 static assert(isInfinite!(PosInfIntervalRange!Date)); 8756 8757 // Commented out due to bug https://issues.dlang.org/show_bug.cgi?id=4895 8758 // static assert(!isOutputRange!(PosInfIntervalRange!Date, Date)); 8759 static assert(!isBidirectionalRange!(PosInfIntervalRange!Date)); 8760 static assert(!isRandomAccessRange!(PosInfIntervalRange!Date)); 8761 static assert(!hasSwappableElements!(PosInfIntervalRange!Date)); 8762 static assert(!hasAssignableElements!(PosInfIntervalRange!Date)); 8763 static assert(!hasLength!(PosInfIntervalRange!Date)); 8764 static assert(!hasSlicing!(PosInfIntervalRange!Date)); 8765 8766 static assert(is(ElementType!(PosInfIntervalRange!Date) == Date)); 8767 static assert(is(ElementType!(PosInfIntervalRange!TimeOfDay) == TimeOfDay)); 8768 static assert(is(ElementType!(PosInfIntervalRange!DateTime) == DateTime)); 8769 static assert(is(ElementType!(PosInfIntervalRange!SysTime) == SysTime)); 8770 } 8771 8772 //Test construction of PosInfIntervalRange. 8773 @safe unittest 8774 { 8775 import std.datetime.date; 8776 import std.datetime.systime; 8777 8778 { 8779 Date dateFunc(scope const Date date) { return date; } 8780 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); 8781 auto ir = PosInfIntervalRange!Date(posInfInterval, &dateFunc); 8782 } 8783 8784 { 8785 TimeOfDay todFunc(scope const TimeOfDay tod) { return tod; } 8786 auto posInfInterval = PosInfInterval!TimeOfDay(TimeOfDay(12, 1, 7)); 8787 auto ir = PosInfIntervalRange!(TimeOfDay)(posInfInterval, &todFunc); 8788 } 8789 8790 { 8791 DateTime dtFunc(scope const DateTime dt) { return dt; } 8792 auto posInfInterval = PosInfInterval!DateTime(DateTime(2010, 7, 4, 12, 1, 7)); 8793 auto ir = PosInfIntervalRange!(DateTime)(posInfInterval, &dtFunc); 8794 } 8795 8796 { 8797 SysTime stFunc(scope const SysTime st) { return SysTime.init; } 8798 auto posInfInterval = PosInfInterval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7))); 8799 auto ir = PosInfIntervalRange!SysTime(posInfInterval, &stFunc); 8800 } 8801 } 8802 8803 //Test PosInfIntervalRange's front. 8804 @system unittest 8805 { 8806 import std.datetime.date; 8807 8808 auto range = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed)); 8809 assert(range.front == Date(2010, 7, 4)); 8810 8811 auto poppedRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); 8812 assert(poppedRange.front == Date(2010, 7, 7)); 8813 8814 const cRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 8815 assert(cRange.front != Date.init); 8816 } 8817 8818 //Test PosInfIntervalRange's popFront(). 8819 @system unittest 8820 { 8821 import std.datetime.date; 8822 import std.range : take; 8823 8824 auto range = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); 8825 auto expected = range.front; 8826 8827 foreach (date; take(range, 79)) 8828 { 8829 assert(date == expected); 8830 expected += dur!"days"(7); 8831 } 8832 8833 const cRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); 8834 static assert(!__traits(compiles, cRange.popFront())); 8835 } 8836 8837 //Test PosInfIntervalRange's save. 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.save == range); 8847 } 8848 8849 //Test PosInfIntervalRange's interval. 8850 @system unittest 8851 { 8852 import std.datetime.date; 8853 8854 auto interval = PosInfInterval!Date(Date(2010, 7, 4)); 8855 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8856 auto range = interval.fwdRange(func); 8857 8858 assert(range.interval == interval); 8859 8860 const cRange = range; 8861 assert(!cRange.interval.empty); 8862 } 8863 8864 //Test PosInfIntervalRange's func. 8865 @system unittest 8866 { 8867 import std.datetime.date; 8868 8869 auto interval = PosInfInterval!Date(Date(2010, 7, 4)); 8870 auto func = everyDayOfWeek!Date(DayOfWeek.fri); 8871 auto range = interval.fwdRange(func); 8872 8873 assert(range.func == func); 8874 } 8875 8876 8877 /++ 8878 A range over a `NegInfInterval`. It is an infinite range. 8879 8880 `NegInfIntervalRange` is only ever constructed by `NegInfInterval`. 8881 However, when it is constructed, it is given a function, `func`, which 8882 is used to generate the time points which are iterated over. `func` 8883 takes a time point and returns a time point of the same type. For 8884 instance, to iterate over all of the days in the interval 8885 `NegInfInterval!Date`, pass a function to `NegInfInterval`'s 8886 `bwdRange` where that function took a $(REF Date,std,datetime,date) and 8887 returned a $(REF Date,std,datetime,date) which was one day earlier. That 8888 function would then be used by `NegInfIntervalRange`'s `popFront` to 8889 iterate over the $(REF Date,std,datetime,date)s in the interval - though 8890 obviously, since the range is infinite, use a function such as 8891 `std.range.take` with it rather than iterating over $(I all) of the dates. 8892 8893 As the interval goes to negative infinity, the range is always iterated over 8894 backwards, never forwards. `func` must generate a time point going in 8895 the proper direction of iteration, or a 8896 $(REF DateTimeException,std,datetime,date) will be thrown. So, the time 8897 points that `func` generates must be earlier in time than the one passed 8898 to it. If it's either identical or later in time, then a 8899 $(REF DateTimeException,std,datetime,date) will be thrown. 8900 8901 Also note that while normally the `end` of an interval is excluded from 8902 it, `NegInfIntervalRange` treats it as if it were included. This allows 8903 for the same behavior as with `PosInfIntervalRange`. This works 8904 because none of `NegInfInterval`'s functions which care about whether 8905 `end` is included or excluded are ever called by 8906 `NegInfIntervalRange`. `interval` returns a normal interval, so any 8907 `NegInfInterval` functions which are called on it which care about 8908 whether `end` is included or excluded will treat `end` as excluded. 8909 +/ 8910 struct NegInfIntervalRange(TP) 8911 if (isTimePoint!TP) 8912 { 8913 public: 8914 8915 /++ 8916 Params: 8917 rhs = The `NegInfIntervalRange` to assign to this one. 8918 +/ 8919 ref NegInfIntervalRange opAssign(ref NegInfIntervalRange rhs) pure nothrow 8920 { 8921 _interval = rhs._interval; 8922 _func = rhs._func; 8923 8924 return this; 8925 } 8926 8927 8928 /++ Ditto +/ 8929 ref NegInfIntervalRange opAssign(NegInfIntervalRange rhs) pure nothrow 8930 { 8931 return this = rhs; 8932 } 8933 8934 8935 /++ 8936 This is an infinite range, so it is never empty. 8937 +/ 8938 enum bool empty = false; 8939 8940 8941 /++ 8942 The first time point in the range. 8943 +/ 8944 @property TP front() const pure nothrow 8945 { 8946 return _interval.end; 8947 } 8948 8949 8950 /++ 8951 Pops `front` from the range, using `func` to generate the next 8952 time point in the range. 8953 8954 Throws: 8955 $(REF DateTimeException,std,datetime,date) if the generated time 8956 point is greater than `front`. 8957 +/ 8958 void popFront() 8959 { 8960 auto end = _func(_interval.end); 8961 _enforceCorrectDirection(end); 8962 _interval.end = end; 8963 } 8964 8965 8966 /++ 8967 Returns a copy of `this`. 8968 +/ 8969 @property NegInfIntervalRange save() pure nothrow 8970 { 8971 return this; 8972 } 8973 8974 8975 /++ 8976 The interval that this range currently covers. 8977 +/ 8978 @property NegInfInterval!TP interval() const pure nothrow 8979 { 8980 return cast(NegInfInterval!TP)_interval; 8981 } 8982 8983 8984 /++ 8985 The function used to generate the next time point in the range. 8986 +/ 8987 TP delegate(scope const TP) func() pure nothrow @property 8988 { 8989 return _func; 8990 } 8991 8992 8993 private: 8994 8995 /+ 8996 Params: 8997 interval = The interval that this range covers. 8998 func = The function used to generate the time points which are 8999 iterated over. 9000 +/ 9001 this(const NegInfInterval!TP interval, TP delegate(scope const TP) func) pure nothrow 9002 { 9003 _func = func; 9004 _interval = interval; 9005 } 9006 9007 9008 /+ 9009 Throws: 9010 $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is 9011 in the wrong direction. 9012 +/ 9013 void _enforceCorrectDirection(scope const TP newTP, size_t line = __LINE__) const 9014 { 9015 import std.format : format; 9016 9017 enforce(newTP < _interval._end, 9018 new DateTimeException(format("Generated time point is before previous end: prev [%s] new [%s]", 9019 interval._end, 9020 newTP), 9021 __FILE__, 9022 line)); 9023 } 9024 9025 9026 NegInfInterval!TP _interval; 9027 TP delegate(scope const TP) _func; 9028 } 9029 9030 //Test that NegInfIntervalRange satisfies the range predicates that it's supposed to satisfy. 9031 @safe unittest 9032 { 9033 import std.datetime.date; 9034 import std.range.primitives; 9035 9036 static assert(isInputRange!(NegInfIntervalRange!Date)); 9037 static assert(isForwardRange!(NegInfIntervalRange!Date)); 9038 static assert(isInfinite!(NegInfIntervalRange!Date)); 9039 9040 // Commented out due to bug https://issues.dlang.org/show_bug.cgi?id=4895 9041 // static assert(!isOutputRange!(NegInfIntervalRange!Date, Date)); 9042 static assert(!isBidirectionalRange!(NegInfIntervalRange!Date)); 9043 static assert(!isRandomAccessRange!(NegInfIntervalRange!Date)); 9044 static assert(!hasSwappableElements!(NegInfIntervalRange!Date)); 9045 static assert(!hasAssignableElements!(NegInfIntervalRange!Date)); 9046 static assert(!hasLength!(NegInfIntervalRange!Date)); 9047 static assert(!hasSlicing!(NegInfIntervalRange!Date)); 9048 9049 static assert(is(ElementType!(NegInfIntervalRange!Date) == Date)); 9050 static assert(is(ElementType!(NegInfIntervalRange!TimeOfDay) == TimeOfDay)); 9051 static assert(is(ElementType!(NegInfIntervalRange!DateTime) == DateTime)); 9052 } 9053 9054 //Test construction of NegInfIntervalRange. 9055 @safe unittest 9056 { 9057 import std.datetime.date; 9058 import std.datetime.systime; 9059 9060 { 9061 Date dateFunc(scope const Date date) { return date; } 9062 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); 9063 auto ir = NegInfIntervalRange!Date(negInfInterval, &dateFunc); 9064 } 9065 9066 { 9067 TimeOfDay todFunc(scope const TimeOfDay tod) { return tod; } 9068 auto negInfInterval = NegInfInterval!TimeOfDay(TimeOfDay(14, 0, 0)); 9069 auto ir = NegInfIntervalRange!(TimeOfDay)(negInfInterval, &todFunc); 9070 } 9071 9072 { 9073 DateTime dtFunc(scope const DateTime dt) { return dt; } 9074 auto negInfInterval = NegInfInterval!DateTime(DateTime(2012, 1, 7, 14, 0, 0)); 9075 auto ir = NegInfIntervalRange!(DateTime)(negInfInterval, &dtFunc); 9076 } 9077 9078 { 9079 SysTime stFunc(scope const SysTime st) { return SysTime.init; } 9080 auto negInfInterval = NegInfInterval!SysTime(SysTime(DateTime(2012, 1, 7, 14, 0, 0))); 9081 auto ir = NegInfIntervalRange!(SysTime)(negInfInterval, &stFunc); 9082 } 9083 } 9084 9085 //Test NegInfIntervalRange's front. 9086 @system unittest 9087 { 9088 import std.datetime.date; 9089 9090 auto range = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed)); 9091 assert(range.front == Date(2012, 1, 7)); 9092 9093 auto poppedRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange( 9094 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); 9095 assert(poppedRange.front == Date(2012, 1, 4)); 9096 9097 const cRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 9098 assert(cRange.front != Date.init); 9099 } 9100 9101 //Test NegInfIntervalRange's popFront(). 9102 @system unittest 9103 { 9104 import std.datetime.date; 9105 import std.range : take; 9106 9107 auto range = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange( 9108 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); 9109 auto expected = range.front; 9110 9111 foreach (date; take(range, 79)) 9112 { 9113 assert(date == expected); 9114 expected += dur!"days"(-7); 9115 } 9116 9117 const cRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); 9118 static assert(!__traits(compiles, cRange.popFront())); 9119 } 9120 9121 //Test NegInfIntervalRange's save. 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.save == range); 9131 } 9132 9133 //Test NegInfIntervalRange's interval. 9134 @system unittest 9135 { 9136 import std.datetime.date; 9137 9138 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 9139 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); 9140 auto range = interval.bwdRange(func); 9141 9142 assert(range.interval == interval); 9143 9144 const cRange = range; 9145 assert(!cRange.interval.empty); 9146 } 9147 9148 //Test NegInfIntervalRange's func. 9149 @system unittest 9150 { 9151 import std.datetime.date; 9152 9153 auto interval = NegInfInterval!Date(Date(2012, 1, 7)); 9154 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); 9155 auto range = interval.bwdRange(func); 9156 9157 assert(range.func == func); 9158 }