1 // Written in the D programming language
2
3 /++
4 License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
5 Authors: Jonathan M Davis
6 Source: $(PHOBOSSRC std/datetime/_interval.d)
7 +/
8 module std.datetime.interval;
9
10 import core.time : Duration, dur;
11 import std.datetime.date : AllowDayOverflow, DateTimeException, daysToDayOfWeek,
12 DayOfWeek, isTimePoint, Month;
13 import std.exception : enforce;
14 import std.traits : isIntegral, Unqual;
15 import std.typecons : Flag;
16
17 version (unittest) import std.exception : assertThrown;
18
19
20 /++
21 Indicates a direction in time. One example of its use is $(LREF Interval)'s
22 $(LREF expand) function which uses it to indicate whether the interval
23 should be expanded backwards (into the past), forwards (into the future), or
24 both.
25 +/
26 enum Direction
27 {
28 /// Backward.
29 bwd,
30
31 /// Forward.
32 fwd,
33
34 /// Both backward and forward.
35 both
36 }
37
38
39 /++
40 Used to indicate whether $(D popFront) should be called immediately upon
41 creating a range. The idea is that for some functions used to generate a
42 range for an interval, $(D front) is not necessarily a time point which
43 would ever be generated by the range (e.g. if the range were every Sunday
44 within an interval, but the interval started on a Monday), so there needs
45 to be a way to deal with that. To get the first time point in the range to
46 match what the function generates, then use $(D PopFirst.yes) to indicate
47 that the range should have $(D popFront) called on it before the range is
48 returned so that $(D front) is a time point which the function would
49 generate. To let the first time point not match the generator function,
50 use $(D PopFront.no).
51
52 For instance, if the function used to generate a range of time points
53 generated successive Easters (i.e. you're iterating over all of the Easters
54 within the interval), the initial date probably isn't an Easter. Using
55 $(D PopFirst.yes) would tell the function which returned the range that
56 $(D popFront) was to be called so that front would then be an Easter - the
57 next one generated by the function (which when iterating forward would be
58 the Easter following the original $(D front), while when iterating backward,
59 it would be the Easter prior to the original $(D front)). If
60 $(D PopFirst.no) were used, then $(D front) would remain the original time
61 point and it would not necessarily be a time point which would be generated
62 by the range-generating function (which in many cases is exactly what is
63 desired - e.g. if iterating over every day starting at the beginning of the
64 interval).
65
66 If set to $(D PopFirst.no), then popFront is not called before returning
67 the range.
68
69 Otherwise, if set to $(D PopFirst.yes), then popFront is called before
70 returning the range.
71 +/
72 alias PopFirst = Flag!"popFirst";
73
74
75 /++
76 Represents an interval of time.
77
78 An $(D Interval) has a starting point and an end point. The interval of time
79 is therefore the time starting at the starting point up to, but not
80 including, the end point. e.g.
81
82 $(BOOKTABLE,
83 $(TR $(TD [January 5th, 2010 - March 10th, 2010$(RPAREN)))
84 $(TR $(TD [05:00:30 - 12:00:00$(RPAREN)))
85 $(TR $(TD [1982-01-04T08:59:00 - 2010-07-04T12:00:00$(RPAREN)))
86 )
87
88 A range can be obtained from an $(D Interval), allowing iteration over
89 that interval, with the exact time points which are iterated over depending
90 on the function which generates the range.
91 +/
Interval(TP)92 struct Interval(TP)
93 {
94 public:
95
96 /++
97 Params:
98 begin = The time point which begins the interval.
99 end = The time point which ends (but is not included in) the
100 interval.
101
102 Throws:
103 $(REF DateTimeException,std,datetime,date) if $(D_PARAM end) is
104 before $(D_PARAM begin).
105
106 Example:
107 --------------------
108 Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
109 --------------------
110 +/
111 this(U)(in TP begin, in U end) pure
112 if (is(Unqual!TP == Unqual!U))
113 {
114 if (!_valid(begin, end))
115 throw new DateTimeException("Arguments would result in an invalid Interval.");
116 _begin = cast(TP) begin;
117 _end = cast(TP) end;
118 }
119
120
121 /++
122 Params:
123 begin = The time point which begins the interval.
124 duration = The duration from the starting point to the end point.
125
126 Throws:
127 $(REF DateTimeException,std,datetime,date) if the resulting
128 $(D end) is before $(D begin).
129
130 Example:
131 --------------------
132 assert(Interval!Date(Date(1996, 1, 2), dur!"days"(3)) ==
133 Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5)));
134 --------------------
135 +/
136 this(D)(in TP begin, in D duration) pure
137 if (__traits(compiles, begin + duration))
138 {
139 _begin = cast(TP) begin;
140 _end = begin + duration;
141 if (!_valid(_begin, _end))
142 throw new DateTimeException("Arguments would result in an invalid Interval.");
143 }
144
145
146 /++
147 Params:
148 rhs = The $(LREF Interval) to assign to this one.
149 +/
150 ref Interval opAssign(const ref Interval rhs) pure nothrow
151 {
152 _begin = cast(TP) rhs._begin;
153 _end = cast(TP) rhs._end;
154 return this;
155 }
156
157
158 /++
159 Params:
160 rhs = The $(LREF Interval) to assign to this one.
161 +/
162 ref Interval opAssign(Interval rhs) pure nothrow
163 {
164 _begin = cast(TP) rhs._begin;
165 _end = cast(TP) rhs._end;
166 return this;
167 }
168
169
170 /++
171 The starting point of the interval. It is included in the interval.
172
173 Example:
174 --------------------
175 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin ==
176 Date(1996, 1, 2));
177 --------------------
178 +/
179 @property TP begin() const pure nothrow
180 {
181 return cast(TP) _begin;
182 }
183
184
185 /++
186 The starting point of the interval. It is included in the interval.
187
188 Params:
189 timePoint = The time point to set $(D begin) to.
190
191 Throws:
192 $(REF DateTimeException,std,datetime,date) if the resulting
193 interval would be invalid.
194 +/
195 @property void begin(TP timePoint) pure
196 {
197 if (!_valid(timePoint, _end))
198 throw new DateTimeException("Arguments would result in an invalid Interval.");
199 _begin = timePoint;
200 }
201
202
203 /++
204 The end point of the interval. It is excluded from the interval.
205
206 Example:
207 --------------------
208 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end ==
209 Date(2012, 3, 1));
210 --------------------
211 +/
212 @property TP end() const pure nothrow
213 {
214 return cast(TP) _end;
215 }
216
217
218 /++
219 The end point of the interval. It is excluded from the interval.
220
221 Params:
222 timePoint = The time point to set end to.
223
224 Throws:
225 $(REF DateTimeException,std,datetime,date) if the resulting
226 interval would be invalid.
227 +/
228 @property void end(TP timePoint) pure
229 {
230 if (!_valid(_begin, timePoint))
231 throw new DateTimeException("Arguments would result in an invalid Interval.");
232 _end = timePoint;
233 }
234
235
236 /++
237 Returns the duration between $(D begin) and $(D end).
238
239 Example:
240 --------------------
241 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length ==
242 dur!"days"(5903));
243 --------------------
244 +/
245 @property auto length() const pure nothrow
246 {
247 return _end - _begin;
248 }
249
250
251 /++
252 Whether the interval's length is 0, that is, whether $(D begin == end).
253
254 Example:
255 --------------------
256 assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty);
257 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty);
258 --------------------
259 +/
260 @property bool empty() const pure nothrow
261 {
262 return _begin == _end;
263 }
264
265
266 /++
267 Whether the given time point is within this interval.
268
269 Params:
270 timePoint = The time point to check for inclusion in this interval.
271
272 Throws:
273 $(REF DateTimeException,std,datetime,date) if this interval is
274 empty.
275
276 Example:
277 --------------------
278 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
279 Date(1994, 12, 24)));
280
281 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
282 Date(2000, 1, 5)));
283 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
284 Date(2012, 3, 1)));
285 --------------------
286 +/
287 bool contains(in TP timePoint) const pure
288 {
289 _enforceNotEmpty();
290 return timePoint >= _begin && timePoint < _end;
291 }
292
293
294 /++
295 Whether the given interval is completely within this interval.
296
297 Params:
298 interval = The interval to check for inclusion in this interval.
299
300 Throws:
301 $(REF DateTimeException,std,datetime,date) if either interval is
302 empty.
303
304 Example:
305 --------------------
306 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
307 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
308
309 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
310 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
311
312 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
313 Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));
314 --------------------
315 +/
316 bool contains(in Interval interval) const pure
317 {
318 _enforceNotEmpty();
319 interval._enforceNotEmpty();
320 return interval._begin >= _begin &&
321 interval._begin < _end &&
322 interval._end <= _end;
323 }
324
325
326 /++
327 Whether the given interval is completely within this interval.
328
329 Always returns false (unless this interval is empty), because an
330 interval going to positive infinity can never be contained in a finite
331 interval.
332
333 Params:
334 interval = The interval to check for inclusion in this interval.
335
336 Throws:
337 $(REF DateTimeException,std,datetime,date) if this interval is
338 empty.
339
340 Example:
341 --------------------
342 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
343 PosInfInterval!Date(Date(1999, 5, 4))));
344 --------------------
345 +/
346 bool contains(in PosInfInterval!TP interval) const pure
347 {
348 _enforceNotEmpty();
349 return false;
350 }
351
352
353 /++
354 Whether the given interval is completely within this interval.
355
356 Always returns false (unless this interval is empty), because an
357 interval beginning at negative infinity can never be contained in a
358 finite interval.
359
360 Params:
361 interval = The interval to check for inclusion in this interval.
362
363 Throws:
364 $(REF DateTimeException,std,datetime,date) if this interval is
365 empty.
366
367 Example:
368 --------------------
369 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
370 NegInfInterval!Date(Date(1996, 5, 4))));
371 --------------------
372 +/
373 bool contains(in NegInfInterval!TP interval) const pure
374 {
375 _enforceNotEmpty();
376 return false;
377 }
378
379
380 /++
381 Whether this interval is before the given time point.
382
383 Params:
384 timePoint = The time point to check whether this interval is before
385 it.
386
387 Throws:
388 $(REF DateTimeException,std,datetime,date) if this interval is
389 empty.
390
391 Example:
392 --------------------
393 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
394 Date(1994, 12, 24)));
395
396 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
397 Date(2000, 1, 5)));
398
399 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
400 Date(2012, 3, 1)));
401 --------------------
402 +/
403 bool isBefore(in TP timePoint) const pure
404 {
405 _enforceNotEmpty();
406 return _end <= timePoint;
407 }
408
409
410 /++
411 Whether this interval is before the given interval and does not
412 intersect with it.
413
414 Params:
415 interval = The interval to check for against this interval.
416
417 Throws:
418 $(REF DateTimeException,std,datetime,date) if either interval is
419 empty.
420
421 Example:
422 --------------------
423 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
424 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
425
426 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
427 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
428
429 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
430 Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1))));
431 --------------------
432 +/
433 bool isBefore(in Interval interval) const pure
434 {
435 _enforceNotEmpty();
436 interval._enforceNotEmpty();
437 return _end <= interval._begin;
438 }
439
440
441 /++
442 Whether this interval is before the given interval and does not
443 intersect with it.
444
445 Params:
446 interval = The interval to check for against this interval.
447
448 Throws:
449 $(REF DateTimeException,std,datetime,date) if this interval is
450 empty.
451
452 Example:
453 --------------------
454 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
455 PosInfInterval!Date(Date(1999, 5, 4))));
456
457 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
458 PosInfInterval!Date(Date(2013, 3, 7))));
459 --------------------
460 +/
461 bool isBefore(in PosInfInterval!TP interval) const pure
462 {
463 _enforceNotEmpty();
464 return _end <= interval._begin;
465 }
466
467
468 /++
469 Whether this interval is before the given interval and does not
470 intersect with it.
471
472 Always returns false (unless this interval is empty) because a finite
473 interval can never be before an interval beginning at negative infinity.
474
475 Params:
476 interval = The interval to check for against this interval.
477
478 Throws:
479 $(REF DateTimeException,std,datetime,date) if this interval is
480 empty.
481
482 Example:
483 --------------------
484 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
485 NegInfInterval!Date(Date(1996, 5, 4))));
486 --------------------
487 +/
488 bool isBefore(in NegInfInterval!TP interval) const pure
489 {
490 _enforceNotEmpty();
491 return false;
492 }
493
494
495 /++
496 Whether this interval is after the given time point.
497
498 Params:
499 timePoint = The time point to check whether this interval is after
500 it.
501
502 Throws:
503 $(REF DateTimeException,std,datetime,date) if this interval is
504 empty.
505
506 Example:
507 --------------------
508 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
509 Date(1994, 12, 24)));
510
511 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
512 Date(2000, 1, 5)));
513
514 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
515 Date(2012, 3, 1)));
516 --------------------
517 +/
518 bool isAfter(in TP timePoint) const pure
519 {
520 _enforceNotEmpty();
521 return timePoint < _begin;
522 }
523
524
525 /++
526 Whether this interval is after the given interval and does not intersect
527 it.
528
529 Params:
530 interval = The interval to check against this interval.
531
532 Throws:
533 $(REF DateTimeException,std,datetime,date) if either interval is
534 empty.
535
536 Example:
537 --------------------
538 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
539 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
540
541 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
542 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
543
544 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
545 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
546 --------------------
547 +/
548 bool isAfter(in Interval interval) const pure
549 {
550 _enforceNotEmpty();
551 interval._enforceNotEmpty();
552 return _begin >= interval._end;
553 }
554
555
556 /++
557 Whether this interval is after the given interval and does not intersect
558 it.
559
560 Always returns false (unless this interval is empty) because a finite
561 interval can never be after an interval going to positive infinity.
562
563 Params:
564 interval = The interval to check against this interval.
565
566 Throws:
567 $(REF DateTimeException,std,datetime,date) if this interval is
568 empty.
569
570 Example:
571 --------------------
572 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
573 PosInfInterval!Date(Date(1999, 5, 4))));
574 --------------------
575 +/
576 bool isAfter(in PosInfInterval!TP interval) const pure
577 {
578 _enforceNotEmpty();
579 return false;
580 }
581
582
583 /++
584 Whether this interval is after the given interval and does not intersect
585 it.
586
587 Params:
588 interval = The interval to check against this interval.
589
590 Throws:
591 $(REF DateTimeException,std,datetime,date) if this interval is
592 empty.
593
594 Example:
595 --------------------
596 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
597 NegInfInterval!Date(Date(1996, 1, 2))));
598 --------------------
599 +/
600 bool isAfter(in NegInfInterval!TP interval) const pure
601 {
602 _enforceNotEmpty();
603 return _begin >= interval._end;
604 }
605
606
607 /++
608 Whether the given interval overlaps this interval.
609
610 Params:
611 interval = The interval to check for intersection with this interval.
612
613 Throws:
614 $(REF DateTimeException,std,datetime,date) if either interval is
615 empty.
616
617 Example:
618 --------------------
619 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
620 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
621
622 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
623 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
624
625 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
626 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
627 --------------------
628 +/
629 bool intersects(in Interval interval) const pure
630 {
631 _enforceNotEmpty();
632 interval._enforceNotEmpty();
633 return interval._begin < _end && interval._end > _begin;
634 }
635
636
637 /++
638 Whether the given interval overlaps this interval.
639
640 Params:
641 interval = The interval to check for intersection with this interval.
642
643 Throws:
644 $(REF DateTimeException,std,datetime,date) if this interval is
645 empty.
646
647 Example:
648 --------------------
649 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
650 PosInfInterval!Date(Date(1999, 5, 4))));
651
652 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
653 PosInfInterval!Date(Date(2012, 3, 1))));
654 --------------------
655 +/
656 bool intersects(in PosInfInterval!TP interval) const pure
657 {
658 _enforceNotEmpty();
659 return _end > interval._begin;
660 }
661
662
663 /++
664 Whether the given interval overlaps this interval.
665
666 Params:
667 interval = The interval to check for intersection with this interval.
668
669 Throws:
670 $(REF DateTimeException,std,datetime,date) if this interval is
671 empty.
672
673 Example:
674 --------------------
675 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
676 NegInfInterval!Date(Date(1996, 1, 2))));
677
678 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
679 NegInfInterval!Date(Date(2000, 1, 2))));
680 --------------------
681 +/
682 bool intersects(in NegInfInterval!TP interval) const pure
683 {
684 _enforceNotEmpty();
685 return _begin < interval._end;
686 }
687
688
689 /++
690 Returns the intersection of two intervals
691
692 Params:
693 interval = The interval to intersect with this interval.
694
695 Throws:
696 $(REF DateTimeException,std,datetime,date) if the two intervals do
697 not intersect or if either interval is empty.
698
699 Example:
700 --------------------
701 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
702 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
703 Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2)));
704
705 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
706 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==
707 Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17)));
708 --------------------
709 +/
710 Interval intersection(in Interval interval) const
711 {
712 import std.format : format;
713
714 enforce(this.intersects(interval),
715 new DateTimeException(format("%s and %s do not intersect.", this, interval)));
716
717 auto begin = _begin > interval._begin ? _begin : interval._begin;
718 auto end = _end < interval._end ? _end : interval._end;
719
720 return Interval(begin, end);
721 }
722
723
724 /++
725 Returns the intersection of two intervals
726
727 Params:
728 interval = The interval to intersect with this interval.
729
730 Throws:
731 $(REF DateTimeException,std,datetime,date) if the two intervals do
732 not intersect or if this interval is empty.
733
734 Example:
735 --------------------
736 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
737 PosInfInterval!Date(Date(1990, 7, 6))) ==
738 Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1)));
739
740 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
741 PosInfInterval!Date(Date(1999, 1, 12))) ==
742 Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));
743 --------------------
744 +/
745 Interval intersection(in PosInfInterval!TP interval) const
746 {
747 import std.format : format;
748
749 enforce(this.intersects(interval),
750 new DateTimeException(format("%s and %s do not intersect.", this, interval)));
751
752 return Interval(_begin > interval._begin ? _begin : interval._begin, _end);
753 }
754
755
756 /++
757 Returns the intersection of two intervals
758
759 Params:
760 interval = The interval to intersect with this interval.
761
762 Throws:
763 $(REF DateTimeException,std,datetime,date) if the two intervals do
764 not intersect or if this interval is empty.
765
766 Example:
767 --------------------
768 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
769 NegInfInterval!Date(Date(1999, 7, 6))) ==
770 Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6)));
771
772 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
773 NegInfInterval!Date(Date(2013, 1, 12))) ==
774 Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1)));
775 --------------------
776 +/
777 Interval intersection(in NegInfInterval!TP interval) const
778 {
779 import std.format : format;
780
781 enforce(this.intersects(interval),
782 new DateTimeException(format("%s and %s do not intersect.", this, interval)));
783
784 return Interval(_begin, _end < interval._end ? _end : interval._end);
785 }
786
787
788 /++
789 Whether the given interval is adjacent to this interval.
790
791 Params:
792 interval = The interval to check whether its adjecent to this
793 interval.
794
795 Throws:
796 $(REF DateTimeException,std,datetime,date) if either interval is
797 empty.
798
799 Example:
800 --------------------
801 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
802 Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2))));
803
804 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
805 Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17))));
806
807 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
808 Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1))));
809 --------------------
810 +/
811 bool isAdjacent(in Interval interval) const pure
812 {
813 _enforceNotEmpty();
814 interval._enforceNotEmpty();
815 return _begin == interval._end || _end == interval._begin;
816 }
817
818
819 /++
820 Whether the given interval is adjacent to this interval.
821
822 Params:
823 interval = The interval to check whether its adjecent to this
824 interval.
825
826 Throws:
827 $(REF DateTimeException,std,datetime,date) if this interval is
828 empty.
829
830 Example:
831 --------------------
832 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
833 PosInfInterval!Date(Date(1999, 5, 4))));
834
835 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
836 PosInfInterval!Date(Date(2012, 3, 1))));
837 --------------------
838 +/
839 bool isAdjacent(in PosInfInterval!TP interval) const pure
840 {
841 _enforceNotEmpty();
842 return _end == interval._begin;
843 }
844
845
846 /++
847 Whether the given interval is adjacent to this interval.
848
849 Params:
850 interval = The interval to check whether its adjecent to this
851 interval.
852
853 Throws:
854 $(REF DateTimeException,std,datetime,date) if this interval is
855 empty.
856
857 Example:
858 --------------------
859 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
860 NegInfInterval!Date(Date(1996, 1, 2))));
861
862 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
863 NegInfInterval!Date(Date(2000, 1, 2))));
864 --------------------
865 +/
866 bool isAdjacent(in NegInfInterval!TP interval) const pure
867 {
868 _enforceNotEmpty();
869 return _begin == interval._end;
870 }
871
872
873 /++
874 Returns the union of two intervals
875
876 Params:
877 interval = The interval to merge with this interval.
878
879 Throws:
880 $(REF DateTimeException,std,datetime,date) if the two intervals do
881 not intersect and are not adjacent or if either interval is empty.
882
883 Example:
884 --------------------
885 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(
886 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
887 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));
888
889 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(
890 Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) ==
891 Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7)));
892 --------------------
893 +/
894 Interval merge(in Interval interval) const
895 {
896 import std.format : format;
897
898 enforce(this.isAdjacent(interval) || this.intersects(interval),
899 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval)));
900
901 auto begin = _begin < interval._begin ? _begin : interval._begin;
902 auto end = _end > interval._end ? _end : interval._end;
903
904 return Interval(begin, end);
905 }
906
907
908 /++
909 Returns the union of two intervals
910
911 Params:
912 interval = The interval to merge with this interval.
913
914 Throws:
915 $(REF DateTimeException,std,datetime,date) if the two intervals do
916 not intersect and are not adjacent or if this interval is empty.
917
918 Example:
919 --------------------
920 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(
921 PosInfInterval!Date(Date(1990, 7, 6))) ==
922 PosInfInterval!Date(Date(1990, 7 , 6)));
923
924 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(
925 PosInfInterval!Date(Date(2012, 3, 1))) ==
926 PosInfInterval!Date(Date(1996, 1 , 2)));
927 --------------------
928 +/
929 PosInfInterval!TP merge(in PosInfInterval!TP interval) const
930 {
931 import std.format : format;
932
933 enforce(this.isAdjacent(interval) || this.intersects(interval),
934 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval)));
935
936 return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin);
937 }
938
939
940 /++
941 Returns the union of two intervals
942
943 Params:
944 interval = The interval to merge with this interval.
945
946 Throws:
947 $(REF DateTimeException,std,datetime,date) if the two intervals do
948 not intersect and are not adjacent or if this interval is empty.
949
950 Example:
951 --------------------
952 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(
953 NegInfInterval!Date(Date(1996, 1, 2))) ==
954 NegInfInterval!Date(Date(2012, 3 , 1)));
955
956 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(
957 NegInfInterval!Date(Date(2013, 1, 12))) ==
958 NegInfInterval!Date(Date(2013, 1 , 12)));
959 --------------------
960 +/
961 NegInfInterval!TP merge(in NegInfInterval!TP interval) const
962 {
963 import std.format : format;
964
965 enforce(this.isAdjacent(interval) || this.intersects(interval),
966 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval)));
967
968 return NegInfInterval!TP(_end > interval._end ? _end : interval._end);
969 }
970
971
972 /++
973 Returns an interval that covers from the earliest time point of two
974 intervals up to (but not including) the latest time point of two
975 intervals.
976
977 Params:
978 interval = The interval to create a span together with this interval.
979
980 Throws:
981 $(REF DateTimeException,std,datetime,date) if either interval is
982 empty.
983
984 Example:
985 --------------------
986 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(
987 Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) ==
988 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));
989
990 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(
991 Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) ==
992 Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7)));
993 --------------------
994 +/
995 Interval span(in Interval interval) const pure
996 {
997 _enforceNotEmpty();
998 interval._enforceNotEmpty();
999
1000 auto begin = _begin < interval._begin ? _begin : interval._begin;
1001 auto end = _end > interval._end ? _end : interval._end;
1002
1003 return Interval(begin, end);
1004 }
1005
1006
1007 /++
1008 Returns an interval that covers from the earliest time point of two
1009 intervals up to (but not including) the latest time point of two
1010 intervals.
1011
1012 Params:
1013 interval = The interval to create a span together with this interval.
1014
1015 Throws:
1016 $(REF DateTimeException,std,datetime,date) if this interval is
1017 empty.
1018
1019 Example:
1020 --------------------
1021 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(
1022 PosInfInterval!Date(Date(1990, 7, 6))) ==
1023 PosInfInterval!Date(Date(1990, 7 , 6)));
1024
1025 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(
1026 PosInfInterval!Date(Date(2050, 1, 1))) ==
1027 PosInfInterval!Date(Date(1996, 1 , 2)));
1028 --------------------
1029 +/
1030 PosInfInterval!TP span(in PosInfInterval!TP interval) const pure
1031 {
1032 _enforceNotEmpty();
1033 return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin);
1034 }
1035
1036
1037 /++
1038 Returns an interval that covers from the earliest time point of two
1039 intervals up to (but not including) the latest time point of two
1040 intervals.
1041
1042 Params:
1043 interval = The interval to create a span together with this interval.
1044
1045 Throws:
1046 $(REF DateTimeException,std,datetime,date) if this interval is
1047 empty.
1048
1049 Example:
1050 --------------------
1051 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(
1052 NegInfInterval!Date(Date(1602, 5, 21))) ==
1053 NegInfInterval!Date(Date(2012, 3 , 1)));
1054
1055 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(
1056 NegInfInterval!Date(Date(2013, 1, 12))) ==
1057 NegInfInterval!Date(Date(2013, 1 , 12)));
1058 --------------------
1059 +/
1060 NegInfInterval!TP span(in NegInfInterval!TP interval) const pure
1061 {
1062 _enforceNotEmpty();
1063 return NegInfInterval!TP(_end > interval._end ? _end : interval._end);
1064 }
1065
1066
1067 /++
1068 Shifts the interval forward or backwards in time by the given duration
1069 (a positive duration shifts the interval forward; a negative duration
1070 shifts it backward). Effectively, it does $(D begin += duration) and
1071 $(D end += duration).
1072
1073 Params:
1074 duration = The duration to shift the interval by.
1075
1076 Throws:
1077 $(REF DateTimeException,std,datetime,date) this interval is empty
1078 or if the resulting interval would be invalid.
1079
1080 Example:
1081 --------------------
1082 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5));
1083 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5));
1084
1085 interval1.shift(dur!"days"(50));
1086 assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25)));
1087
1088 interval2.shift(dur!"days"(-50));
1089 assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15)));
1090 --------------------
1091 +/
1092 void shift(D)(D duration) pure
1093 if (__traits(compiles, begin + duration))
1094 {
1095 _enforceNotEmpty();
1096
1097 auto begin = _begin + duration;
1098 auto end = _end + duration;
1099
1100 if (!_valid(begin, end))
1101 throw new DateTimeException("Argument would result in an invalid Interval.");
1102
1103 _begin = begin;
1104 _end = end;
1105 }
1106
1107
1108 static if (__traits(compiles, begin.add!"months"(1)) &&
1109 __traits(compiles, begin.add!"years"(1)))
1110 {
1111 /++
1112 Shifts the interval forward or backwards in time by the given number
1113 of years and/or months (a positive number of years and months shifts
1114 the interval forward; a negative number shifts it backward).
1115 It adds the years the given years and months to both begin and end.
1116 It effectively calls $(D add!"years"()) and then $(D add!"months"())
1117 on begin and end with the given number of years and months.
1118
1119 Params:
1120 years = The number of years to shift the interval by.
1121 months = The number of months to shift the interval by.
1122 allowOverflow = Whether the days should be allowed to overflow
1123 on $(D begin) and $(D end), causing their month
1124 to increment.
1125
1126 Throws:
1127 $(REF DateTimeException,std,datetime,date) if this interval is
1128 empty or if the resulting interval would be invalid.
1129
1130 Example:
1131 --------------------
1132 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
1133 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
1134
1135 interval1.shift(2);
1136 assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1)));
1137
1138 interval2.shift(-2);
1139 assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1)));
1140 --------------------
1141 +/
1142 void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
1143 if (isIntegral!T)
1144 {
1145 _enforceNotEmpty();
1146
1147 auto begin = _begin;
1148 auto end = _end;
1149
1150 begin.add!"years"(years, allowOverflow);
1151 begin.add!"months"(months, allowOverflow);
1152 end.add!"years"(years, allowOverflow);
1153 end.add!"months"(months, allowOverflow);
1154
1155 enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval."));
1156
1157 _begin = begin;
1158 _end = end;
1159 }
1160 }
1161
1162
1163 /++
1164 Expands the interval forwards and/or backwards in time. Effectively,
1165 it does $(D begin -= duration) and/or $(D end += duration). Whether
1166 it expands forwards and/or backwards in time is determined by
1167 $(D_PARAM dir).
1168
1169 Params:
1170 duration = The duration to expand the interval by.
1171 dir = The direction in time to expand the interval.
1172
1173 Throws:
1174 $(REF DateTimeException,std,datetime,date) this interval is empty
1175 or if the resulting interval would be invalid.
1176
1177 Example:
1178 --------------------
1179 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
1180 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
1181
1182 interval1.expand(2);
1183 assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1)));
1184
1185 interval2.expand(-2);
1186 assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1)));
1187 --------------------
1188 +/
1189 void expand(D)(D duration, Direction dir = Direction.both) pure
1190 if (__traits(compiles, begin + duration))
1191 {
1192 _enforceNotEmpty();
1193
1194 switch (dir)
1195 {
1196 case Direction.both:
1197 {
1198 auto begin = _begin - duration;
1199 auto end = _end + duration;
1200
1201 if (!_valid(begin, end))
1202 throw new DateTimeException("Argument would result in an invalid Interval.");
1203
1204 _begin = begin;
1205 _end = end;
1206
1207 return;
1208 }
1209 case Direction.fwd:
1210 {
1211 auto end = _end + duration;
1212
1213 if (!_valid(_begin, end))
1214 throw new DateTimeException("Argument would result in an invalid Interval.");
1215 _end = end;
1216
1217 return;
1218 }
1219 case Direction.bwd:
1220 {
1221 auto begin = _begin - duration;
1222
1223 if (!_valid(begin, _end))
1224 throw new DateTimeException("Argument would result in an invalid Interval.");
1225 _begin = begin;
1226
1227 return;
1228 }
1229 default:
1230 assert(0, "Invalid Direction.");
1231 }
1232 }
1233
1234 static if (__traits(compiles, begin.add!"months"(1)) &&
1235 __traits(compiles, begin.add!"years"(1)))
1236 {
1237 /++
1238 Expands the interval forwards and/or backwards in time. Effectively,
1239 it subtracts the given number of months/years from $(D begin) and
1240 adds them to $(D end). Whether it expands forwards and/or backwards
1241 in time is determined by $(D_PARAM dir).
1242
1243 Params:
1244 years = The number of years to expand the interval by.
1245 months = The number of months to expand the interval by.
1246 allowOverflow = Whether the days should be allowed to overflow
1247 on $(D begin) and $(D end), causing their month
1248 to increment.
1249 dir = The direction in time to expand the interval.
1250
1251 Throws:
1252 $(REF DateTimeException,std,datetime,date) if this interval is
1253 empty or if the resulting interval would be invalid.
1254
1255 Example:
1256 --------------------
1257 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
1258 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
1259
1260 interval1.expand(2);
1261 assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1)));
1262
1263 interval2.expand(-2);
1264 assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1)));
1265 --------------------
1266 +/
1267 void expand(T)(T years,
1268 T months = 0,
1269 AllowDayOverflow allowOverflow = AllowDayOverflow.yes,
1270 Direction dir = Direction.both)
1271 if (isIntegral!T)
1272 {
1273 _enforceNotEmpty();
1274
1275 switch (dir)
1276 {
1277 case Direction.both:
1278 {
1279 auto begin = _begin;
1280 auto end = _end;
1281
1282 begin.add!"years"(-years, allowOverflow);
1283 begin.add!"months"(-months, allowOverflow);
1284 end.add!"years"(years, allowOverflow);
1285 end.add!"months"(months, allowOverflow);
1286
1287 enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval."));
1288 _begin = begin;
1289 _end = end;
1290
1291 return;
1292 }
1293 case Direction.fwd:
1294 {
1295 auto end = _end;
1296
1297 end.add!"years"(years, allowOverflow);
1298 end.add!"months"(months, allowOverflow);
1299
1300 enforce(_valid(_begin, end),
1301 new DateTimeException("Argument would result in an invalid Interval."));
1302 _end = end;
1303
1304 return;
1305 }
1306 case Direction.bwd:
1307 {
1308 auto begin = _begin;
1309
1310 begin.add!"years"(-years, allowOverflow);
1311 begin.add!"months"(-months, allowOverflow);
1312
1313 enforce(_valid(begin, _end),
1314 new DateTimeException("Argument would result in an invalid Interval."));
1315 _begin = begin;
1316
1317 return;
1318 }
1319 default:
1320 assert(0, "Invalid Direction.");
1321 }
1322 }
1323 }
1324
1325
1326 /++
1327 Returns a range which iterates forward over the interval, starting
1328 at $(D begin), using $(D_PARAM func) to generate each successive time
1329 point.
1330
1331 The range's $(D front) is the interval's $(D begin). $(D_PARAM func) is
1332 used to generate the next $(D front) when $(D popFront) is called. If
1333 $(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called
1334 before the range is returned (so that $(D front) is a time point which
1335 $(D_PARAM func) would generate).
1336
1337 If $(D_PARAM func) ever generates a time point less than or equal to the
1338 current $(D front) of the range, then a
1339 $(REF DateTimeException,std,datetime,date) will be thrown. The range
1340 will be empty and iteration complete when $(D_PARAM func) generates a
1341 time point equal to or beyond the $(D end) of the interval.
1342
1343 There are helper functions in this module which generate common
1344 delegates to pass to $(D fwdRange). Their documentation starts with
1345 "Range-generating function," making them easily searchable.
1346
1347 Params:
1348 func = The function used to generate the time points of the
1349 range over the interval.
1350 popFirst = Whether $(D popFront) should be called on the range
1351 before returning it.
1352
1353 Throws:
1354 $(REF DateTimeException,std,datetime,date) if this interval is
1355 empty.
1356
1357 Warning:
1358 $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func)
1359 would be a function pointer to a pure function, but forcing
1360 $(D_PARAM func) to be pure is far too restrictive to be useful, and
1361 in order to have the ease of use of having functions which generate
1362 functions to pass to $(D fwdRange), $(D_PARAM func) must be a
1363 delegate.
1364
1365 If $(D_PARAM func) retains state which changes as it is called, then
1366 some algorithms will not work correctly, because the range's
1367 $(D save) will have failed to have really saved the range's state.
1368 To avoid such bugs, don't pass a delegate which is
1369 not logically pure to $(D fwdRange). If $(D_PARAM func) is given the
1370 same time point with two different calls, it must return the same
1371 result both times.
1372
1373 Of course, none of the functions in this module have this problem,
1374 so it's only relevant if when creating a custom delegate.
1375
1376 Example:
1377 --------------------
1378 auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9));
1379 auto func = delegate (in Date date) // For iterating over even-numbered days.
1380 {
1381 if ((date.day & 1) == 0)
1382 return date + dur!"days"(2);
1383
1384 return date + dur!"days"(1);
1385 };
1386 auto range = interval.fwdRange(func);
1387
1388 // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2).
1389 assert(range.front == Date(2010, 9, 1));
1390
1391 range.popFront();
1392 assert(range.front == Date(2010, 9, 2));
1393
1394 range.popFront();
1395 assert(range.front == Date(2010, 9, 4));
1396
1397 range.popFront();
1398 assert(range.front == Date(2010, 9, 6));
1399
1400 range.popFront();
1401 assert(range.front == Date(2010, 9, 8));
1402
1403 range.popFront();
1404 assert(range.empty);
1405 --------------------
1406 +/
1407 IntervalRange!(TP, Direction.fwd) fwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const
1408 {
1409 _enforceNotEmpty();
1410
1411 auto range = IntervalRange!(TP, Direction.fwd)(this, func);
1412
1413 if (popFirst == PopFirst.yes)
1414 range.popFront();
1415
1416 return range;
1417 }
1418
1419
1420 /++
1421 Returns a range which iterates backwards over the interval, starting
1422 at $(D end), using $(D_PARAM func) to generate each successive time
1423 point.
1424
1425 The range's $(D front) is the interval's $(D end). $(D_PARAM func) is
1426 used to generate the next $(D front) when $(D popFront) is called. If
1427 $(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called
1428 before the range is returned (so that $(D front) is a time point which
1429 $(D_PARAM func) would generate).
1430
1431 If $(D_PARAM func) ever generates a time point greater than or equal to
1432 the current $(D front) of the range, then a
1433 $(REF DateTimeException,std,datetime,date) will be thrown. The range
1434 will be empty and iteration complete when $(D_PARAM func) generates a
1435 time point equal to or less than the $(D begin) of the interval.
1436
1437 There are helper functions in this module which generate common
1438 delegates to pass to $(D bwdRange). Their documentation starts with
1439 "Range-generating function," making them easily searchable.
1440
1441 Params:
1442 func = The function used to generate the time points of the
1443 range over the interval.
1444 popFirst = Whether $(D popFront) should be called on the range
1445 before returning it.
1446
1447 Throws:
1448 $(REF DateTimeException,std,datetime,date) if this interval is
1449 empty.
1450
1451 Warning:
1452 $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func)
1453 would be a function pointer to a pure function, but forcing
1454 $(D_PARAM func) to be pure is far too restrictive to be useful, and
1455 in order to have the ease of use of having functions which generate
1456 functions to pass to $(D fwdRange), $(D_PARAM func) must be a
1457 delegate.
1458
1459 If $(D_PARAM func) retains state which changes as it is called, then
1460 some algorithms will not work correctly, because the range's
1461 $(D save) will have failed to have really saved the range's state.
1462 To avoid such bugs, don't pass a delegate which is
1463 not logically pure to $(D fwdRange). If $(D_PARAM func) is given the
1464 same time point with two different calls, it must return the same
1465 result both times.
1466
1467 Of course, none of the functions in this module have this problem,
1468 so it's only relevant for custom delegates.
1469
1470 Example:
1471 --------------------
1472 auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9));
1473 auto func = delegate (in Date date) // For iterating over even-numbered days.
1474 {
1475 if ((date.day & 1) == 0)
1476 return date - dur!"days"(2);
1477
1478 return date - dur!"days"(1);
1479 };
1480 auto range = interval.bwdRange(func);
1481
1482 // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8).
1483 assert(range.front == Date(2010, 9, 9));
1484
1485 range.popFront();
1486 assert(range.front == Date(2010, 9, 8));
1487
1488 range.popFront();
1489 assert(range.front == Date(2010, 9, 6));
1490
1491 range.popFront();
1492 assert(range.front == Date(2010, 9, 4));
1493
1494 range.popFront();
1495 assert(range.front == Date(2010, 9, 2));
1496
1497 range.popFront();
1498 assert(range.empty);
1499 --------------------
1500 +/
1501 IntervalRange!(TP, Direction.bwd) bwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const
1502 {
1503 _enforceNotEmpty();
1504
1505 auto range = IntervalRange!(TP, Direction.bwd)(this, func);
1506
1507 if (popFirst == PopFirst.yes)
1508 range.popFront();
1509
1510 return range;
1511 }
1512
1513
1514 /+
1515 Converts this interval to a string.
1516 +/
1517 // Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
1518 // have versions of toString() with extra modifiers, so we define one version
1519 // with modifiers and one without.
1520 string toString()
1521 {
1522 return _toStringImpl();
1523 }
1524
1525
1526 /++
1527 Converts this interval to a string.
1528 +/
1529 // Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
1530 // have versions of toString() with extra modifiers, so we define one version
1531 // with modifiers and one without.
1532 string toString() const nothrow
1533 {
1534 return _toStringImpl();
1535 }
1536
1537
1538 private:
1539
1540 /+
1541 Since we have two versions of toString, we have _toStringImpl
1542 so that they can share implementations.
1543 +/
1544 string _toStringImpl() const nothrow
1545 {
1546 import std.format : format;
1547 try
1548 return format("[%s - %s)", _begin, _end);
1549 catch (Exception e)
1550 assert(0, "format() threw.");
1551 }
1552
1553
1554 /+
1555 Throws:
1556 $(REF DateTimeException,std,datetime,date) if this interval is
1557 empty.
1558 +/
1559 void _enforceNotEmpty(size_t line = __LINE__) const pure
1560 {
1561 if (empty)
1562 throw new DateTimeException("Invalid operation for an empty Interval.", __FILE__, line);
1563 }
1564
1565
1566 /+
1567 Whether the given values form a valid time interval.
1568
1569 Params:
1570 begin = The starting point of the interval.
1571 end = The end point of the interval.
1572 +/
1573 static bool _valid(in TP begin, in TP end) pure nothrow
1574 {
1575 return begin <= end;
1576 }
1577
1578
1579 pure invariant()
1580 {
1581 assert(_valid(_begin, _end), "Invariant Failure: begin is not before or equal to end.");
1582 }
1583
1584
1585 TP _begin;
1586 TP _end;
1587 }
1588
1589 // Test Interval's constructors.
1590 @safe unittest
1591 {
1592 import std.datetime.date;
1593 import std.datetime.systime;
1594
1595 assertThrown!DateTimeException(Interval!Date(Date(2010, 1, 1), Date(1, 1, 1)));
1596
1597 Interval!Date(Date.init, Date.init);
1598 Interval!TimeOfDay(TimeOfDay.init, TimeOfDay.init);
1599 Interval!DateTime(DateTime.init, DateTime.init);
1600 Interval!SysTime(SysTime(0), SysTime(0));
1601
1602 Interval!DateTime(DateTime.init, dur!"days"(7));
1603
1604 // Verify Examples.
1605 Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
1606 assert(Interval!Date(Date(1996, 1, 2), dur!"weeks"(3)) == Interval!Date(Date(1996, 1, 2), Date(1996, 1, 23)));
1607 assert(Interval!Date(Date(1996, 1, 2), dur!"days"(3)) == Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5)));
1608 assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"hours"(3)) ==
1609 Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 15, 0, 0)));
1610 assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"minutes"(3)) ==
1611 Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 3, 0)));
1612 assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"seconds"(3)) ==
1613 Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3)));
1614 assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"msecs"(3000)) ==
1615 Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3)));
1616 }
1617
1618 // Test Interval's begin.
1619 @safe unittest
1620 {
1621 import std.datetime.date;
1622
1623 assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).begin == Date(1, 1, 1));
1624 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).begin == Date(2010, 1, 1));
1625 assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).begin == Date(1997, 12, 31));
1626
1627 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1628 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1629 assert(cInterval.begin == Date(2010, 7, 4));
1630 assert(iInterval.begin == Date(2010, 7, 4));
1631
1632 // Verify Examples.
1633 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == Date(1996, 1, 2));
1634 }
1635
1636 // Test Interval's end.
1637 @safe unittest
1638 {
1639 import std.datetime.date;
1640
1641 assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1));
1642 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1));
1643 assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).end == Date(1998, 1, 1));
1644
1645 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1646 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1647 assert(cInterval.end == Date(2012, 1, 7));
1648 assert(iInterval.end == Date(2012, 1, 7));
1649
1650 // Verify Examples.
1651 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == Date(2012, 3, 1));
1652 }
1653
1654 // Test Interval's length.
1655 @safe unittest
1656 {
1657 import std.datetime.date;
1658 import std.datetime.systime;
1659
1660 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).length == dur!"days"(0));
1661 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).length == dur!"days"(90));
1662 assert(Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).length == dur!"seconds"(42_727));
1663 assert(Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).length ==
1664 dur!"seconds"(129_127));
1665 assert(Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)),SysTime(DateTime(2010, 1, 2, 12, 22, 7))).length ==
1666 dur!"seconds"(129_127));
1667
1668 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1669 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1670 assert(cInterval.length != Duration.zero);
1671 assert(iInterval.length != Duration.zero);
1672
1673 // Verify Examples.
1674 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == dur!"days"(5903));
1675 }
1676
1677 // Test Interval's empty.
1678 @safe unittest
1679 {
1680 import std.datetime.date;
1681 import std.datetime.systime;
1682
1683 assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).empty);
1684 assert(!Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).empty);
1685 assert(!Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).empty);
1686 assert(!Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).empty);
1687 assert(!Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)), SysTime(DateTime(2010, 1, 2, 12, 22, 7))).empty);
1688
1689 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1690 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1691 assert(!cInterval.empty);
1692 assert(!iInterval.empty);
1693
1694 // Verify Examples.
1695 assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty);
1696 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty);
1697 }
1698
1699 // Test Interval's contains(time point).
1700 @safe unittest
1701 {
1702 import std.datetime.date;
1703
1704 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1705
1706 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(Date(2010, 7, 4)));
1707
1708 assert(!interval.contains(Date(2009, 7, 4)));
1709 assert(!interval.contains(Date(2010, 7, 3)));
1710 assert(interval.contains(Date(2010, 7, 4)));
1711 assert(interval.contains(Date(2010, 7, 5)));
1712 assert(interval.contains(Date(2011, 7, 1)));
1713 assert(interval.contains(Date(2012, 1, 6)));
1714 assert(!interval.contains(Date(2012, 1, 7)));
1715 assert(!interval.contains(Date(2012, 1, 8)));
1716 assert(!interval.contains(Date(2013, 1, 7)));
1717
1718 const cdate = Date(2010, 7, 6);
1719 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1720 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1721 assert(interval.contains(cdate));
1722 assert(cInterval.contains(cdate));
1723 assert(iInterval.contains(cdate));
1724
1725 // Verify Examples.
1726 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(1994, 12, 24)));
1727 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2000, 1, 5)));
1728 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2012, 3, 1)));
1729 }
1730
1731 // Test Interval's contains(Interval).
1732 @safe unittest
1733 {
1734 import std.datetime.date;
1735
1736 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1737
1738 assertThrown!DateTimeException(interval.contains(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
1739 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(interval));
1740 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4),dur!"days"(0)).contains(
1741 Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
1742
1743 assert(interval.contains(interval));
1744 assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
1745 assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
1746 assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
1747 assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
1748 assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
1749 assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
1750 assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
1751 assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
1752 assert(interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
1753 assert(!interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
1754 assert(!interval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
1755 assert(!interval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
1756
1757 assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).contains(interval));
1758 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).contains(interval));
1759 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).contains(interval));
1760 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).contains(interval));
1761 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).contains(interval));
1762 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).contains(interval));
1763 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).contains(interval));
1764 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).contains(interval));
1765 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).contains(interval));
1766 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).contains(interval));
1767 assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).contains(interval));
1768 assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).contains(interval));
1769
1770 assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 3))));
1771 assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 4))));
1772 assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 5))));
1773 assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 6))));
1774 assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 7))));
1775 assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 8))));
1776
1777 assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 3))));
1778 assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 4))));
1779 assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 5))));
1780 assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 6))));
1781 assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 7))));
1782 assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 8))));
1783
1784 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1785 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1786 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
1787 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
1788 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
1789 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
1790 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
1791 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
1792 assert(interval.contains(interval));
1793 assert(interval.contains(cInterval));
1794 assert(interval.contains(iInterval));
1795 assert(!interval.contains(posInfInterval));
1796 assert(!interval.contains(cPosInfInterval));
1797 assert(!interval.contains(iPosInfInterval));
1798 assert(!interval.contains(negInfInterval));
1799 assert(!interval.contains(cNegInfInterval));
1800 assert(!interval.contains(iNegInfInterval));
1801 assert(cInterval.contains(interval));
1802 assert(cInterval.contains(cInterval));
1803 assert(cInterval.contains(iInterval));
1804 assert(!cInterval.contains(posInfInterval));
1805 assert(!cInterval.contains(cPosInfInterval));
1806 assert(!cInterval.contains(iPosInfInterval));
1807 assert(!cInterval.contains(negInfInterval));
1808 assert(!cInterval.contains(cNegInfInterval));
1809 assert(!cInterval.contains(iNegInfInterval));
1810 assert(iInterval.contains(interval));
1811 assert(iInterval.contains(cInterval));
1812 assert(iInterval.contains(iInterval));
1813 assert(!iInterval.contains(posInfInterval));
1814 assert(!iInterval.contains(cPosInfInterval));
1815 assert(!iInterval.contains(iPosInfInterval));
1816 assert(!iInterval.contains(negInfInterval));
1817 assert(!iInterval.contains(cNegInfInterval));
1818 assert(!iInterval.contains(iNegInfInterval));
1819
1820 // Verify Examples.
1821 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
1822 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
1823 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
1824 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
1825 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
1826 Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));
1827
1828 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4))));
1829
1830 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4))));
1831 }
1832
1833 // Test Interval's isBefore(time point).
1834 @safe unittest
1835 {
1836 import std.datetime.date;
1837
1838 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1839
1840 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(Date(2010, 7, 4)));
1841
1842 assert(!interval.isBefore(Date(2009, 7, 3)));
1843 assert(!interval.isBefore(Date(2010, 7, 3)));
1844 assert(!interval.isBefore(Date(2010, 7, 4)));
1845 assert(!interval.isBefore(Date(2010, 7, 5)));
1846 assert(!interval.isBefore(Date(2011, 7, 1)));
1847 assert(!interval.isBefore(Date(2012, 1, 6)));
1848 assert(interval.isBefore(Date(2012, 1, 7)));
1849 assert(interval.isBefore(Date(2012, 1, 8)));
1850 assert(interval.isBefore(Date(2013, 1, 7)));
1851
1852 const cdate = Date(2010, 7, 6);
1853 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1854 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1855 assert(!interval.isBefore(cdate));
1856 assert(!cInterval.isBefore(cdate));
1857 assert(!iInterval.isBefore(cdate));
1858
1859 // Verify Examples.
1860 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(1994, 12, 24)));
1861 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2000, 1, 5)));
1862 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2012, 3, 1)));
1863 }
1864
1865 // Test Interval's isBefore(Interval).
1866 @safe unittest
1867 {
1868 import std.datetime.date;
1869
1870 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1871
1872 assertThrown!DateTimeException(interval.isBefore(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
1873 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(interval));
1874 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(
1875 Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
1876
1877 assert(!interval.isBefore(interval));
1878 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
1879 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
1880 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
1881 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
1882 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
1883 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
1884 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
1885 assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
1886 assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
1887 assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
1888 assert(interval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
1889 assert(interval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
1890
1891 assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isBefore(interval));
1892 assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isBefore(interval));
1893 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isBefore(interval));
1894 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isBefore(interval));
1895 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isBefore(interval));
1896 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isBefore(interval));
1897 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isBefore(interval));
1898 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isBefore(interval));
1899 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isBefore(interval));
1900 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isBefore(interval));
1901 assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isBefore(interval));
1902 assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isBefore(interval));
1903
1904 assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 3))));
1905 assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 4))));
1906 assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 5))));
1907 assert(!interval.isBefore(PosInfInterval!Date(Date(2012, 1, 6))));
1908 assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 7))));
1909 assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 8))));
1910
1911 assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 3))));
1912 assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 4))));
1913 assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 5))));
1914 assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 6))));
1915 assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 7))));
1916 assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 8))));
1917
1918 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1919 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1920 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
1921 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
1922 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
1923 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
1924 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
1925 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
1926 assert(!interval.isBefore(interval));
1927 assert(!interval.isBefore(cInterval));
1928 assert(!interval.isBefore(iInterval));
1929 assert(!interval.isBefore(posInfInterval));
1930 assert(!interval.isBefore(cPosInfInterval));
1931 assert(!interval.isBefore(iPosInfInterval));
1932 assert(!interval.isBefore(negInfInterval));
1933 assert(!interval.isBefore(cNegInfInterval));
1934 assert(!interval.isBefore(iNegInfInterval));
1935 assert(!cInterval.isBefore(interval));
1936 assert(!cInterval.isBefore(cInterval));
1937 assert(!cInterval.isBefore(iInterval));
1938 assert(!cInterval.isBefore(posInfInterval));
1939 assert(!cInterval.isBefore(cPosInfInterval));
1940 assert(!cInterval.isBefore(iPosInfInterval));
1941 assert(!cInterval.isBefore(negInfInterval));
1942 assert(!cInterval.isBefore(cNegInfInterval));
1943 assert(!cInterval.isBefore(iNegInfInterval));
1944 assert(!iInterval.isBefore(interval));
1945 assert(!iInterval.isBefore(cInterval));
1946 assert(!iInterval.isBefore(iInterval));
1947 assert(!iInterval.isBefore(posInfInterval));
1948 assert(!iInterval.isBefore(cPosInfInterval));
1949 assert(!iInterval.isBefore(iPosInfInterval));
1950 assert(!iInterval.isBefore(negInfInterval));
1951 assert(!iInterval.isBefore(cNegInfInterval));
1952 assert(!iInterval.isBefore(iNegInfInterval));
1953
1954 // Verify Examples.
1955 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
1956 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
1957 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
1958 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
1959 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
1960 Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1))));
1961
1962 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4))));
1963 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2013, 3, 7))));
1964
1965 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4))));
1966 }
1967
1968 // Test Interval's isAfter(time point).
1969 @safe unittest
1970 {
1971 import std.datetime.date;
1972
1973 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1974
1975 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(Date(2010, 7, 4)));
1976
1977 assert(interval.isAfter(Date(2009, 7, 4)));
1978 assert(interval.isAfter(Date(2010, 7, 3)));
1979 assert(!interval.isAfter(Date(2010, 7, 4)));
1980 assert(!interval.isAfter(Date(2010, 7, 5)));
1981 assert(!interval.isAfter(Date(2011, 7, 1)));
1982 assert(!interval.isAfter(Date(2012, 1, 6)));
1983 assert(!interval.isAfter(Date(2012, 1, 7)));
1984 assert(!interval.isAfter(Date(2012, 1, 8)));
1985 assert(!interval.isAfter(Date(2013, 1, 7)));
1986
1987 const cdate = Date(2010, 7, 6);
1988 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1989 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
1990 assert(!interval.isAfter(cdate));
1991 assert(!cInterval.isAfter(cdate));
1992 assert(!iInterval.isAfter(cdate));
1993
1994 // Verify Examples.
1995 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(1994, 12, 24)));
1996 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2000, 1, 5)));
1997 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2012, 3, 1)));
1998 }
1999
2000 // Test Interval's isAfter(Interval).
2001 @safe unittest
2002 {
2003 import std.datetime.date;
2004
2005 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2006
2007 assertThrown!DateTimeException(interval.isAfter(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2008 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(interval));
2009 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(
2010 Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2011
2012 assert(!interval.isAfter(interval));
2013 assert(interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
2014 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
2015 assert(interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
2016 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
2017 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
2018 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
2019 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
2020 assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
2021 assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
2022 assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
2023 assert(!interval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
2024 assert(!interval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
2025
2026 assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAfter(interval));
2027 assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAfter(interval));
2028 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAfter(interval));
2029 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAfter(interval));
2030 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAfter(interval));
2031 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAfter(interval));
2032 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAfter(interval));
2033 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAfter(interval));
2034 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAfter(interval));
2035 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAfter(interval));
2036 assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAfter(interval));
2037 assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAfter(interval));
2038
2039 assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 3))));
2040 assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 4))));
2041 assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 5))));
2042 assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 6))));
2043 assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 7))));
2044 assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 8))));
2045
2046 assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 3))));
2047 assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 4))));
2048 assert(!interval.isAfter(NegInfInterval!Date(Date(2010, 7, 5))));
2049 assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 6))));
2050 assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 7))));
2051 assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 8))));
2052
2053 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2054 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2055 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2056 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2057 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2058 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2059 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2060 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2061 assert(!interval.isAfter(interval));
2062 assert(!interval.isAfter(cInterval));
2063 assert(!interval.isAfter(iInterval));
2064 assert(!interval.isAfter(posInfInterval));
2065 assert(!interval.isAfter(cPosInfInterval));
2066 assert(!interval.isAfter(iPosInfInterval));
2067 assert(!interval.isAfter(negInfInterval));
2068 assert(!interval.isAfter(cNegInfInterval));
2069 assert(!interval.isAfter(iNegInfInterval));
2070 assert(!cInterval.isAfter(interval));
2071 assert(!cInterval.isAfter(cInterval));
2072 assert(!cInterval.isAfter(iInterval));
2073 assert(!cInterval.isAfter(posInfInterval));
2074 assert(!cInterval.isAfter(cPosInfInterval));
2075 assert(!cInterval.isAfter(iPosInfInterval));
2076 assert(!cInterval.isAfter(negInfInterval));
2077 assert(!cInterval.isAfter(cNegInfInterval));
2078 assert(!cInterval.isAfter(iNegInfInterval));
2079 assert(!iInterval.isAfter(interval));
2080 assert(!iInterval.isAfter(cInterval));
2081 assert(!iInterval.isAfter(iInterval));
2082 assert(!iInterval.isAfter(posInfInterval));
2083 assert(!iInterval.isAfter(cPosInfInterval));
2084 assert(!iInterval.isAfter(iPosInfInterval));
2085 assert(!iInterval.isAfter(negInfInterval));
2086 assert(!iInterval.isAfter(cNegInfInterval));
2087 assert(!iInterval.isAfter(iNegInfInterval));
2088
2089 // Verify Examples.
2090 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
2091 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
2092 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
2093 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
2094 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
2095 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
2096
2097 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4))));
2098
2099 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 1, 2))));
2100 }
2101
2102 // Test Interval's intersects().
2103 @safe unittest
2104 {
2105 import std.datetime.date;
2106
2107 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2108
2109 assertThrown!DateTimeException(interval.intersects(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2110 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects(interval));
2111 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects(
2112 Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2113
2114 assert(interval.intersects(interval));
2115 assert(!interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
2116 assert(interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
2117 assert(!interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
2118 assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
2119 assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
2120 assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
2121 assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
2122 assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
2123 assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
2124 assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
2125 assert(!interval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
2126 assert(!interval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
2127
2128 assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersects(interval));
2129 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersects(interval));
2130 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersects(interval));
2131 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersects(interval));
2132 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersects(interval));
2133 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersects(interval));
2134 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersects(interval));
2135 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersects(interval));
2136 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersects(interval));
2137 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersects(interval));
2138 assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersects(interval));
2139 assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersects(interval));
2140
2141 assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 3))));
2142 assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 4))));
2143 assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 5))));
2144 assert(interval.intersects(PosInfInterval!Date(Date(2012, 1, 6))));
2145 assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 7))));
2146 assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 8))));
2147
2148 assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 3))));
2149 assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 4))));
2150 assert(interval.intersects(NegInfInterval!Date(Date(2010, 7, 5))));
2151 assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 6))));
2152 assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 7))));
2153 assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 8))));
2154
2155 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2156 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2157 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2158 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2159 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2160 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2161 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2162 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2163 assert(interval.intersects(interval));
2164 assert(interval.intersects(cInterval));
2165 assert(interval.intersects(iInterval));
2166 assert(interval.intersects(posInfInterval));
2167 assert(interval.intersects(cPosInfInterval));
2168 assert(interval.intersects(iPosInfInterval));
2169 assert(interval.intersects(negInfInterval));
2170 assert(interval.intersects(cNegInfInterval));
2171 assert(interval.intersects(iNegInfInterval));
2172 assert(cInterval.intersects(interval));
2173 assert(cInterval.intersects(cInterval));
2174 assert(cInterval.intersects(iInterval));
2175 assert(cInterval.intersects(posInfInterval));
2176 assert(cInterval.intersects(cPosInfInterval));
2177 assert(cInterval.intersects(iPosInfInterval));
2178 assert(cInterval.intersects(negInfInterval));
2179 assert(cInterval.intersects(cNegInfInterval));
2180 assert(cInterval.intersects(iNegInfInterval));
2181 assert(iInterval.intersects(interval));
2182 assert(iInterval.intersects(cInterval));
2183 assert(iInterval.intersects(iInterval));
2184 assert(iInterval.intersects(posInfInterval));
2185 assert(iInterval.intersects(cPosInfInterval));
2186 assert(iInterval.intersects(iPosInfInterval));
2187 assert(iInterval.intersects(negInfInterval));
2188 assert(iInterval.intersects(cNegInfInterval));
2189 assert(iInterval.intersects(iNegInfInterval));
2190
2191 // Verify Examples.
2192 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
2193 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
2194 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
2195 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
2196 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
2197 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
2198
2199 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4))));
2200 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1))));
2201
2202 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 1, 2))));
2203 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2000, 1, 2))));
2204 }
2205
2206 // Test Interval's intersection().
2207 @safe unittest
2208 {
2209 import std.datetime.date;
2210
2211 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2212
2213 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2214 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection(interval));
2215 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection(
2216 Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2217
2218 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
2219 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
2220 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
2221 assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
2222
2223 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersection(interval));
2224 assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersection(interval));
2225 assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersection(interval));
2226 assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersection(interval));
2227
2228 assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 7))));
2229 assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 8))));
2230
2231 assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 3))));
2232 assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 4))));
2233
2234 assert(interval.intersection(interval) == interval);
2235 assert(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==
2236 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2237 assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==
2238 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));
2239 assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==
2240 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2241 assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==
2242 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2243 assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==
2244 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)));
2245 assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==
2246 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));
2247 assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==
2248 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
2249 assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==
2250 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
2251
2252 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersection(interval) ==
2253 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2254 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersection(interval) ==
2255 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));
2256 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersection(interval) ==
2257 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2258 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersection(interval) ==
2259 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2260 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersection(interval) ==
2261 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)));
2262 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersection(interval) ==
2263 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));
2264 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersection(interval) ==
2265 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
2266 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersection(interval) ==
2267 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
2268
2269 assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) ==
2270 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2271 assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) ==
2272 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2273 assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) ==
2274 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));
2275 assert(interval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) ==
2276 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
2277
2278 assert(interval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) ==
2279 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));
2280 assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) ==
2281 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6)));
2282 assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) ==
2283 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2284 assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) ==
2285 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2286
2287 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2288 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2289 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2290 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2291 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2292 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2293 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2294 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2295 assert(!interval.intersection(interval).empty);
2296 assert(!interval.intersection(cInterval).empty);
2297 assert(!interval.intersection(iInterval).empty);
2298 assert(!interval.intersection(posInfInterval).empty);
2299 assert(!interval.intersection(cPosInfInterval).empty);
2300 assert(!interval.intersection(iPosInfInterval).empty);
2301 assert(!interval.intersection(negInfInterval).empty);
2302 assert(!interval.intersection(cNegInfInterval).empty);
2303 assert(!interval.intersection(iNegInfInterval).empty);
2304 assert(!cInterval.intersection(interval).empty);
2305 assert(!cInterval.intersection(cInterval).empty);
2306 assert(!cInterval.intersection(iInterval).empty);
2307 assert(!cInterval.intersection(posInfInterval).empty);
2308 assert(!cInterval.intersection(cPosInfInterval).empty);
2309 assert(!cInterval.intersection(iPosInfInterval).empty);
2310 assert(!cInterval.intersection(negInfInterval).empty);
2311 assert(!cInterval.intersection(cNegInfInterval).empty);
2312 assert(!cInterval.intersection(iNegInfInterval).empty);
2313 assert(!iInterval.intersection(interval).empty);
2314 assert(!iInterval.intersection(cInterval).empty);
2315 assert(!iInterval.intersection(iInterval).empty);
2316 assert(!iInterval.intersection(posInfInterval).empty);
2317 assert(!iInterval.intersection(cPosInfInterval).empty);
2318 assert(!iInterval.intersection(iPosInfInterval).empty);
2319 assert(!iInterval.intersection(negInfInterval).empty);
2320 assert(!iInterval.intersection(cNegInfInterval).empty);
2321 assert(!iInterval.intersection(iNegInfInterval).empty);
2322
2323 // Verify Examples.
2324 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
2325 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
2326 Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2)));
2327 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
2328 Interval!Date(Date(1999, 1, 12),Date(2011, 9, 17))) ==
2329 Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17)));
2330
2331 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
2332 PosInfInterval!Date(Date(1990, 7, 6))) ==
2333 Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1)));
2334 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
2335 PosInfInterval!Date(Date(1999, 1, 12))) ==
2336 Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));
2337
2338 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
2339 NegInfInterval!Date(Date(1999, 7, 6))) ==
2340 Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6)));
2341 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
2342 NegInfInterval!Date(Date(2013, 1, 12))) ==
2343 Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1)));
2344 }
2345
2346 // Test Interval's isAdjacent().
2347 @safe unittest
2348 {
2349 import std.datetime.date;
2350
2351 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2352
2353 static void testInterval(in Interval!Date interval1, in Interval!Date interval2)
2354 {
2355 interval1.isAdjacent(interval2);
2356 }
2357
2358 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2359 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval));
2360 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)),
2361 Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2362
2363 assert(!interval.isAdjacent(interval));
2364 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
2365 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
2366 assert(interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
2367 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
2368 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
2369 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
2370 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
2371 assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
2372 assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
2373 assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
2374 assert(interval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
2375 assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
2376
2377 assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAdjacent(interval));
2378 assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAdjacent(interval));
2379 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAdjacent(interval));
2380 assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAdjacent(interval));
2381 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAdjacent(interval));
2382 assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAdjacent(interval));
2383 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAdjacent(interval));
2384 assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAdjacent(interval));
2385 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAdjacent(interval));
2386 assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAdjacent(interval));
2387 assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAdjacent(interval));
2388 assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAdjacent(interval));
2389
2390 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3))));
2391 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4))));
2392 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5))));
2393 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6))));
2394 assert(interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7))));
2395 assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8))));
2396
2397 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3))));
2398 assert(interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4))));
2399 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5))));
2400 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6))));
2401 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7))));
2402 assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8))));
2403
2404 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2405 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2406 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2407 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2408 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2409 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2410 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2411 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2412 assert(!interval.isAdjacent(interval));
2413 assert(!interval.isAdjacent(cInterval));
2414 assert(!interval.isAdjacent(iInterval));
2415 assert(!interval.isAdjacent(posInfInterval));
2416 assert(!interval.isAdjacent(cPosInfInterval));
2417 assert(!interval.isAdjacent(iPosInfInterval));
2418 assert(!interval.isAdjacent(negInfInterval));
2419 assert(!interval.isAdjacent(cNegInfInterval));
2420 assert(!interval.isAdjacent(iNegInfInterval));
2421 assert(!cInterval.isAdjacent(interval));
2422 assert(!cInterval.isAdjacent(cInterval));
2423 assert(!cInterval.isAdjacent(iInterval));
2424 assert(!cInterval.isAdjacent(posInfInterval));
2425 assert(!cInterval.isAdjacent(cPosInfInterval));
2426 assert(!cInterval.isAdjacent(iPosInfInterval));
2427 assert(!cInterval.isAdjacent(negInfInterval));
2428 assert(!cInterval.isAdjacent(cNegInfInterval));
2429 assert(!cInterval.isAdjacent(iNegInfInterval));
2430 assert(!iInterval.isAdjacent(interval));
2431 assert(!iInterval.isAdjacent(cInterval));
2432 assert(!iInterval.isAdjacent(iInterval));
2433 assert(!iInterval.isAdjacent(posInfInterval));
2434 assert(!iInterval.isAdjacent(cPosInfInterval));
2435 assert(!iInterval.isAdjacent(iPosInfInterval));
2436 assert(!iInterval.isAdjacent(negInfInterval));
2437 assert(!iInterval.isAdjacent(cNegInfInterval));
2438 assert(!iInterval.isAdjacent(iNegInfInterval));
2439
2440 // Verify Examples.
2441 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
2442 Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2))));
2443 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
2444 Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17))));
2445 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
2446 Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1))));
2447
2448 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4))));
2449 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1))));
2450
2451 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2))));
2452 assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)) .isAdjacent(NegInfInterval!Date(Date(2000, 1, 2))));
2453 }
2454
2455 // Test Interval's merge().
2456 @safe unittest
2457 {
2458 import std.datetime.date;
2459
2460 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2461
testInterval(I)2462 static void testInterval(I)(in Interval!Date interval1, in I interval2)
2463 {
2464 interval1.merge(interval2);
2465 }
2466
2467 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2468 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval));
2469 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)),
2470 Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2471
2472 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
2473 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
2474
2475 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)), interval));
2476 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)), interval));
2477
2478 assertThrown!DateTimeException(testInterval(interval, PosInfInterval!Date(Date(2012, 1, 8))));
2479
2480 assertThrown!DateTimeException(testInterval(interval, NegInfInterval!Date(Date(2010, 7, 3))));
2481
2482 assert(interval.merge(interval) == interval);
2483 assert(interval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==
2484 Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)));
2485 assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==
2486 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
2487 assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==
2488 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
2489 assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==
2490 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
2491 assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==
2492 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)));
2493 assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==
2494 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2495 assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==
2496 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2497 assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==
2498 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2499 assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==
2500 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
2501 assert(interval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==
2502 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
2503
2504 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).merge(interval) ==
2505 Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)));
2506 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).merge(interval) ==
2507 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
2508 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).merge(interval) ==
2509 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
2510 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).merge(interval) ==
2511 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
2512 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).merge(interval) ==
2513 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)));
2514 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).merge(interval) ==
2515 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2516 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).merge(interval) ==
2517 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2518 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).merge(interval) ==
2519 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2520 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).merge(interval) ==
2521 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
2522 assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).merge(interval) ==
2523 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
2524
2525 assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 3))) ==
2526 PosInfInterval!Date(Date(2010, 7, 3)));
2527 assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 4))) ==
2528 PosInfInterval!Date(Date(2010, 7, 4)));
2529 assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 5))) ==
2530 PosInfInterval!Date(Date(2010, 7, 4)));
2531 assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 6))) ==
2532 PosInfInterval!Date(Date(2010, 7, 4)));
2533 assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 7))) ==
2534 PosInfInterval!Date(Date(2010, 7, 4)));
2535
2536 assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 4))) ==
2537 NegInfInterval!Date(Date(2012, 1, 7)));
2538 assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 5))) ==
2539 NegInfInterval!Date(Date(2012, 1, 7)));
2540 assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 6))) ==
2541 NegInfInterval!Date(Date(2012, 1, 7)));
2542 assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 7))) ==
2543 NegInfInterval!Date(Date(2012, 1, 7)));
2544 assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 8))) ==
2545 NegInfInterval!Date(Date(2012, 1, 8)));
2546
2547 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2548 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2549 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2550 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2551 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2552 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2553 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2554 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2555 assert(!interval.merge(interval).empty);
2556 assert(!interval.merge(cInterval).empty);
2557 assert(!interval.merge(iInterval).empty);
2558 assert(!interval.merge(posInfInterval).empty);
2559 assert(!interval.merge(cPosInfInterval).empty);
2560 assert(!interval.merge(iPosInfInterval).empty);
2561 assert(!interval.merge(negInfInterval).empty);
2562 assert(!interval.merge(cNegInfInterval).empty);
2563 assert(!interval.merge(iNegInfInterval).empty);
2564 assert(!cInterval.merge(interval).empty);
2565 assert(!cInterval.merge(cInterval).empty);
2566 assert(!cInterval.merge(iInterval).empty);
2567 assert(!cInterval.merge(posInfInterval).empty);
2568 assert(!cInterval.merge(cPosInfInterval).empty);
2569 assert(!cInterval.merge(iPosInfInterval).empty);
2570 assert(!cInterval.merge(negInfInterval).empty);
2571 assert(!cInterval.merge(cNegInfInterval).empty);
2572 assert(!cInterval.merge(iNegInfInterval).empty);
2573 assert(!iInterval.merge(interval).empty);
2574 assert(!iInterval.merge(cInterval).empty);
2575 assert(!iInterval.merge(iInterval).empty);
2576 assert(!iInterval.merge(posInfInterval).empty);
2577 assert(!iInterval.merge(cPosInfInterval).empty);
2578 assert(!iInterval.merge(iPosInfInterval).empty);
2579 assert(!iInterval.merge(negInfInterval).empty);
2580 assert(!iInterval.merge(cNegInfInterval).empty);
2581 assert(!iInterval.merge(iNegInfInterval).empty);
2582
2583 // Verify Examples.
2584 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
2585 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));
2586 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) ==
2587 Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7)));
2588
2589 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(1990, 7, 6))) ==
2590 PosInfInterval!Date(Date(1990, 7 , 6)));
2591 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(2012, 3, 1))) ==
2592 PosInfInterval!Date(Date(1996, 1 , 2)));
2593
2594 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1996, 1, 2))) ==
2595 NegInfInterval!Date(Date(2012, 3 , 1)));
2596 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) ==
2597 NegInfInterval!Date(Date(2013, 1 , 12)));
2598 }
2599
2600 // Test Interval's span().
2601 @safe unittest
2602 {
2603 import std.datetime.date;
2604
2605 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2606
2607 static void testInterval(in Interval!Date interval1, in Interval!Date interval2)
2608 {
2609 interval1.span(interval2);
2610 }
2611
2612 assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2613 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)),interval));
2614 assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)),
2615 Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2616
2617 assert(interval.span(interval) == interval);
2618 assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) ==
2619 Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7)));
2620 assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==
2621 Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)));
2622 assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==
2623 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
2624 assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==
2625 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
2626 assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==
2627 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
2628 assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==
2629 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)));
2630 assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==
2631 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2632 assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==
2633 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2634 assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==
2635 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2636 assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==
2637 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
2638 assert(interval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==
2639 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
2640 assert(interval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) ==
2641 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9)));
2642
2643 assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).span(interval) ==
2644 Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7)));
2645 assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).span(interval) ==
2646 Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)));
2647 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).span(interval) ==
2648 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
2649 assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).span(interval) ==
2650 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
2651 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).span(interval) ==
2652 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
2653 assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).span(interval) ==
2654 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)));
2655 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).span(interval) ==
2656 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2657 assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).span(interval) ==
2658 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2659 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).span(interval) ==
2660 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
2661 assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).span(interval) ==
2662 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
2663 assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).span(interval) ==
2664 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
2665 assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).span(interval) ==
2666 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9)));
2667
2668 assert(interval.span(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3)));
2669 assert(interval.span(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4)));
2670 assert(interval.span(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4)));
2671 assert(interval.span(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4)));
2672 assert(interval.span(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4)));
2673 assert(interval.span(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4)));
2674
2675 assert(interval.span(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7)));
2676 assert(interval.span(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7)));
2677 assert(interval.span(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7)));
2678 assert(interval.span(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7)));
2679 assert(interval.span(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7)));
2680 assert(interval.span(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8)));
2681
2682 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2683 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2684 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2685 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2686 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
2687 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2688 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2689 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
2690 assert(!interval.span(interval).empty);
2691 assert(!interval.span(cInterval).empty);
2692 assert(!interval.span(iInterval).empty);
2693 assert(!interval.span(posInfInterval).empty);
2694 assert(!interval.span(cPosInfInterval).empty);
2695 assert(!interval.span(iPosInfInterval).empty);
2696 assert(!interval.span(negInfInterval).empty);
2697 assert(!interval.span(cNegInfInterval).empty);
2698 assert(!interval.span(iNegInfInterval).empty);
2699 assert(!cInterval.span(interval).empty);
2700 assert(!cInterval.span(cInterval).empty);
2701 assert(!cInterval.span(iInterval).empty);
2702 assert(!cInterval.span(posInfInterval).empty);
2703 assert(!cInterval.span(cPosInfInterval).empty);
2704 assert(!cInterval.span(iPosInfInterval).empty);
2705 assert(!cInterval.span(negInfInterval).empty);
2706 assert(!cInterval.span(cNegInfInterval).empty);
2707 assert(!cInterval.span(iNegInfInterval).empty);
2708 assert(!iInterval.span(interval).empty);
2709 assert(!iInterval.span(cInterval).empty);
2710 assert(!iInterval.span(iInterval).empty);
2711 assert(!iInterval.span(posInfInterval).empty);
2712 assert(!iInterval.span(cPosInfInterval).empty);
2713 assert(!iInterval.span(iPosInfInterval).empty);
2714 assert(!iInterval.span(negInfInterval).empty);
2715 assert(!iInterval.span(cNegInfInterval).empty);
2716 assert(!iInterval.span(iNegInfInterval).empty);
2717
2718 // Verify Examples.
2719 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) ==
2720 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));
2721 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) ==
2722 Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7)));
2723
2724 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(1990, 7, 6))) ==
2725 PosInfInterval!Date(Date(1990, 7 , 6)));
2726 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(2050, 1, 1))) ==
2727 PosInfInterval!Date(Date(1996, 1 , 2)));
2728
2729 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1602, 5, 21))) ==
2730 NegInfInterval!Date(Date(2012, 3 , 1)));
2731 assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) ==
2732 NegInfInterval!Date(Date(2013, 1 , 12)));
2733 }
2734
2735 // Test Interval's shift(duration).
2736 @safe unittest
2737 {
2738 import std.datetime.date;
2739
2740 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2741
2742 static void testIntervalFail(Interval!Date interval, in Duration duration)
2743 {
2744 interval.shift(duration);
2745 }
2746
2747 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1)));
2748
testInterval(I)2749 static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__)
2750 {
2751 interval.shift(duration);
2752 assert(interval == expected);
2753 }
2754
2755 testInterval(interval, dur!"days"(22), Interval!Date(Date(2010, 7, 26), Date(2012, 1, 29)));
2756 testInterval(interval, dur!"days"(-22), Interval!Date(Date(2010, 6, 12), Date(2011, 12, 16)));
2757
2758 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2759 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2760 static assert(!__traits(compiles, cInterval.shift(dur!"days"(5))));
2761 static assert(!__traits(compiles, iInterval.shift(dur!"days"(5))));
2762
2763 // Verify Examples.
2764 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5));
2765 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5));
2766
2767 interval1.shift(dur!"days"(50));
2768 assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25)));
2769
2770 interval2.shift(dur!"days"(-50));
2771 assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15)));
2772 }
2773
2774 // Test Interval's shift(int, int, AllowDayOverflow).
2775 @safe unittest
2776 {
2777 import std.datetime.date;
2778
2779 {
2780 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2781
2782 static void testIntervalFail(Interval!Date interval, int years, int months)
2783 {
2784 interval.shift(years, months);
2785 }
2786
2787 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0));
2788
testInterval(I)2789 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow,
2790 in I expected, size_t line = __LINE__)
2791 {
2792 interval.shift(years, months, allow);
2793 assert(interval == expected);
2794 }
2795
2796 testInterval(interval, 5, 0, AllowDayOverflow.yes, Interval!Date(Date(2015, 7, 4), Date(2017, 1, 7)));
2797 testInterval(interval, -5, 0, AllowDayOverflow.yes, Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7)));
2798
2799 auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31));
2800
2801 testInterval(interval2, 1, 1, AllowDayOverflow.yes, Interval!Date(Date(2001, 3, 1), Date(2011, 7, 1)));
2802 testInterval(interval2, 1, -1, AllowDayOverflow.yes, Interval!Date(Date(2000, 12, 29), Date(2011, 5, 1)));
2803 testInterval(interval2, -1, -1, AllowDayOverflow.yes, Interval!Date(Date(1998, 12, 29), Date(2009, 5, 1)));
2804 testInterval(interval2, -1, 1, AllowDayOverflow.yes, Interval!Date(Date(1999, 3, 1), Date(2009, 7, 1)));
2805
2806 testInterval(interval2, 1, 1, AllowDayOverflow.no, Interval!Date(Date(2001, 2, 28), Date(2011, 6, 30)));
2807 testInterval(interval2, 1, -1, AllowDayOverflow.no, Interval!Date(Date(2000, 12, 29), Date(2011, 4, 30)));
2808 testInterval(interval2, -1, -1, AllowDayOverflow.no, Interval!Date(Date(1998, 12, 29), Date(2009, 4, 30)));
2809 testInterval(interval2, -1, 1, AllowDayOverflow.no, Interval!Date(Date(1999, 2, 28), Date(2009, 6, 30)));
2810 }
2811
2812 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2813 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2814 static assert(!__traits(compiles, cInterval.shift(5)));
2815 static assert(!__traits(compiles, iInterval.shift(5)));
2816
2817 // Verify Examples.
2818 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
2819 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
2820
2821 interval1.shift(2);
2822 assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1)));
2823
2824 interval2.shift(-2);
2825 assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1)));
2826 }
2827
2828 // Test Interval's expand(Duration).
2829 @safe unittest
2830 {
2831 import std.datetime.date;
2832
2833 auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7));
2834
testIntervalFail(I)2835 static void testIntervalFail(I)(I interval, in Duration duration)
2836 {
2837 interval.expand(duration);
2838 }
2839
2840 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1)));
2841 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)), dur!"days"(-5)));
2842
testInterval(I)2843 static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__)
2844 {
2845 interval.expand(duration);
2846 assert(interval == expected);
2847 }
2848
2849 testInterval(interval, dur!"days"(22), Interval!Date(Date(2000, 6, 12), Date(2012, 1, 29)));
2850 testInterval(interval, dur!"days"(-22), Interval!Date(Date(2000, 7, 26), Date(2011, 12, 16)));
2851
2852 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2853 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2854 static assert(!__traits(compiles, cInterval.expand(dur!"days"(5))));
2855 static assert(!__traits(compiles, iInterval.expand(dur!"days"(5))));
2856
2857 // Verify Examples.
2858 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
2859 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
2860
2861 interval1.expand(dur!"days"(2));
2862 assert(interval1 == Interval!Date(Date(1995, 12, 31), Date(2012, 3, 3)));
2863
2864 interval2.expand(dur!"days"(-2));
2865 assert(interval2 == Interval!Date(Date(1996, 1, 4), Date(2012, 2, 28)));
2866 }
2867
2868 // Test Interval's expand(int, int, AllowDayOverflow, Direction)
2869 @safe unittest
2870 {
2871 import std.datetime.date;
2872
2873 {
2874 auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7));
2875
2876 static void testIntervalFail(Interval!Date interval, int years, int months)
2877 {
2878 interval.expand(years, months);
2879 }
2880
2881 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0));
2882 assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)), -5, 0));
2883
testInterval(I)2884 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, Direction dir,
2885 in I expected, size_t line = __LINE__)
2886 {
2887 interval.expand(years, months, allow, dir);
2888 assert(interval == expected);
2889 }
2890
2891 testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.both,
2892 Interval!Date(Date(1995, 7, 4), Date(2017, 1, 7)));
2893 testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.both,
2894 Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7)));
2895
2896 testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.fwd,
2897 Interval!Date(Date(2000, 7, 4), Date(2017, 1, 7)));
2898 testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.fwd,
2899 Interval!Date(Date(2000, 7, 4), Date(2007, 1, 7)));
2900
2901 testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.bwd,
2902 Interval!Date(Date(1995, 7, 4), Date(2012, 1, 7)));
2903 testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.bwd,
2904 Interval!Date(Date(2005, 7, 4), Date(2012, 1, 7)));
2905
2906 auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31));
2907
2908 testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.both,
2909 Interval!Date(Date(1998, 12, 29), Date(2011, 7, 1)));
2910 testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.both,
2911 Interval!Date(Date(1999, 3, 1), Date(2011, 5, 1)));
2912 testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.both,
2913 Interval!Date(Date(2001, 3, 1), Date(2009, 5, 1)));
2914 testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.both,
2915 Interval!Date(Date(2000, 12, 29), Date(2009, 7, 1)));
2916
2917 testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.both,
2918 Interval!Date(Date(1998, 12, 29), Date(2011, 6, 30)));
2919 testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.both,
2920 Interval!Date(Date(1999, 2, 28), Date(2011, 4, 30)));
2921 testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.both,
2922 Interval!Date(Date(2001, 2, 28), Date(2009, 4, 30)));
2923 testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.both,
2924 Interval!Date(Date(2000, 12, 29), Date(2009, 6, 30)));
2925
2926 testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.fwd,
2927 Interval!Date(Date(2000, 1, 29), Date(2011, 7, 1)));
2928 testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.fwd,
2929 Interval!Date(Date(2000, 1, 29), Date(2011, 5, 1)));
2930 testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.fwd,
2931 Interval!Date(Date(2000, 1, 29), Date(2009, 5, 1)));
2932 testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.fwd,
2933 Interval!Date(Date(2000, 1, 29), Date(2009, 7, 1)));
2934
2935 testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.fwd,
2936 Interval!Date(Date(2000, 1, 29), Date(2011, 6, 30)));
2937 testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.fwd,
2938 Interval!Date(Date(2000, 1, 29), Date(2011, 4, 30)));
2939 testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.fwd,
2940 Interval!Date(Date(2000, 1, 29), Date(2009, 4, 30)));
2941 testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.fwd,
2942 Interval!Date(Date(2000, 1, 29), Date(2009, 6, 30)));
2943
2944 testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.bwd,
2945 Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31)));
2946 testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.bwd,
2947 Interval!Date(Date(1999, 3, 1), Date(2010, 5, 31)));
2948 testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.bwd,
2949 Interval!Date(Date(2001, 3, 1), Date(2010, 5, 31)));
2950 testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.bwd,
2951 Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31)));
2952
2953 testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.bwd,
2954 Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31)));
2955 testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.bwd,
2956 Interval!Date(Date(1999, 2, 28), Date(2010, 5, 31)));
2957 testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.bwd,
2958 Interval!Date(Date(2001, 2, 28), Date(2010, 5, 31)));
2959 testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.bwd,
2960 Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31)));
2961 }
2962
2963 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2964 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
2965 static assert(!__traits(compiles, cInterval.expand(5)));
2966 static assert(!__traits(compiles, iInterval.expand(5)));
2967
2968 // Verify Examples.
2969 auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
2970 auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
2971
2972 interval1.expand(2);
2973 assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1)));
2974
2975 interval2.expand(-2);
2976 assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1)));
2977 }
2978
2979 // Test Interval's fwdRange.
2980 @system unittest
2981 {
2982 import std.datetime.date;
2983
2984 {
2985 auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21));
2986
2987 static void testInterval1(Interval!Date interval)
2988 {
2989 interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
2990 }
2991
2992 assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
2993
2994 static void testInterval2(Interval!Date interval)
2995 {
2996 interval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront();
2997 }
2998
2999 assertThrown!DateTimeException(testInterval2(interval));
3000
3001 assert(!interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);
3002 assert(interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).empty);
3003
3004 assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front ==
3005 Date(2010, 9, 12));
3006
3007 assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange(
3008 everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 17));
3009 }
3010
3011 // Verify Examples.
3012 {
3013 auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9));
delegate(in Date date)3014 auto func = delegate (in Date date)
3015 {
3016 if ((date.day & 1) == 0)
3017 return date + dur!"days"(2);
3018 return date + dur!"days"(1);
3019 };
3020 auto range = interval.fwdRange(func);
3021
3022 // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2).
3023 assert(range.front == Date(2010, 9, 1));
3024
3025 range.popFront();
3026 assert(range.front == Date(2010, 9, 2));
3027
3028 range.popFront();
3029 assert(range.front == Date(2010, 9, 4));
3030
3031 range.popFront();
3032 assert(range.front == Date(2010, 9, 6));
3033
3034 range.popFront();
3035 assert(range.front == Date(2010, 9, 8));
3036
3037 range.popFront();
3038 assert(range.empty);
3039 }
3040
3041 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
3042 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
3043 assert(!cInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);
3044 assert(!iInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);
3045 }
3046
3047 // Test Interval's bwdRange.
3048 @system unittest
3049 {
3050 import std.datetime.date;
3051
3052 {
3053 auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21));
3054
3055 static void testInterval1(Interval!Date interval)
3056 {
3057 interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
3058 }
3059
3060 assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
3061
3062 static void testInterval2(Interval!Date interval)
3063 {
3064 interval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront();
3065 }
3066
3067 assertThrown!DateTimeException(testInterval2(interval));
3068
3069 assert(!interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty);
3070 assert(interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).empty);
3071
3072 assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange(
3073 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front == Date(2010, 10, 1));
3074
3075 assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange(
3076 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 24));
3077 }
3078
3079 // Verify Examples.
3080 {
3081 auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9));
delegate(in Date date)3082 auto func = delegate (in Date date)
3083 {
3084 if ((date.day & 1) == 0)
3085 return date - dur!"days"(2);
3086 return date - dur!"days"(1);
3087 };
3088 auto range = interval.bwdRange(func);
3089
3090 // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8).
3091 assert(range.front == Date(2010, 9, 9));
3092
3093 range.popFront();
3094 assert(range.front == Date(2010, 9, 8));
3095
3096 range.popFront();
3097 assert(range.front == Date(2010, 9, 6));
3098
3099 range.popFront();
3100 assert(range.front == Date(2010, 9, 4));
3101
3102 range.popFront();
3103 assert(range.front == Date(2010, 9, 2));
3104
3105 range.popFront();
3106 assert(range.empty);
3107 }
3108
3109 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
3110 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
3111 assert(!cInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);
3112 assert(!iInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);
3113 }
3114
3115 // Test Interval's toString().
3116 @safe unittest
3117 {
3118 import std.datetime.date;
3119
3120 assert(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).toString() == "[2010-Jul-04 - 2012-Jan-07)");
3121
3122 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
3123 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
3124 assert(cInterval.toString());
3125 assert(iInterval.toString());
3126 }
3127
3128
3129 /++
3130 Represents an interval of time which has positive infinity as its end point.
3131
3132 Any ranges which iterate over a $(D PosInfInterval) are infinite. So, the
3133 main purpose of using $(D PosInfInterval) is to create an infinite range
3134 which starts at a fixed point in time and goes to positive infinity.
3135 +/
PosInfInterval(TP)3136 struct PosInfInterval(TP)
3137 {
3138 public:
3139
3140 /++
3141 Params:
3142 begin = The time point which begins the interval.
3143
3144 Example:
3145 --------------------
3146 auto interval = PosInfInterval!Date(Date(1996, 1, 2));
3147 --------------------
3148 +/
3149 this(in TP begin) pure nothrow
3150 {
3151 _begin = cast(TP) begin;
3152 }
3153
3154
3155 /++
3156 Params:
3157 rhs = The $(D PosInfInterval) to assign to this one.
3158 +/
3159 ref PosInfInterval opAssign(const ref PosInfInterval rhs) pure nothrow
3160 {
3161 _begin = cast(TP) rhs._begin;
3162 return this;
3163 }
3164
3165
3166 /++
3167 Params:
3168 rhs = The $(D PosInfInterval) to assign to this one.
3169 +/
3170 ref PosInfInterval opAssign(PosInfInterval rhs) pure nothrow
3171 {
3172 _begin = cast(TP) rhs._begin;
3173 return this;
3174 }
3175
3176
3177 /++
3178 The starting point of the interval. It is included in the interval.
3179
3180 Example:
3181 --------------------
3182 assert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2));
3183 --------------------
3184 +/
3185 @property TP begin() const pure nothrow
3186 {
3187 return cast(TP)_begin;
3188 }
3189
3190
3191 /++
3192 The starting point of the interval. It is included in the interval.
3193
3194 Params:
3195 timePoint = The time point to set $(D begin) to.
3196 +/
3197 @property void begin(TP timePoint) pure nothrow
3198 {
3199 _begin = timePoint;
3200 }
3201
3202
3203 /++
3204 Whether the interval's length is 0. Always returns false.
3205
3206 Example:
3207 --------------------
3208 assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty);
3209 --------------------
3210 +/
3211 enum bool empty = false;
3212
3213
3214 /++
3215 Whether the given time point is within this interval.
3216
3217 Params:
3218 timePoint = The time point to check for inclusion in this interval.
3219
3220 Example:
3221 --------------------
3222 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24)));
3223 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5)));
3224 --------------------
3225 +/
3226 bool contains(TP timePoint) const pure nothrow
3227 {
3228 return timePoint >= _begin;
3229 }
3230
3231
3232 /++
3233 Whether the given interval is completely within this interval.
3234
3235 Params:
3236 interval = The interval to check for inclusion in this interval.
3237
3238 Throws:
3239 $(REF DateTimeException,std,datetime,date) if the given interval
3240 is empty.
3241
3242 Example:
3243 --------------------
3244 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(
3245 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
3246
3247 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(
3248 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
3249
3250 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(
3251 Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));
3252 --------------------
3253 +/
3254 bool contains(in Interval!TP interval) const pure
3255 {
3256 interval._enforceNotEmpty();
3257 return interval._begin >= _begin;
3258 }
3259
3260
3261 /++
3262 Whether the given interval is completely within this interval.
3263
3264 Params:
3265 interval = The interval to check for inclusion in this interval.
3266
3267 Example:
3268 --------------------
3269 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(
3270 PosInfInterval!Date(Date(1999, 5, 4))));
3271
3272 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(
3273 PosInfInterval!Date(Date(1995, 7, 2))));
3274 --------------------
3275 +/
3276 bool contains(in PosInfInterval interval) const pure nothrow
3277 {
3278 return interval._begin >= _begin;
3279 }
3280
3281
3282 /++
3283 Whether the given interval is completely within this interval.
3284
3285 Always returns false because an interval going to positive infinity
3286 can never contain an interval beginning at negative infinity.
3287
3288 Params:
3289 interval = The interval to check for inclusion in this interval.
3290
3291 Example:
3292 --------------------
3293 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(
3294 NegInfInterval!Date(Date(1996, 5, 4))));
3295 --------------------
3296 +/
3297 bool contains(in NegInfInterval!TP interval) const pure nothrow
3298 {
3299 return false;
3300 }
3301
3302
3303 /++
3304 Whether this interval is before the given time point.
3305
3306 Always returns false because an interval going to positive infinity
3307 can never be before any time point.
3308
3309 Params:
3310 timePoint = The time point to check whether this interval is before
3311 it.
3312
3313 Example:
3314 --------------------
3315 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24)));
3316 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5)));
3317 --------------------
3318 +/
3319 bool isBefore(in TP timePoint) const pure nothrow
3320 {
3321 return false;
3322 }
3323
3324
3325 /++
3326 Whether this interval is before the given interval and does not
3327 intersect it.
3328
3329 Always returns false (unless the given interval is empty) because an
3330 interval going to positive infinity can never be before any other
3331 interval.
3332
3333 Params:
3334 interval = The interval to check for against this interval.
3335
3336 Throws:
3337 $(REF DateTimeException,std,datetime,date) if the given interval
3338 is empty.
3339
3340 Example:
3341 --------------------
3342 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(
3343 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
3344
3345 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(
3346 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
3347 --------------------
3348 +/
3349 bool isBefore(in Interval!TP interval) const pure
3350 {
3351 interval._enforceNotEmpty();
3352 return false;
3353 }
3354
3355
3356 /++
3357 Whether this interval is before the given interval and does not
3358 intersect it.
3359
3360 Always returns false because an interval going to positive infinity can
3361 never be before any other interval.
3362
3363 Params:
3364 interval = The interval to check for against this interval.
3365
3366 Example:
3367 --------------------
3368 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(
3369 PosInfInterval!Date(Date(1992, 5, 4))));
3370
3371 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(
3372 PosInfInterval!Date(Date(2013, 3, 7))));
3373 --------------------
3374 +/
3375 bool isBefore(in PosInfInterval interval) const pure nothrow
3376 {
3377 return false;
3378 }
3379
3380
3381 /++
3382 Whether this interval is before the given interval and does not
3383 intersect it.
3384
3385 Always returns false because an interval going to positive infinity can
3386 never be before any other interval.
3387
3388 Params:
3389 interval = The interval to check for against this interval.
3390
3391 Example:
3392 --------------------
3393 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(
3394 NegInfInterval!Date(Date(1996, 5, 4))));
3395 --------------------
3396 +/
3397 bool isBefore(in NegInfInterval!TP interval) const pure nothrow
3398 {
3399 return false;
3400 }
3401
3402
3403 /++
3404 Whether this interval is after the given time point.
3405
3406 Params:
3407 timePoint = The time point to check whether this interval is after
3408 it.
3409
3410 Example:
3411 --------------------
3412 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24)));
3413 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5)));
3414 --------------------
3415 +/
3416 bool isAfter(in TP timePoint) const pure nothrow
3417 {
3418 return timePoint < _begin;
3419 }
3420
3421
3422 /++
3423 Whether this interval is after the given interval and does not intersect
3424 it.
3425
3426 Params:
3427 interval = The interval to check against this interval.
3428
3429 Throws:
3430 $(REF DateTimeException,std,datetime,date) if the given interval
3431 is empty.
3432
3433 Example:
3434 --------------------
3435 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
3436 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
3437
3438 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
3439 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
3440
3441 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
3442 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
3443 --------------------
3444 +/
3445 bool isAfter(in Interval!TP interval) const pure
3446 {
3447 interval._enforceNotEmpty();
3448 return _begin >= interval._end;
3449 }
3450
3451
3452 /++
3453 Whether this interval is after the given interval and does not intersect
3454 it.
3455
3456 Always returns false because an interval going to positive infinity can
3457 never be after another interval going to positive infinity.
3458
3459 Params:
3460 interval = The interval to check against this interval.
3461
3462 Example:
3463 --------------------
3464 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
3465 PosInfInterval!Date(Date(1990, 1, 7))));
3466
3467 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
3468 PosInfInterval!Date(Date(1999, 5, 4))));
3469 --------------------
3470 +/
3471 bool isAfter(in PosInfInterval interval) const pure nothrow
3472 {
3473 return false;
3474 }
3475
3476
3477 /++
3478 Whether this interval is after the given interval and does not intersect
3479 it.
3480
3481 Params:
3482 interval = The interval to check against this interval.
3483
3484 Example:
3485 --------------------
3486 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
3487 NegInfInterval!Date(Date(1996, 1, 2))));
3488
3489 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
3490 NegInfInterval!Date(Date(2000, 7, 1))));
3491 --------------------
3492 +/
3493 bool isAfter(in NegInfInterval!TP interval) const pure nothrow
3494 {
3495 return _begin >= interval._end;
3496 }
3497
3498
3499 /++
3500 Whether the given interval overlaps this interval.
3501
3502 Params:
3503 interval = The interval to check for intersection with this interval.
3504
3505 Throws:
3506 $(REF DateTimeException,std,datetime,date) if the given interval
3507 is empty.
3508
3509 Example:
3510 --------------------
3511 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(
3512 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
3513
3514 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(
3515 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
3516
3517 assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(
3518 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
3519 --------------------
3520 +/
3521 bool intersects(in Interval!TP interval) const pure
3522 {
3523 interval._enforceNotEmpty();
3524 return interval._end > _begin;
3525 }
3526
3527
3528 /++
3529 Whether the given interval overlaps this interval.
3530
3531 Always returns true because two intervals going to positive infinity
3532 always overlap.
3533
3534 Params:
3535 interval = The interval to check for intersection with this
3536 interval.
3537
3538 Example:
3539 --------------------
3540 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(
3541 PosInfInterval!Date(Date(1990, 1, 7))));
3542
3543 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(
3544 PosInfInterval!Date(Date(1999, 5, 4))));
3545 --------------------
3546 +/
3547 bool intersects(in PosInfInterval interval) const pure nothrow
3548 {
3549 return true;
3550 }
3551
3552
3553 /++
3554 Whether the given interval overlaps this interval.
3555
3556 Params:
3557 interval = The interval to check for intersection with this
3558 interval.
3559
3560 Example:
3561 --------------------
3562 assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(
3563 NegInfInterval!Date(Date(1996, 1, 2))));
3564
3565 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(
3566 NegInfInterval!Date(Date(2000, 7, 1))));
3567 --------------------
3568 +/
3569 bool intersects(in NegInfInterval!TP interval) const pure nothrow
3570 {
3571 return _begin < interval._end;
3572 }
3573
3574
3575 /++
3576 Returns the intersection of two intervals
3577
3578 Params:
3579 interval = The interval to intersect with this interval.
3580
3581 Throws:
3582 $(REF DateTimeException,std,datetime,date) if the two intervals do
3583 not intersect or if the given interval is empty.
3584
3585 Example:
3586 --------------------
3587 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(
3588 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
3589 Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2)));
3590
3591 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(
3592 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==
3593 Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17)));
3594 --------------------
3595 +/
3596 Interval!TP intersection(in Interval!TP interval) const
3597 {
3598 import std.format : format;
3599
3600 enforce(this.intersects(interval),
3601 new DateTimeException(format("%s and %s do not intersect.", this, interval)));
3602
3603 auto begin = _begin > interval._begin ? _begin : interval._begin;
3604
3605 return Interval!TP(begin, interval._end);
3606 }
3607
3608
3609 /++
3610 Returns the intersection of two intervals
3611
3612 Params:
3613 interval = The interval to intersect with this interval.
3614
3615 Example:
3616 --------------------
3617 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(
3618 PosInfInterval!Date(Date(1990, 7, 6))) ==
3619 PosInfInterval!Date(Date(1996, 1 , 2)));
3620
3621 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(
3622 PosInfInterval!Date(Date(1999, 1, 12))) ==
3623 PosInfInterval!Date(Date(1999, 1 , 12)));
3624 --------------------
3625 +/
3626 PosInfInterval intersection(in PosInfInterval interval) const pure nothrow
3627 {
3628 return PosInfInterval(_begin < interval._begin ? interval._begin : _begin);
3629 }
3630
3631
3632 /++
3633 Returns the intersection of two intervals
3634
3635 Params:
3636 interval = The interval to intersect with this interval.
3637
3638 Throws:
3639 $(REF DateTimeException,std,datetime,date) if the two intervals do
3640 not intersect.
3641
3642 Example:
3643 --------------------
3644 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(
3645 NegInfInterval!Date(Date(1999, 7, 6))) ==
3646 Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6)));
3647
3648 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(
3649 NegInfInterval!Date(Date(2013, 1, 12))) ==
3650 Interval!Date(Date(1996, 1 , 2), Date(2013, 1, 12)));
3651 --------------------
3652 +/
3653 Interval!TP intersection(in NegInfInterval!TP interval) const
3654 {
3655 import std.format : format;
3656
3657 enforce(this.intersects(interval),
3658 new DateTimeException(format("%s and %s do not intersect.", this, interval)));
3659
3660 return Interval!TP(_begin, interval._end);
3661 }
3662
3663
3664 /++
3665 Whether the given interval is adjacent to this interval.
3666
3667 Params:
3668 interval = The interval to check whether its adjecent to this
3669 interval.
3670
3671 Throws:
3672 $(REF DateTimeException,std,datetime,date) if the given interval
3673 is empty.
3674
3675 Example:
3676 --------------------
3677 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(
3678 Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
3679
3680 assert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent(
3681 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
3682 --------------------
3683 +/
3684 bool isAdjacent(in Interval!TP interval) const pure
3685 {
3686 interval._enforceNotEmpty();
3687 return _begin == interval._end;
3688 }
3689
3690
3691 /++
3692 Whether the given interval is adjacent to this interval.
3693
3694 Always returns false because two intervals going to positive infinity
3695 can never be adjacent to one another.
3696
3697 Params:
3698 interval = The interval to check whether its adjecent to this
3699 interval.
3700
3701 Example:
3702 --------------------
3703 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(
3704 PosInfInterval!Date(Date(1990, 1, 7))));
3705
3706 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(
3707 PosInfInterval!Date(Date(1996, 1, 2))));
3708 --------------------
3709 +/
3710 bool isAdjacent(in PosInfInterval interval) const pure nothrow
3711 {
3712 return false;
3713 }
3714
3715
3716 /++
3717 Whether the given interval is adjacent to this interval.
3718
3719 Params:
3720 interval = The interval to check whether its adjecent to this
3721 interval.
3722
3723 Example:
3724 --------------------
3725 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(
3726 NegInfInterval!Date(Date(1996, 1, 2))));
3727
3728 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(
3729 NegInfInterval!Date(Date(2000, 7, 1))));
3730 --------------------
3731 +/
3732 bool isAdjacent(in NegInfInterval!TP interval) const pure nothrow
3733 {
3734 return _begin == interval._end;
3735 }
3736
3737
3738 /++
3739 Returns the union of two intervals
3740
3741 Params:
3742 interval = The interval to merge with this interval.
3743
3744 Throws:
3745 $(REF DateTimeException,std,datetime,date) if the two intervals do
3746 not intersect and are not adjacent or if the given interval is
3747 empty.
3748
3749 Note:
3750 There is no overload for $(D merge) which takes a
3751 $(D NegInfInterval), because an interval
3752 going from negative infinity to positive infinity
3753 is not possible.
3754
3755 Example:
3756 --------------------
3757 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(
3758 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
3759 PosInfInterval!Date(Date(1990, 7 , 6)));
3760
3761 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(
3762 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==
3763 PosInfInterval!Date(Date(1996, 1 , 2)));
3764 --------------------
3765 +/
3766 PosInfInterval merge(in Interval!TP interval) const
3767 {
3768 import std.format : format;
3769
3770 enforce(this.isAdjacent(interval) || this.intersects(interval),
3771 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval)));
3772
3773 return PosInfInterval(_begin < interval._begin ? _begin : interval._begin);
3774 }
3775
3776
3777 /++
3778 Returns the union of two intervals
3779
3780 Params:
3781 interval = The interval to merge with this interval.
3782
3783 Note:
3784 There is no overload for $(D merge) which takes a
3785 $(D NegInfInterval), because an interval
3786 going from negative infinity to positive infinity
3787 is not possible.
3788
3789 Example:
3790 --------------------
3791 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(
3792 PosInfInterval!Date(Date(1990, 7, 6))) ==
3793 PosInfInterval!Date(Date(1990, 7 , 6)));
3794
3795 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(
3796 PosInfInterval!Date(Date(1999, 1, 12))) ==
3797 PosInfInterval!Date(Date(1996, 1 , 2)));
3798 --------------------
3799 +/
3800 PosInfInterval merge(in PosInfInterval interval) const pure nothrow
3801 {
3802 return PosInfInterval(_begin < interval._begin ? _begin : interval._begin);
3803 }
3804
3805
3806 /++
3807 Returns an interval that covers from the earliest time point of two
3808 intervals up to (but not including) the latest time point of two
3809 intervals.
3810
3811 Params:
3812 interval = The interval to create a span together with this
3813 interval.
3814
3815 Throws:
3816 $(REF DateTimeException,std,datetime,date) if the given interval
3817 is empty.
3818
3819 Note:
3820 There is no overload for $(D span) which takes a
3821 $(D NegInfInterval), because an interval
3822 going from negative infinity to positive infinity
3823 is not possible.
3824
3825 Example:
3826 --------------------
3827 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(
3828 Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) ==
3829 PosInfInterval!Date(Date(500, 8, 9)));
3830
3831 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(
3832 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
3833 PosInfInterval!Date(Date(1990, 7 , 6)));
3834
3835 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(
3836 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==
3837 PosInfInterval!Date(Date(1996, 1 , 2)));
3838 --------------------
3839 +/
3840 PosInfInterval span(in Interval!TP interval) const pure
3841 {
3842 interval._enforceNotEmpty();
3843 return PosInfInterval(_begin < interval._begin ? _begin : interval._begin);
3844 }
3845
3846
3847 /++
3848 Returns an interval that covers from the earliest time point of two
3849 intervals up to (but not including) the latest time point of two
3850 intervals.
3851
3852 Params:
3853 interval = The interval to create a span together with this
3854 interval.
3855
3856 Note:
3857 There is no overload for $(D span) which takes a
3858 $(D NegInfInterval), because an interval
3859 going from negative infinity to positive infinity
3860 is not possible.
3861
3862 Example:
3863 --------------------
3864 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(
3865 PosInfInterval!Date(Date(1990, 7, 6))) ==
3866 PosInfInterval!Date(Date(1990, 7 , 6)));
3867
3868 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(
3869 PosInfInterval!Date(Date(1999, 1, 12))) ==
3870 PosInfInterval!Date(Date(1996, 1 , 2)));
3871 --------------------
3872 +/
3873 PosInfInterval span(in PosInfInterval interval) const pure nothrow
3874 {
3875 return PosInfInterval(_begin < interval._begin ? _begin : interval._begin);
3876 }
3877
3878
3879 /++
3880 Shifts the $(D begin) of this interval forward or backwards in time by
3881 the given duration (a positive duration shifts the interval forward; a
3882 negative duration shifts it backward). Effectively, it does
3883 $(D begin += duration).
3884
3885 Params:
3886 duration = The duration to shift the interval by.
3887
3888 Example:
3889 --------------------
3890 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
3891 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
3892
3893 interval1.shift(dur!"days"(50));
3894 assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21)));
3895
3896 interval2.shift(dur!"days"(-50));
3897 assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13)));
3898 --------------------
3899 +/
3900 void shift(D)(D duration) pure nothrow
3901 if (__traits(compiles, begin + duration))
3902 {
3903 _begin += duration;
3904 }
3905
3906
3907 static if (__traits(compiles, begin.add!"months"(1)) &&
3908 __traits(compiles, begin.add!"years"(1)))
3909 {
3910 /++
3911 Shifts the $(D begin) of this interval forward or backwards in time
3912 by the given number of years and/or months (a positive number of
3913 years and months shifts the interval forward; a negative number
3914 shifts it backward). It adds the years the given years and months to
3915 $(D begin). It effectively calls $(D add!"years"()) and then
3916 $(D add!"months"()) on $(D begin) with the given number of years and
3917 months.
3918
3919 Params:
3920 years = The number of years to shift the interval by.
3921 months = The number of months to shift the interval by.
3922 allowOverflow = Whether the days should be allowed to overflow
3923 on $(D begin), causing its month to increment.
3924
3925 Throws:
3926 $(REF DateTimeException,std,datetime,date) if this interval is
3927 empty or if the resulting interval would be invalid.
3928
3929 Example:
3930 --------------------
3931 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
3932 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
3933
3934 interval1.shift(dur!"days"(50));
3935 assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21)));
3936
3937 interval2.shift(dur!"days"(-50));
3938 assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13)));
3939 --------------------
3940 +/
3941 void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
3942 if (isIntegral!T)
3943 {
3944 auto begin = _begin;
3945
3946 begin.add!"years"(years, allowOverflow);
3947 begin.add!"months"(months, allowOverflow);
3948
3949 _begin = begin;
3950 }
3951 }
3952
3953
3954 /++
3955 Expands the interval backwards in time. Effectively, it does
3956 $(D begin -= duration).
3957
3958 Params:
3959 duration = The duration to expand the interval by.
3960
3961 Example:
3962 --------------------
3963 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
3964 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
3965
3966 interval1.expand(dur!"days"(2));
3967 assert(interval1 == PosInfInterval!Date(Date(1995, 12, 31)));
3968
3969 interval2.expand(dur!"days"(-2));
3970 assert(interval2 == PosInfInterval!Date(Date(1996, 1, 4)));
3971 --------------------
3972 +/
3973 void expand(D)(D duration) pure nothrow
3974 if (__traits(compiles, begin + duration))
3975 {
3976 _begin -= duration;
3977 }
3978
3979
3980 static if (__traits(compiles, begin.add!"months"(1)) &&
3981 __traits(compiles, begin.add!"years"(1)))
3982 {
3983 /++
3984 Expands the interval forwards and/or backwards in time. Effectively,
3985 it subtracts the given number of months/years from $(D begin).
3986
3987 Params:
3988 years = The number of years to expand the interval by.
3989 months = The number of months to expand the interval by.
3990 allowOverflow = Whether the days should be allowed to overflow
3991 on $(D begin), causing its month to increment.
3992
3993 Throws:
3994 $(REF DateTimeException,std,datetime,date) if this interval is
3995 empty or if the resulting interval would be invalid.
3996
3997 Example:
3998 --------------------
3999 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
4000 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
4001
4002 interval1.expand(2);
4003 assert(interval1 == PosInfInterval!Date(Date(1994, 1, 2)));
4004
4005 interval2.expand(-2);
4006 assert(interval2 == PosInfInterval!Date(Date(1998, 1, 2)));
4007 --------------------
4008 +/
4009 void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
4010 if (isIntegral!T)
4011 {
4012 auto begin = _begin;
4013
4014 begin.add!"years"(-years, allowOverflow);
4015 begin.add!"months"(-months, allowOverflow);
4016
4017 _begin = begin;
4018 }
4019 }
4020
4021
4022 /++
4023 Returns a range which iterates forward over the interval, starting
4024 at $(D begin), using $(D_PARAM func) to generate each successive time
4025 point.
4026
4027 The range's $(D front) is the interval's $(D begin). $(D_PARAM func) is
4028 used to generate the next $(D front) when $(D popFront) is called. If
4029 $(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called
4030 before the range is returned (so that $(D front) is a time point which
4031 $(D_PARAM func) would generate).
4032
4033 If $(D_PARAM func) ever generates a time point less than or equal to the
4034 current $(D front) of the range, then a
4035 $(REF DateTimeException,std,datetime,date) will be thrown.
4036
4037 There are helper functions in this module which generate common
4038 delegates to pass to $(D fwdRange). Their documentation starts with
4039 "Range-generating function," to make them easily searchable.
4040
4041 Params:
4042 func = The function used to generate the time points of the
4043 range over the interval.
4044 popFirst = Whether $(D popFront) should be called on the range
4045 before returning it.
4046
4047 Throws:
4048 $(REF DateTimeException,std,datetime,date) if this interval is
4049 empty.
4050
4051 Warning:
4052 $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func)
4053 would be a function pointer to a pure function, but forcing
4054 $(D_PARAM func) to be pure is far too restrictive to be useful, and
4055 in order to have the ease of use of having functions which generate
4056 functions to pass to $(D fwdRange), $(D_PARAM func) must be a
4057 delegate.
4058
4059 If $(D_PARAM func) retains state which changes as it is called, then
4060 some algorithms will not work correctly, because the range's
4061 $(D save) will have failed to have really saved the range's state.
4062 To avoid such bugs, don't pass a delegate which is
4063 not logically pure to $(D fwdRange). If $(D_PARAM func) is given the
4064 same time point with two different calls, it must return the same
4065 result both times.
4066
4067 Of course, none of the functions in this module have this problem,
4068 so it's only relevant for custom delegates.
4069
4070 Example:
4071 --------------------
4072 auto interval = PosInfInterval!Date(Date(2010, 9, 1));
4073 auto func = delegate (in Date date) //For iterating over even-numbered days.
4074 {
4075 if ((date.day & 1) == 0)
4076 return date + dur!"days"(2);
4077
4078 return date + dur!"days"(1);
4079 };
4080 auto range = interval.fwdRange(func);
4081
4082 //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2).
4083 assert(range.front == Date(2010, 9, 1));
4084
4085 range.popFront();
4086 assert(range.front == Date(2010, 9, 2));
4087
4088 range.popFront();
4089 assert(range.front == Date(2010, 9, 4));
4090
4091 range.popFront();
4092 assert(range.front == Date(2010, 9, 6));
4093
4094 range.popFront();
4095 assert(range.front == Date(2010, 9, 8));
4096
4097 range.popFront();
4098 assert(!range.empty);
4099 --------------------
4100 +/
4101 PosInfIntervalRange!(TP) fwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const
4102 {
4103 auto range = PosInfIntervalRange!(TP)(this, func);
4104
4105 if (popFirst == PopFirst.yes)
4106 range.popFront();
4107
4108 return range;
4109 }
4110
4111
4112 /+
4113 Converts this interval to a string.
4114 +/
4115 //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
4116 //have versions of toString() with extra modifiers, so we define one version
4117 //with modifiers and one without.
4118 string toString()
4119 {
4120 return _toStringImpl();
4121 }
4122
4123
4124 /++
4125 Converts this interval to a string.
4126 +/
4127 //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
4128 //have versions of toString() with extra modifiers, so we define one version
4129 //with modifiers and one without.
4130 string toString() const nothrow
4131 {
4132 return _toStringImpl();
4133 }
4134
4135 private:
4136
4137 /+
4138 Since we have two versions of toString(), we have _toStringImpl()
4139 so that they can share implementations.
4140 +/
4141 string _toStringImpl() const nothrow
4142 {
4143 import std.format : format;
4144 try
4145 return format("[%s - ∞)", _begin);
4146 catch (Exception e)
4147 assert(0, "format() threw.");
4148 }
4149
4150
4151 TP _begin;
4152 }
4153
4154 //Test PosInfInterval's constructor.
4155 @safe unittest
4156 {
4157 import std.datetime.date;
4158 import std.datetime.systime;
4159
4160 PosInfInterval!Date(Date.init);
4161 PosInfInterval!TimeOfDay(TimeOfDay.init);
4162 PosInfInterval!DateTime(DateTime.init);
4163 PosInfInterval!SysTime(SysTime(0));
4164
4165 //Verify Examples.
4166 auto interval = PosInfInterval!Date(Date(1996, 1, 2));
4167 }
4168
4169 //Test PosInfInterval's begin.
4170 @safe unittest
4171 {
4172 import std.datetime.date;
4173
4174 assert(PosInfInterval!Date(Date(1, 1, 1)).begin == Date(1, 1, 1));
4175 assert(PosInfInterval!Date(Date(2010, 1, 1)).begin == Date(2010, 1, 1));
4176 assert(PosInfInterval!Date(Date(1997, 12, 31)).begin == Date(1997, 12, 31));
4177
4178 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4179 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4180 assert(cPosInfInterval.begin != Date.init);
4181 assert(iPosInfInterval.begin != Date.init);
4182
4183 //Verify Examples.
4184 assert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2));
4185 }
4186
4187 //Test PosInfInterval's empty.
4188 @safe unittest
4189 {
4190 import std.datetime.date;
4191 import std.datetime.systime;
4192
4193 assert(!PosInfInterval!Date(Date(2010, 1, 1)).empty);
4194 assert(!PosInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty);
4195 assert(!PosInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty);
4196 assert(!PosInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty);
4197
4198 const cPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4199 immutable iPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4200 assert(!cPosInfInterval.empty);
4201 assert(!iPosInfInterval.empty);
4202
4203 //Verify Examples.
4204 assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty);
4205 }
4206
4207 //Test PosInfInterval's contains(time point).
4208 @safe unittest
4209 {
4210 import std.datetime.date;
4211
4212 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4213
4214 assert(!posInfInterval.contains(Date(2009, 7, 4)));
4215 assert(!posInfInterval.contains(Date(2010, 7, 3)));
4216 assert(posInfInterval.contains(Date(2010, 7, 4)));
4217 assert(posInfInterval.contains(Date(2010, 7, 5)));
4218 assert(posInfInterval.contains(Date(2011, 7, 1)));
4219 assert(posInfInterval.contains(Date(2012, 1, 6)));
4220 assert(posInfInterval.contains(Date(2012, 1, 7)));
4221 assert(posInfInterval.contains(Date(2012, 1, 8)));
4222 assert(posInfInterval.contains(Date(2013, 1, 7)));
4223
4224 const cdate = Date(2010, 7, 6);
4225 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4226 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4227 assert(posInfInterval.contains(cdate));
4228 assert(cPosInfInterval.contains(cdate));
4229 assert(iPosInfInterval.contains(cdate));
4230
4231 //Verify Examples.
4232 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24)));
4233 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5)));
4234 }
4235
4236 //Test PosInfInterval's contains(Interval).
4237 @safe unittest
4238 {
4239 import std.datetime.date;
4240
4241 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4242
4243 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
4244 {
4245 posInfInterval.contains(interval);
4246 }
4247
4248 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
4249
4250 assert(posInfInterval.contains(posInfInterval));
4251 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
4252 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
4253 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
4254 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
4255 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
4256 assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
4257 assert(posInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
4258 assert(posInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
4259 assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
4260 assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
4261 assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
4262 assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
4263
4264 assert(!posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 3))));
4265 assert(posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 4))));
4266 assert(posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 5))));
4267 assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 6))));
4268 assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 7))));
4269 assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 8))));
4270
4271 assert(PosInfInterval!Date(Date(2010, 7, 3)).contains(posInfInterval));
4272 assert(PosInfInterval!Date(Date(2010, 7, 4)).contains(posInfInterval));
4273 assert(!PosInfInterval!Date(Date(2010, 7, 5)).contains(posInfInterval));
4274 assert(!PosInfInterval!Date(Date(2012, 1, 6)).contains(posInfInterval));
4275 assert(!PosInfInterval!Date(Date(2012, 1, 7)).contains(posInfInterval));
4276 assert(!PosInfInterval!Date(Date(2012, 1, 8)).contains(posInfInterval));
4277
4278 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 3))));
4279 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 4))));
4280 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 5))));
4281 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 6))));
4282 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 7))));
4283 assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 8))));
4284
4285 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4286 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4287 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4288 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4289 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4290 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4291 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4292 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4293 assert(posInfInterval.contains(interval));
4294 assert(posInfInterval.contains(cInterval));
4295 assert(posInfInterval.contains(iInterval));
4296 assert(posInfInterval.contains(posInfInterval));
4297 assert(posInfInterval.contains(cPosInfInterval));
4298 assert(posInfInterval.contains(iPosInfInterval));
4299 assert(!posInfInterval.contains(negInfInterval));
4300 assert(!posInfInterval.contains(cNegInfInterval));
4301 assert(!posInfInterval.contains(iNegInfInterval));
4302 assert(cPosInfInterval.contains(interval));
4303 assert(cPosInfInterval.contains(cInterval));
4304 assert(cPosInfInterval.contains(iInterval));
4305 assert(cPosInfInterval.contains(posInfInterval));
4306 assert(cPosInfInterval.contains(cPosInfInterval));
4307 assert(cPosInfInterval.contains(iPosInfInterval));
4308 assert(!cPosInfInterval.contains(negInfInterval));
4309 assert(!cPosInfInterval.contains(cNegInfInterval));
4310 assert(!cPosInfInterval.contains(iNegInfInterval));
4311 assert(iPosInfInterval.contains(interval));
4312 assert(iPosInfInterval.contains(cInterval));
4313 assert(iPosInfInterval.contains(iInterval));
4314 assert(iPosInfInterval.contains(posInfInterval));
4315 assert(iPosInfInterval.contains(cPosInfInterval));
4316 assert(iPosInfInterval.contains(iPosInfInterval));
4317 assert(!iPosInfInterval.contains(negInfInterval));
4318 assert(!iPosInfInterval.contains(cNegInfInterval));
4319 assert(!iPosInfInterval.contains(iNegInfInterval));
4320
4321 //Verify Examples.
4322 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
4323 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
4324 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));
4325
4326 assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(PosInfInterval!Date(Date(1999, 5, 4))));
4327 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(PosInfInterval!Date(Date(1995, 7, 2))));
4328
4329 assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(NegInfInterval!Date(Date(1996, 5, 4))));
4330 }
4331
4332 //Test PosInfInterval's isBefore(time point).
4333 @safe unittest
4334 {
4335 import std.datetime.date;
4336
4337 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4338
4339 assert(!posInfInterval.isBefore(Date(2009, 7, 3)));
4340 assert(!posInfInterval.isBefore(Date(2010, 7, 3)));
4341 assert(!posInfInterval.isBefore(Date(2010, 7, 4)));
4342 assert(!posInfInterval.isBefore(Date(2010, 7, 5)));
4343 assert(!posInfInterval.isBefore(Date(2011, 7, 1)));
4344 assert(!posInfInterval.isBefore(Date(2012, 1, 6)));
4345 assert(!posInfInterval.isBefore(Date(2012, 1, 7)));
4346 assert(!posInfInterval.isBefore(Date(2012, 1, 8)));
4347 assert(!posInfInterval.isBefore(Date(2013, 1, 7)));
4348
4349 const cdate = Date(2010, 7, 6);
4350 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4351 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4352 assert(!posInfInterval.isBefore(cdate));
4353 assert(!cPosInfInterval.isBefore(cdate));
4354 assert(!iPosInfInterval.isBefore(cdate));
4355
4356 //Verify Examples.
4357 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24)));
4358 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5)));
4359 }
4360
4361 //Test PosInfInterval's isBefore(Interval).
4362 @safe unittest
4363 {
4364 import std.datetime.date;
4365
4366 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4367
4368 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
4369 {
4370 posInfInterval.isBefore(interval);
4371 }
4372
4373 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
4374
4375 assert(!posInfInterval.isBefore(posInfInterval));
4376 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
4377 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
4378 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
4379 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
4380 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
4381 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
4382 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
4383 assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
4384 assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
4385 assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
4386 assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
4387 assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
4388
4389 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 3))));
4390 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 4))));
4391 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 5))));
4392 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 6))));
4393 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 7))));
4394 assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 8))));
4395
4396 assert(!PosInfInterval!Date(Date(2010, 7, 3)).isBefore(posInfInterval));
4397 assert(!PosInfInterval!Date(Date(2010, 7, 4)).isBefore(posInfInterval));
4398 assert(!PosInfInterval!Date(Date(2010, 7, 5)).isBefore(posInfInterval));
4399 assert(!PosInfInterval!Date(Date(2012, 1, 6)).isBefore(posInfInterval));
4400 assert(!PosInfInterval!Date(Date(2012, 1, 7)).isBefore(posInfInterval));
4401 assert(!PosInfInterval!Date(Date(2012, 1, 8)).isBefore(posInfInterval));
4402
4403 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 3))));
4404 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 4))));
4405 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 5))));
4406 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 6))));
4407 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 7))));
4408 assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 8))));
4409
4410 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4411 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4412 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4413 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4414 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4415 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4416 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4417 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4418 assert(!posInfInterval.isBefore(interval));
4419 assert(!posInfInterval.isBefore(cInterval));
4420 assert(!posInfInterval.isBefore(iInterval));
4421 assert(!posInfInterval.isBefore(posInfInterval));
4422 assert(!posInfInterval.isBefore(cPosInfInterval));
4423 assert(!posInfInterval.isBefore(iPosInfInterval));
4424 assert(!posInfInterval.isBefore(negInfInterval));
4425 assert(!posInfInterval.isBefore(cNegInfInterval));
4426 assert(!posInfInterval.isBefore(iNegInfInterval));
4427 assert(!cPosInfInterval.isBefore(interval));
4428 assert(!cPosInfInterval.isBefore(cInterval));
4429 assert(!cPosInfInterval.isBefore(iInterval));
4430 assert(!cPosInfInterval.isBefore(posInfInterval));
4431 assert(!cPosInfInterval.isBefore(cPosInfInterval));
4432 assert(!cPosInfInterval.isBefore(iPosInfInterval));
4433 assert(!cPosInfInterval.isBefore(negInfInterval));
4434 assert(!cPosInfInterval.isBefore(cNegInfInterval));
4435 assert(!cPosInfInterval.isBefore(iNegInfInterval));
4436 assert(!iPosInfInterval.isBefore(interval));
4437 assert(!iPosInfInterval.isBefore(cInterval));
4438 assert(!iPosInfInterval.isBefore(iInterval));
4439 assert(!iPosInfInterval.isBefore(posInfInterval));
4440 assert(!iPosInfInterval.isBefore(cPosInfInterval));
4441 assert(!iPosInfInterval.isBefore(iPosInfInterval));
4442 assert(!iPosInfInterval.isBefore(negInfInterval));
4443 assert(!iPosInfInterval.isBefore(cNegInfInterval));
4444 assert(!iPosInfInterval.isBefore(iNegInfInterval));
4445
4446 //Verify Examples.
4447 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
4448 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
4449
4450 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(PosInfInterval!Date(Date(1992, 5, 4))));
4451 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(PosInfInterval!Date(Date(2013, 3, 7))));
4452
4453 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(NegInfInterval!Date(Date(1996, 5, 4))));
4454 }
4455
4456 //Test PosInfInterval's isAfter(time point).
4457 @safe unittest
4458 {
4459 import std.datetime.date;
4460
4461 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4462
4463 assert(posInfInterval.isAfter(Date(2009, 7, 3)));
4464 assert(posInfInterval.isAfter(Date(2010, 7, 3)));
4465 assert(!posInfInterval.isAfter(Date(2010, 7, 4)));
4466 assert(!posInfInterval.isAfter(Date(2010, 7, 5)));
4467 assert(!posInfInterval.isAfter(Date(2011, 7, 1)));
4468 assert(!posInfInterval.isAfter(Date(2012, 1, 6)));
4469 assert(!posInfInterval.isAfter(Date(2012, 1, 7)));
4470 assert(!posInfInterval.isAfter(Date(2012, 1, 8)));
4471 assert(!posInfInterval.isAfter(Date(2013, 1, 7)));
4472
4473 const cdate = Date(2010, 7, 6);
4474 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4475 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4476 assert(!posInfInterval.isAfter(cdate));
4477 assert(!cPosInfInterval.isAfter(cdate));
4478 assert(!iPosInfInterval.isAfter(cdate));
4479
4480 //Verify Examples.
4481 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24)));
4482 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5)));
4483 }
4484
4485 //Test PosInfInterval's isAfter(Interval).
4486 @safe unittest
4487 {
4488 import std.datetime.date;
4489
4490 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4491
4492 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
4493 {
4494 posInfInterval.isAfter(interval);
4495 }
4496
4497 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
4498
4499 assert(!posInfInterval.isAfter(posInfInterval));
4500 assert(posInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
4501 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
4502 assert(posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
4503 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
4504 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
4505 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
4506 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
4507 assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
4508 assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
4509 assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
4510 assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
4511 assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
4512
4513 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 3))));
4514 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 4))));
4515 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 5))));
4516 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 6))));
4517 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 7))));
4518 assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 8))));
4519
4520 assert(!PosInfInterval!Date(Date(2010, 7, 3)).isAfter(posInfInterval));
4521 assert(!PosInfInterval!Date(Date(2010, 7, 4)).isAfter(posInfInterval));
4522 assert(!PosInfInterval!Date(Date(2010, 7, 5)).isAfter(posInfInterval));
4523 assert(!PosInfInterval!Date(Date(2012, 1, 6)).isAfter(posInfInterval));
4524 assert(!PosInfInterval!Date(Date(2012, 1, 7)).isAfter(posInfInterval));
4525 assert(!PosInfInterval!Date(Date(2012, 1, 8)).isAfter(posInfInterval));
4526
4527 assert(posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 3))));
4528 assert(posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 4))));
4529 assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 5))));
4530 assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 6))));
4531 assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 7))));
4532 assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 8))));
4533
4534 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4535 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4536 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4537 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4538 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4539 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4540 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4541 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4542 assert(!posInfInterval.isAfter(interval));
4543 assert(!posInfInterval.isAfter(cInterval));
4544 assert(!posInfInterval.isAfter(iInterval));
4545 assert(!posInfInterval.isAfter(posInfInterval));
4546 assert(!posInfInterval.isAfter(cPosInfInterval));
4547 assert(!posInfInterval.isAfter(iPosInfInterval));
4548 assert(!posInfInterval.isAfter(negInfInterval));
4549 assert(!posInfInterval.isAfter(cNegInfInterval));
4550 assert(!posInfInterval.isAfter(iNegInfInterval));
4551 assert(!cPosInfInterval.isAfter(interval));
4552 assert(!cPosInfInterval.isAfter(cInterval));
4553 assert(!cPosInfInterval.isAfter(iInterval));
4554 assert(!cPosInfInterval.isAfter(posInfInterval));
4555 assert(!cPosInfInterval.isAfter(cPosInfInterval));
4556 assert(!cPosInfInterval.isAfter(iPosInfInterval));
4557 assert(!cPosInfInterval.isAfter(negInfInterval));
4558 assert(!cPosInfInterval.isAfter(cNegInfInterval));
4559 assert(!cPosInfInterval.isAfter(iNegInfInterval));
4560 assert(!iPosInfInterval.isAfter(interval));
4561 assert(!iPosInfInterval.isAfter(cInterval));
4562 assert(!iPosInfInterval.isAfter(iInterval));
4563 assert(!iPosInfInterval.isAfter(posInfInterval));
4564 assert(!iPosInfInterval.isAfter(cPosInfInterval));
4565 assert(!iPosInfInterval.isAfter(iPosInfInterval));
4566 assert(!iPosInfInterval.isAfter(negInfInterval));
4567 assert(!iPosInfInterval.isAfter(cNegInfInterval));
4568 assert(!iPosInfInterval.isAfter(iNegInfInterval));
4569
4570 //Verify Examples.
4571 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
4572 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
4573 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
4574
4575 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(PosInfInterval!Date(Date(1990, 1, 7))));
4576 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(PosInfInterval!Date(Date(1999, 5, 4))));
4577
4578 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(NegInfInterval!Date(Date(1996, 1, 2))));
4579 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(NegInfInterval!Date(Date(2000, 7, 1))));
4580 }
4581
4582 //Test PosInfInterval's intersects().
4583 @safe unittest
4584 {
4585 import std.datetime.date;
4586
4587 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4588
4589 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
4590 {
4591 posInfInterval.intersects(interval);
4592 }
4593
4594 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
4595
4596 assert(posInfInterval.intersects(posInfInterval));
4597 assert(!posInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
4598 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
4599 assert(!posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
4600 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
4601 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
4602 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
4603 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
4604 assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
4605 assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
4606 assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
4607 assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
4608 assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
4609
4610 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 3))));
4611 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 4))));
4612 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 5))));
4613 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 6))));
4614 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 7))));
4615 assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 8))));
4616
4617 assert(PosInfInterval!Date(Date(2010, 7, 3)).intersects(posInfInterval));
4618 assert(PosInfInterval!Date(Date(2010, 7, 4)).intersects(posInfInterval));
4619 assert(PosInfInterval!Date(Date(2010, 7, 5)).intersects(posInfInterval));
4620 assert(PosInfInterval!Date(Date(2012, 1, 6)).intersects(posInfInterval));
4621 assert(PosInfInterval!Date(Date(2012, 1, 7)).intersects(posInfInterval));
4622 assert(PosInfInterval!Date(Date(2012, 1, 8)).intersects(posInfInterval));
4623
4624 assert(!posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 3))));
4625 assert(!posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 4))));
4626 assert(posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 5))));
4627 assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 6))));
4628 assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 7))));
4629 assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 8))));
4630
4631 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4632 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4633 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4634 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4635 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4636 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4637 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4638 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4639 assert(posInfInterval.intersects(interval));
4640 assert(posInfInterval.intersects(cInterval));
4641 assert(posInfInterval.intersects(iInterval));
4642 assert(posInfInterval.intersects(posInfInterval));
4643 assert(posInfInterval.intersects(cPosInfInterval));
4644 assert(posInfInterval.intersects(iPosInfInterval));
4645 assert(posInfInterval.intersects(negInfInterval));
4646 assert(posInfInterval.intersects(cNegInfInterval));
4647 assert(posInfInterval.intersects(iNegInfInterval));
4648 assert(cPosInfInterval.intersects(interval));
4649 assert(cPosInfInterval.intersects(cInterval));
4650 assert(cPosInfInterval.intersects(iInterval));
4651 assert(cPosInfInterval.intersects(posInfInterval));
4652 assert(cPosInfInterval.intersects(cPosInfInterval));
4653 assert(cPosInfInterval.intersects(iPosInfInterval));
4654 assert(cPosInfInterval.intersects(negInfInterval));
4655 assert(cPosInfInterval.intersects(cNegInfInterval));
4656 assert(cPosInfInterval.intersects(iNegInfInterval));
4657 assert(iPosInfInterval.intersects(interval));
4658 assert(iPosInfInterval.intersects(cInterval));
4659 assert(iPosInfInterval.intersects(iInterval));
4660 assert(iPosInfInterval.intersects(posInfInterval));
4661 assert(iPosInfInterval.intersects(cPosInfInterval));
4662 assert(iPosInfInterval.intersects(iPosInfInterval));
4663 assert(iPosInfInterval.intersects(negInfInterval));
4664 assert(iPosInfInterval.intersects(cNegInfInterval));
4665 assert(iPosInfInterval.intersects(iNegInfInterval));
4666
4667 //Verify Examples.
4668 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
4669 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
4670 assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
4671
4672 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(PosInfInterval!Date(Date(1990, 1, 7))));
4673 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(PosInfInterval!Date(Date(1999, 5, 4))));
4674
4675 assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(NegInfInterval!Date(Date(1996, 1, 2))));
4676 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(NegInfInterval!Date(Date(2000, 7, 1))));
4677 }
4678
4679 //Test PosInfInterval's intersection().
4680 @safe unittest
4681 {
4682 import std.datetime.date;
4683
4684 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4685
testInterval(I,J)4686 static void testInterval(I, J)(in I interval1, in J interval2)
4687 {
4688 interval1.intersection(interval2);
4689 }
4690
4691 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
4692
4693 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
4694 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
4695
4696 assertThrown!DateTimeException(testInterval(posInfInterval, NegInfInterval!Date(Date(2010, 7, 3))));
4697 assertThrown!DateTimeException(testInterval(posInfInterval, NegInfInterval!Date(Date(2010, 7, 4))));
4698
4699 assert(posInfInterval.intersection(posInfInterval) == posInfInterval);
4700 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==
4701 Interval!Date(Date(2010, 7, 4), Date(2013, 7, 3)));
4702 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==
4703 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));
4704 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==
4705 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
4706 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==
4707 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
4708 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==
4709 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)));
4710 assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==
4711 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));
4712 assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==
4713 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
4714 assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==
4715 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)));
4716 assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==
4717 Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)));
4718 assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) ==
4719 Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)));
4720
4721 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 4)));
4722 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4)));
4723 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 5)));
4724 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2012, 1, 6)));
4725 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2012, 1, 7)));
4726 assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2012, 1, 8)));
4727
4728 assert(PosInfInterval!Date(Date(2010, 7, 3)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));
4729 assert(PosInfInterval!Date(Date(2010, 7, 4)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));
4730 assert(PosInfInterval!Date(Date(2010, 7, 5)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 5)));
4731 assert(PosInfInterval!Date(Date(2012, 1, 6)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 6)));
4732 assert(PosInfInterval!Date(Date(2012, 1, 7)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 7)));
4733 assert(PosInfInterval!Date(Date(2012, 1, 8)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 8)));
4734
4735 assert(posInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) ==
4736 Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));
4737 assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) ==
4738 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6)));
4739 assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) ==
4740 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
4741 assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) ==
4742 Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
4743
4744 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4745 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4746 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4747 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4748 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4749 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4750 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4751 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4752 assert(!posInfInterval.intersection(interval).empty);
4753 assert(!posInfInterval.intersection(cInterval).empty);
4754 assert(!posInfInterval.intersection(iInterval).empty);
4755 assert(!posInfInterval.intersection(posInfInterval).empty);
4756 assert(!posInfInterval.intersection(cPosInfInterval).empty);
4757 assert(!posInfInterval.intersection(iPosInfInterval).empty);
4758 assert(!posInfInterval.intersection(negInfInterval).empty);
4759 assert(!posInfInterval.intersection(cNegInfInterval).empty);
4760 assert(!posInfInterval.intersection(iNegInfInterval).empty);
4761 assert(!cPosInfInterval.intersection(interval).empty);
4762 assert(!cPosInfInterval.intersection(cInterval).empty);
4763 assert(!cPosInfInterval.intersection(iInterval).empty);
4764 assert(!cPosInfInterval.intersection(posInfInterval).empty);
4765 assert(!cPosInfInterval.intersection(cPosInfInterval).empty);
4766 assert(!cPosInfInterval.intersection(iPosInfInterval).empty);
4767 assert(!cPosInfInterval.intersection(negInfInterval).empty);
4768 assert(!cPosInfInterval.intersection(cNegInfInterval).empty);
4769 assert(!cPosInfInterval.intersection(iNegInfInterval).empty);
4770 assert(!iPosInfInterval.intersection(interval).empty);
4771 assert(!iPosInfInterval.intersection(cInterval).empty);
4772 assert(!iPosInfInterval.intersection(iInterval).empty);
4773 assert(!iPosInfInterval.intersection(posInfInterval).empty);
4774 assert(!iPosInfInterval.intersection(cPosInfInterval).empty);
4775 assert(!iPosInfInterval.intersection(iPosInfInterval).empty);
4776 assert(!iPosInfInterval.intersection(negInfInterval).empty);
4777 assert(!iPosInfInterval.intersection(cNegInfInterval).empty);
4778 assert(!iPosInfInterval.intersection(iNegInfInterval).empty);
4779
4780 //Verify Examples.
4781 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
4782 Interval!Date(Date(1996, 1, 2), Date(2000, 8, 2)));
4783 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==
4784 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)));
4785
4786 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) ==
4787 PosInfInterval!Date(Date(1996, 1, 2)));
4788 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) ==
4789 PosInfInterval!Date(Date(1999, 1, 12)));
4790
4791 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) ==
4792 Interval!Date(Date(1996, 1, 2), Date(1999, 7, 6)));
4793 assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) ==
4794 Interval!Date(Date(1996, 1, 2), Date(2013, 1, 12)));
4795 }
4796
4797 //Test PosInfInterval's isAdjacent().
4798 @safe unittest
4799 {
4800 import std.datetime.date;
4801
4802 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4803
4804 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
4805 {
4806 posInfInterval.isAdjacent(interval);
4807 }
4808
4809 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
4810
4811 assert(!posInfInterval.isAdjacent(posInfInterval));
4812 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
4813 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
4814 assert(posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
4815 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
4816 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
4817 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
4818 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
4819 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
4820 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
4821 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
4822 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
4823 assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
4824
4825 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3))));
4826 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4))));
4827 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5))));
4828 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6))));
4829 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7))));
4830 assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8))));
4831
4832 assert(!PosInfInterval!Date(Date(2010, 7, 3)).isAdjacent(posInfInterval));
4833 assert(!PosInfInterval!Date(Date(2010, 7, 4)).isAdjacent(posInfInterval));
4834 assert(!PosInfInterval!Date(Date(2010, 7, 5)).isAdjacent(posInfInterval));
4835 assert(!PosInfInterval!Date(Date(2012, 1, 6)).isAdjacent(posInfInterval));
4836 assert(!PosInfInterval!Date(Date(2012, 1, 7)).isAdjacent(posInfInterval));
4837 assert(!PosInfInterval!Date(Date(2012, 1, 8)).isAdjacent(posInfInterval));
4838
4839 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3))));
4840 assert(posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4))));
4841 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5))));
4842 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6))));
4843 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7))));
4844 assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8))));
4845
4846 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4847 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4848 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4849 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4850 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4851 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4852 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4853 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4854 assert(!posInfInterval.isAdjacent(interval));
4855 assert(!posInfInterval.isAdjacent(cInterval));
4856 assert(!posInfInterval.isAdjacent(iInterval));
4857 assert(!posInfInterval.isAdjacent(posInfInterval));
4858 assert(!posInfInterval.isAdjacent(cPosInfInterval));
4859 assert(!posInfInterval.isAdjacent(iPosInfInterval));
4860 assert(!posInfInterval.isAdjacent(negInfInterval));
4861 assert(!posInfInterval.isAdjacent(cNegInfInterval));
4862 assert(!posInfInterval.isAdjacent(iNegInfInterval));
4863 assert(!cPosInfInterval.isAdjacent(interval));
4864 assert(!cPosInfInterval.isAdjacent(cInterval));
4865 assert(!cPosInfInterval.isAdjacent(iInterval));
4866 assert(!cPosInfInterval.isAdjacent(posInfInterval));
4867 assert(!cPosInfInterval.isAdjacent(cPosInfInterval));
4868 assert(!cPosInfInterval.isAdjacent(iPosInfInterval));
4869 assert(!cPosInfInterval.isAdjacent(negInfInterval));
4870 assert(!cPosInfInterval.isAdjacent(cNegInfInterval));
4871 assert(!cPosInfInterval.isAdjacent(iNegInfInterval));
4872 assert(!iPosInfInterval.isAdjacent(interval));
4873 assert(!iPosInfInterval.isAdjacent(cInterval));
4874 assert(!iPosInfInterval.isAdjacent(iInterval));
4875 assert(!iPosInfInterval.isAdjacent(posInfInterval));
4876 assert(!iPosInfInterval.isAdjacent(cPosInfInterval));
4877 assert(!iPosInfInterval.isAdjacent(iPosInfInterval));
4878 assert(!iPosInfInterval.isAdjacent(negInfInterval));
4879 assert(!iPosInfInterval.isAdjacent(cNegInfInterval));
4880 assert(!iPosInfInterval.isAdjacent(iNegInfInterval));
4881
4882 //Verify Examples.
4883 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
4884 assert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
4885
4886 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(PosInfInterval!Date(Date(1990, 1, 7))));
4887 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(PosInfInterval!Date(Date(1996, 1, 2))));
4888
4889 assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2))));
4890 assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(NegInfInterval!Date(Date(2000, 7, 1))));
4891 }
4892
4893 //Test PosInfInterval's merge().
4894 @safe unittest
4895 {
4896 import std.datetime.date;
4897
4898 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4899
4900 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
4901 {
4902 posInfInterval.merge(interval);
4903 }
4904
4905 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
4906
4907 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
4908
4909 assert(posInfInterval.merge(posInfInterval) == posInfInterval);
4910 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==
4911 PosInfInterval!Date(Date(2010, 7, 1)));
4912 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==
4913 PosInfInterval!Date(Date(2010, 7, 3)));
4914 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==
4915 PosInfInterval!Date(Date(2010, 7, 3)));
4916 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==
4917 PosInfInterval!Date(Date(2010, 7, 3)));
4918 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==
4919 PosInfInterval!Date(Date(2010, 7, 3)));
4920 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==
4921 PosInfInterval!Date(Date(2010, 7, 4)));
4922 assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==
4923 PosInfInterval!Date(Date(2010, 7, 4)));
4924 assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==
4925 PosInfInterval!Date(Date(2010, 7, 4)));
4926 assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==
4927 PosInfInterval!Date(Date(2010, 7, 4)));
4928 assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==
4929 PosInfInterval!Date(Date(2010, 7, 4)));
4930 assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) ==
4931 PosInfInterval!Date(Date(2010, 7, 4)));
4932
4933 assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3)));
4934 assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4)));
4935 assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4)));
4936 assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4)));
4937 assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4)));
4938 assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4)));
4939
4940 assert(PosInfInterval!Date(Date(2010, 7, 3)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 3)));
4941 assert(PosInfInterval!Date(Date(2010, 7, 4)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));
4942 assert(PosInfInterval!Date(Date(2010, 7, 5)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));
4943 assert(PosInfInterval!Date(Date(2012, 1, 6)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));
4944 assert(PosInfInterval!Date(Date(2012, 1, 7)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));
4945 assert(PosInfInterval!Date(Date(2012, 1, 8)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));
4946
4947 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 3)))));
4948 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 4)))));
4949 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 5)))));
4950 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 6)))));
4951 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 7)))));
4952 static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 8)))));
4953
4954 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4955 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4956 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
4957 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4958 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
4959 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4960 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4961 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
4962 assert(!posInfInterval.merge(interval).empty);
4963 assert(!posInfInterval.merge(cInterval).empty);
4964 assert(!posInfInterval.merge(iInterval).empty);
4965 assert(!posInfInterval.merge(posInfInterval).empty);
4966 assert(!posInfInterval.merge(cPosInfInterval).empty);
4967 assert(!posInfInterval.merge(iPosInfInterval).empty);
4968 static assert(!__traits(compiles, posInfInterval.merge(negInfInterval)));
4969 static assert(!__traits(compiles, posInfInterval.merge(cNegInfInterval)));
4970 static assert(!__traits(compiles, posInfInterval.merge(iNegInfInterval)));
4971 assert(!cPosInfInterval.merge(interval).empty);
4972 assert(!cPosInfInterval.merge(cInterval).empty);
4973 assert(!cPosInfInterval.merge(iInterval).empty);
4974 assert(!cPosInfInterval.merge(posInfInterval).empty);
4975 assert(!cPosInfInterval.merge(cPosInfInterval).empty);
4976 assert(!cPosInfInterval.merge(iPosInfInterval).empty);
4977 static assert(!__traits(compiles, cPosInfInterval.merge(negInfInterval)));
4978 static assert(!__traits(compiles, cPosInfInterval.merge(cNegInfInterval)));
4979 static assert(!__traits(compiles, cPosInfInterval.merge(iNegInfInterval)));
4980 assert(!iPosInfInterval.merge(interval).empty);
4981 assert(!iPosInfInterval.merge(cInterval).empty);
4982 assert(!iPosInfInterval.merge(iInterval).empty);
4983 assert(!iPosInfInterval.merge(posInfInterval).empty);
4984 assert(!iPosInfInterval.merge(cPosInfInterval).empty);
4985 assert(!iPosInfInterval.merge(iPosInfInterval).empty);
4986 static assert(!__traits(compiles, iPosInfInterval.merge(negInfInterval)));
4987 static assert(!__traits(compiles, iPosInfInterval.merge(cNegInfInterval)));
4988 static assert(!__traits(compiles, iPosInfInterval.merge(iNegInfInterval)));
4989
4990 //Verify Examples.
4991 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
4992 PosInfInterval!Date(Date(1990, 7, 6)));
4993 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==
4994 PosInfInterval!Date(Date(1996, 1, 2)));
4995
4996 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(PosInfInterval!Date(Date(1990, 7, 6))) ==
4997 PosInfInterval!Date(Date(1990, 7, 6)));
4998 assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(PosInfInterval!Date(Date(1999, 1, 12))) ==
4999 PosInfInterval!Date(Date(1996, 1, 2)));
5000 }
5001
5002 //Test PosInfInterval's span().
5003 @safe unittest
5004 {
5005 import std.datetime.date;
5006
5007 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
5008
5009 static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
5010 {
5011 posInfInterval.span(interval);
5012 }
5013
5014 assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
5015
5016 assert(posInfInterval.span(posInfInterval) == posInfInterval);
5017 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) ==
5018 PosInfInterval!Date(Date(2010, 7, 1)));
5019 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==
5020 PosInfInterval!Date(Date(2010, 7, 1)));
5021 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==
5022 PosInfInterval!Date(Date(2010, 7, 3)));
5023 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==
5024 PosInfInterval!Date(Date(2010, 7, 3)));
5025 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==
5026 PosInfInterval!Date(Date(2010, 7, 3)));
5027 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==
5028 PosInfInterval!Date(Date(2010, 7, 3)));
5029 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==
5030 PosInfInterval!Date(Date(2010, 7, 4)));
5031 assert(posInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==
5032 PosInfInterval!Date(Date(2010, 7, 4)));
5033 assert(posInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==
5034 PosInfInterval!Date(Date(2010, 7, 4)));
5035 assert(posInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==
5036 PosInfInterval!Date(Date(2010, 7, 4)));
5037 assert(posInfInterval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==
5038 PosInfInterval!Date(Date(2010, 7, 4)));
5039 assert(posInfInterval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) ==
5040 PosInfInterval!Date(Date(2010, 7, 4)));
5041
5042 assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3)));
5043 assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4)));
5044 assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4)));
5045 assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4)));
5046 assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4)));
5047 assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4)));
5048
5049 assert(PosInfInterval!Date(Date(2010, 7, 3)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 3)));
5050 assert(PosInfInterval!Date(Date(2010, 7, 4)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));
5051 assert(PosInfInterval!Date(Date(2010, 7, 5)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));
5052 assert(PosInfInterval!Date(Date(2012, 1, 6)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));
5053 assert(PosInfInterval!Date(Date(2012, 1, 7)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));
5054 assert(PosInfInterval!Date(Date(2012, 1, 8)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4)));
5055
5056 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 3)))));
5057 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 4)))));
5058 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 5)))));
5059 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 6)))));
5060 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 7)))));
5061 static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 8)))));
5062
5063 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
5064 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
5065 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
5066 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
5067 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
5068 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
5069 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
5070 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
5071 assert(!posInfInterval.span(interval).empty);
5072 assert(!posInfInterval.span(cInterval).empty);
5073 assert(!posInfInterval.span(iInterval).empty);
5074 assert(!posInfInterval.span(posInfInterval).empty);
5075 assert(!posInfInterval.span(cPosInfInterval).empty);
5076 assert(!posInfInterval.span(iPosInfInterval).empty);
5077 static assert(!__traits(compiles, posInfInterval.span(negInfInterval)));
5078 static assert(!__traits(compiles, posInfInterval.span(cNegInfInterval)));
5079 static assert(!__traits(compiles, posInfInterval.span(iNegInfInterval)));
5080 assert(!cPosInfInterval.span(interval).empty);
5081 assert(!cPosInfInterval.span(cInterval).empty);
5082 assert(!cPosInfInterval.span(iInterval).empty);
5083 assert(!cPosInfInterval.span(posInfInterval).empty);
5084 assert(!cPosInfInterval.span(cPosInfInterval).empty);
5085 assert(!cPosInfInterval.span(iPosInfInterval).empty);
5086 static assert(!__traits(compiles, cPosInfInterval.span(negInfInterval)));
5087 static assert(!__traits(compiles, cPosInfInterval.span(cNegInfInterval)));
5088 static assert(!__traits(compiles, cPosInfInterval.span(iNegInfInterval)));
5089 assert(!iPosInfInterval.span(interval).empty);
5090 assert(!iPosInfInterval.span(cInterval).empty);
5091 assert(!iPosInfInterval.span(iInterval).empty);
5092 assert(!iPosInfInterval.span(posInfInterval).empty);
5093 assert(!iPosInfInterval.span(cPosInfInterval).empty);
5094 assert(!iPosInfInterval.span(iPosInfInterval).empty);
5095 static assert(!__traits(compiles, iPosInfInterval.span(negInfInterval)));
5096 static assert(!__traits(compiles, iPosInfInterval.span(cNegInfInterval)));
5097 static assert(!__traits(compiles, iPosInfInterval.span(iNegInfInterval)));
5098
5099 //Verify Examples.
5100 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) ==
5101 PosInfInterval!Date(Date(500, 8, 9)));
5102 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
5103 PosInfInterval!Date(Date(1990, 7, 6)));
5104 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==
5105 PosInfInterval!Date(Date(1996, 1, 2)));
5106
5107 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(PosInfInterval!Date(Date(1990, 7, 6))) ==
5108 PosInfInterval!Date(Date(1990, 7, 6)));
5109 assert(PosInfInterval!Date(Date(1996, 1, 2)).span(PosInfInterval!Date(Date(1999, 1, 12))) ==
5110 PosInfInterval!Date(Date(1996, 1, 2)));
5111 }
5112
5113 //Test PosInfInterval's shift().
5114 @safe unittest
5115 {
5116 import std.datetime.date;
5117
5118 auto interval = PosInfInterval!Date(Date(2010, 7, 4));
5119
testInterval(I)5120 static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__)
5121 {
5122 interval.shift(duration);
5123 assert(interval == expected);
5124 }
5125
5126 testInterval(interval, dur!"days"(22), PosInfInterval!Date(Date(2010, 7, 26)));
5127 testInterval(interval, dur!"days"(-22), PosInfInterval!Date(Date(2010, 6, 12)));
5128
5129 const cInterval = PosInfInterval!Date(Date(2010, 7, 4));
5130 immutable iInterval = PosInfInterval!Date(Date(2010, 7, 4));
5131 static assert(!__traits(compiles, cInterval.shift(dur!"days"(5))));
5132 static assert(!__traits(compiles, iInterval.shift(dur!"days"(5))));
5133
5134 //Verify Examples.
5135 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
5136 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
5137
5138 interval1.shift(dur!"days"(50));
5139 assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21)));
5140
5141 interval2.shift(dur!"days"(-50));
5142 assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13)));
5143 }
5144
5145 //Test PosInfInterval's shift(int, int, AllowDayOverflow).
5146 @safe unittest
5147 {
5148 import std.datetime.date;
5149
5150 {
5151 auto interval = PosInfInterval!Date(Date(2010, 7, 4));
5152
testInterval(I)5153 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow,
5154 in I expected, size_t line = __LINE__)
5155 {
5156 interval.shift(years, months, allow);
5157 assert(interval == expected);
5158 }
5159
5160 testInterval(interval, 5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2015, 7, 4)));
5161 testInterval(interval, -5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2005, 7, 4)));
5162
5163 auto interval2 = PosInfInterval!Date(Date(2000, 1, 29));
5164
5165 testInterval(interval2, 1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2001, 3, 1)));
5166 testInterval(interval2, 1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2000, 12, 29)));
5167 testInterval(interval2, -1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1998, 12, 29)));
5168 testInterval(interval2, -1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1999, 3, 1)));
5169
5170 testInterval(interval2, 1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(2001, 2, 28)));
5171 testInterval(interval2, 1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(2000, 12, 29)));
5172 testInterval(interval2, -1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(1998, 12, 29)));
5173 testInterval(interval2, -1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(1999, 2, 28)));
5174 }
5175
5176 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
5177 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
5178 static assert(!__traits(compiles, cPosInfInterval.shift(1)));
5179 static assert(!__traits(compiles, iPosInfInterval.shift(1)));
5180
5181 //Verify Examples.
5182 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
5183 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
5184
5185 interval1.shift(2);
5186 assert(interval1 == PosInfInterval!Date(Date(1998, 1, 2)));
5187
5188 interval2.shift(-2);
5189 assert(interval2 == PosInfInterval!Date(Date(1994, 1, 2)));
5190 }
5191
5192 //Test PosInfInterval's expand().
5193 @safe unittest
5194 {
5195 import std.datetime.date;
5196
5197 auto interval = PosInfInterval!Date(Date(2000, 7, 4));
5198
testInterval(I)5199 static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__)
5200 {
5201 interval.expand(duration);
5202 assert(interval == expected);
5203 }
5204
5205 testInterval(interval, dur!"days"(22), PosInfInterval!Date(Date(2000, 6, 12)));
5206 testInterval(interval, dur!"days"(-22), PosInfInterval!Date(Date(2000, 7, 26)));
5207
5208 const cInterval = PosInfInterval!Date(Date(2010, 7, 4));
5209 immutable iInterval = PosInfInterval!Date(Date(2010, 7, 4));
5210 static assert(!__traits(compiles, cInterval.expand(dur!"days"(5))));
5211 static assert(!__traits(compiles, iInterval.expand(dur!"days"(5))));
5212
5213 //Verify Examples.
5214 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
5215 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
5216
5217 interval1.expand(dur!"days"(2));
5218 assert(interval1 == PosInfInterval!Date(Date(1995, 12, 31)));
5219
5220 interval2.expand(dur!"days"(-2));
5221 assert(interval2 == PosInfInterval!Date(Date(1996, 1, 4)));
5222 }
5223
5224 //Test PosInfInterval's expand(int, int, AllowDayOverflow).
5225 @safe unittest
5226 {
5227 import std.datetime.date;
5228
5229 {
5230 auto interval = PosInfInterval!Date(Date(2000, 7, 4));
5231
testInterval(I)5232 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow,
5233 in I expected, size_t line = __LINE__)
5234 {
5235 interval.expand(years, months, allow);
5236 assert(interval == expected);
5237 }
5238
5239 testInterval(interval, 5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(1995, 7, 4)));
5240 testInterval(interval, -5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2005, 7, 4)));
5241
5242 auto interval2 = PosInfInterval!Date(Date(2000, 1, 29));
5243
5244 testInterval(interval2, 1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1998, 12, 29)));
5245 testInterval(interval2, 1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1999, 3, 1)));
5246 testInterval(interval2, -1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2001, 3, 1)));
5247 testInterval(interval2, -1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2000, 12, 29)));
5248
5249 testInterval(interval2, 1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(1998, 12, 29)));
5250 testInterval(interval2, 1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(1999, 2, 28)));
5251 testInterval(interval2, -1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(2001, 2, 28)));
5252 testInterval(interval2, -1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(2000, 12, 29)));
5253 }
5254
5255 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
5256 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
5257 static assert(!__traits(compiles, cPosInfInterval.expand(1)));
5258 static assert(!__traits(compiles, iPosInfInterval.expand(1)));
5259
5260 //Verify Examples.
5261 auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
5262 auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
5263
5264 interval1.expand(2);
5265 assert(interval1 == PosInfInterval!Date(Date(1994, 1, 2)));
5266
5267 interval2.expand(-2);
5268 assert(interval2 == PosInfInterval!Date(Date(1998, 1, 2)));
5269 }
5270
5271 //Test PosInfInterval's fwdRange().
5272 @system unittest
5273 {
5274 import std.datetime.date;
5275
5276 auto posInfInterval = PosInfInterval!Date(Date(2010, 9, 19));
5277
5278 static void testInterval(PosInfInterval!Date posInfInterval)
5279 {
5280 posInfInterval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront();
5281 }
5282
5283 assertThrown!DateTimeException(testInterval(posInfInterval));
5284
5285 assert(PosInfInterval!Date(Date(2010, 9, 12)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front ==
5286 Date(2010, 9, 12));
5287
5288 assert(PosInfInterval!Date(Date(2010, 9, 12)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front ==
5289 Date(2010, 9, 17));
5290
5291 //Verify Examples.
5292 auto interval = PosInfInterval!Date(Date(2010, 9, 1));
delegate(in Date date)5293 auto func = delegate (in Date date)
5294 {
5295 if ((date.day & 1) == 0)
5296 return date + dur!"days"(2);
5297 return date + dur!"days"(1);
5298 };
5299 auto range = interval.fwdRange(func);
5300
5301 assert(range.front == Date(2010, 9, 1)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2).
5302
5303 range.popFront();
5304 assert(range.front == Date(2010, 9, 2));
5305
5306 range.popFront();
5307 assert(range.front == Date(2010, 9, 4));
5308
5309 range.popFront();
5310 assert(range.front == Date(2010, 9, 6));
5311
5312 range.popFront();
5313 assert(range.front == Date(2010, 9, 8));
5314
5315 range.popFront();
5316 assert(!range.empty);
5317
5318 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
5319 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
5320 assert(!cPosInfInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);
5321 assert(!iPosInfInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);
5322 }
5323
5324 //Test PosInfInterval's toString().
5325 @safe unittest
5326 {
5327 import std.datetime.date;
5328 assert(PosInfInterval!Date(Date(2010, 7, 4)).toString() == "[2010-Jul-04 - ∞)");
5329
5330 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
5331 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
5332 assert(cPosInfInterval.toString());
5333 assert(iPosInfInterval.toString());
5334 }
5335
5336
5337 /++
5338 Represents an interval of time which has negative infinity as its starting
5339 point.
5340
5341 Any ranges which iterate over a $(D NegInfInterval) are infinite. So, the
5342 main purpose of using $(D NegInfInterval) is to create an infinite range
5343 which starts at negative infinity and goes to a fixed end point.
5344 Iterate over it in reverse.
5345 +/
NegInfInterval(TP)5346 struct NegInfInterval(TP)
5347 {
5348 public:
5349
5350 /++
5351 Params:
5352 end = The time point which ends the interval.
5353
5354 Example:
5355 --------------------
5356 auto interval = PosInfInterval!Date(Date(1996, 1, 2));
5357 --------------------
5358 +/
5359 this(in TP end) pure nothrow
5360 {
5361 _end = cast(TP) end;
5362 }
5363
5364
5365 /++
5366 Params:
5367 rhs = The $(D NegInfInterval) to assign to this one.
5368 +/
5369 ref NegInfInterval opAssign(const ref NegInfInterval rhs) pure nothrow
5370 {
5371 _end = cast(TP) rhs._end;
5372 return this;
5373 }
5374
5375
5376 /++
5377 Params:
5378 rhs = The $(D NegInfInterval) to assign to this one.
5379 +/
5380 ref NegInfInterval opAssign(NegInfInterval rhs) pure nothrow
5381 {
5382 _end = cast(TP) rhs._end;
5383 return this;
5384 }
5385
5386
5387 /++
5388 The end point of the interval. It is excluded from the interval.
5389
5390 Example:
5391 --------------------
5392 assert(NegInfInterval!Date(Date(2012, 3, 1)).end == Date(2012, 3, 1));
5393 --------------------
5394 +/
5395 @property TP end() const pure nothrow
5396 {
5397 return cast(TP)_end;
5398 }
5399
5400
5401 /++
5402 The end point of the interval. It is excluded from the interval.
5403
5404 Params:
5405 timePoint = The time point to set end to.
5406 +/
5407 @property void end(TP timePoint) pure nothrow
5408 {
5409 _end = timePoint;
5410 }
5411
5412
5413 /++
5414 Whether the interval's length is 0. Always returns false.
5415
5416 Example:
5417 --------------------
5418 assert(!NegInfInterval!Date(Date(1996, 1, 2)).empty);
5419 --------------------
5420 +/
5421 enum bool empty = false;
5422
5423
5424 /++
5425 Whether the given time point is within this interval.
5426
5427 Params:
5428 timePoint = The time point to check for inclusion in this interval.
5429
5430 Example:
5431 --------------------
5432 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(1994, 12, 24)));
5433 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2000, 1, 5)));
5434 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2012, 3, 1)));
5435 --------------------
5436 +/
5437 bool contains(TP timePoint) const pure nothrow
5438 {
5439 return timePoint < _end;
5440 }
5441
5442
5443 /++
5444 Whether the given interval is completely within this interval.
5445
5446 Params:
5447 interval = The interval to check for inclusion in this interval.
5448
5449 Throws:
5450 $(REF DateTimeException,std,datetime,date) if the given interval
5451 is empty.
5452
5453 Example:
5454 --------------------
5455 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(
5456 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
5457
5458 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(
5459 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
5460
5461 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(
5462 Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));
5463 --------------------
5464 +/
5465 bool contains(in Interval!TP interval) const pure
5466 {
5467 interval._enforceNotEmpty();
5468 return interval._end <= _end;
5469 }
5470
5471
5472 /++
5473 Whether the given interval is completely within this interval.
5474
5475 Always returns false because an interval beginning at negative
5476 infinity can never contain an interval going to positive infinity.
5477
5478 Params:
5479 interval = The interval to check for inclusion in this interval.
5480
5481 Example:
5482 --------------------
5483 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(
5484 PosInfInterval!Date(Date(1999, 5, 4))));
5485 --------------------
5486 +/
5487 bool contains(in PosInfInterval!TP interval) const pure nothrow
5488 {
5489 return false;
5490 }
5491
5492
5493 /++
5494 Whether the given interval is completely within this interval.
5495
5496 Params:
5497 interval = The interval to check for inclusion in this interval.
5498
5499 Example:
5500 --------------------
5501 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(
5502 NegInfInterval!Date(Date(1996, 5, 4))));
5503
5504 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(
5505 NegInfInterval!Date(Date(2013, 7, 9))));
5506 --------------------
5507 +/
5508 bool contains(in NegInfInterval interval) const pure nothrow
5509 {
5510 return interval._end <= _end;
5511 }
5512
5513
5514 /++
5515 Whether this interval is before the given time point.
5516
5517 Params:
5518 timePoint = The time point to check whether this interval is
5519 before it.
5520
5521 Example:
5522 --------------------
5523 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(1994, 12, 24)));
5524 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2000, 1, 5)));
5525 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2012, 3, 1)));
5526 --------------------
5527 +/
5528 bool isBefore(in TP timePoint) const pure nothrow
5529 {
5530 return timePoint >= _end;
5531 }
5532
5533
5534 /++
5535 Whether this interval is before the given interval and does not
5536 intersect it.
5537
5538 Params:
5539 interval = The interval to check for against this interval.
5540
5541 Throws:
5542 $(REF DateTimeException,std,datetime,date) if the given interval
5543 is empty
5544
5545 Example:
5546 --------------------
5547 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
5548 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
5549
5550 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
5551 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
5552
5553 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
5554 Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
5555 --------------------
5556 +/
5557 bool isBefore(in Interval!TP interval) const pure
5558 {
5559 interval._enforceNotEmpty();
5560 return _end <= interval._begin;
5561 }
5562
5563
5564 /++
5565 Whether this interval is before the given interval and does not
5566 intersect it.
5567
5568 Params:
5569 interval = The interval to check for against this interval.
5570
5571 Example:
5572 --------------------
5573 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
5574 PosInfInterval!Date(Date(1999, 5, 4))));
5575
5576 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
5577 PosInfInterval!Date(Date(2012, 3, 1))));
5578 --------------------
5579 +/
5580 bool isBefore(in PosInfInterval!TP interval) const pure nothrow
5581 {
5582 return _end <= interval._begin;
5583 }
5584
5585
5586 /++
5587 Whether this interval is before the given interval and does not
5588 intersect it.
5589
5590 Always returns false because an interval beginning at negative
5591 infinity can never be before another interval beginning at negative
5592 infinity.
5593
5594 Params:
5595 interval = The interval to check for against this interval.
5596
5597 Example:
5598 --------------------
5599 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
5600 NegInfInterval!Date(Date(1996, 5, 4))));
5601
5602 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
5603 NegInfInterval!Date(Date(2013, 7, 9))));
5604 --------------------
5605 +/
5606 bool isBefore(in NegInfInterval interval) const pure nothrow
5607 {
5608 return false;
5609 }
5610
5611
5612 /++
5613 Whether this interval is after the given time point.
5614
5615 Always returns false because an interval beginning at negative infinity
5616 can never be after any time point.
5617
5618 Params:
5619 timePoint = The time point to check whether this interval is after
5620 it.
5621
5622 Example:
5623 --------------------
5624 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(1994, 12, 24)));
5625 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2000, 1, 5)));
5626 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2012, 3, 1)));
5627 --------------------
5628 +/
5629 bool isAfter(in TP timePoint) const pure nothrow
5630 {
5631 return false;
5632 }
5633
5634
5635 /++
5636 Whether this interval is after the given interval and does not
5637 intersect it.
5638
5639 Always returns false (unless the given interval is empty) because an
5640 interval beginning at negative infinity can never be after any other
5641 interval.
5642
5643 Params:
5644 interval = The interval to check against this interval.
5645
5646 Throws:
5647 $(REF DateTimeException,std,datetime,date) if the given interval
5648 is empty.
5649
5650 Example:
5651 --------------------
5652 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
5653 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
5654
5655 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
5656 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
5657
5658 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
5659 Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
5660 --------------------
5661 +/
5662 bool isAfter(in Interval!TP interval) const pure
5663 {
5664 interval._enforceNotEmpty();
5665 return false;
5666 }
5667
5668
5669 /++
5670 Whether this interval is after the given interval and does not intersect
5671 it.
5672
5673 Always returns false because an interval beginning at negative infinity
5674 can never be after any other interval.
5675
5676 Params:
5677 interval = The interval to check against this interval.
5678
5679 Example:
5680 --------------------
5681 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
5682 PosInfInterval!Date(Date(1999, 5, 4))));
5683
5684 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
5685 PosInfInterval!Date(Date(2012, 3, 1))));
5686 --------------------
5687 +/
5688 bool isAfter(in PosInfInterval!TP interval) const pure nothrow
5689 {
5690 return false;
5691 }
5692
5693
5694 /++
5695 Whether this interval is after the given interval and does not intersect
5696 it.
5697
5698 Always returns false because an interval beginning at negative infinity
5699 can never be after any other interval.
5700
5701 Params:
5702 interval = The interval to check against this interval.
5703
5704 Example:
5705 --------------------
5706 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
5707 NegInfInterval!Date(Date(1996, 5, 4))));
5708
5709 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
5710 NegInfInterval!Date(Date(2013, 7, 9))));
5711 --------------------
5712 +/
5713 bool isAfter(in NegInfInterval interval) const pure nothrow
5714 {
5715 return false;
5716 }
5717
5718
5719 /++
5720 Whether the given interval overlaps this interval.
5721
5722 Params:
5723 interval = The interval to check for intersection with this interval.
5724
5725 Throws:
5726 $(REF DateTimeException,std,datetime,date) if the given interval
5727 is empty.
5728
5729 Example:
5730 --------------------
5731 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(
5732 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
5733
5734 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(
5735 Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
5736
5737 assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(
5738 Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
5739 --------------------
5740 +/
5741 bool intersects(in Interval!TP interval) const pure
5742 {
5743 interval._enforceNotEmpty();
5744 return interval._begin < _end;
5745 }
5746
5747
5748 /++
5749 Whether the given interval overlaps this interval.
5750
5751 Params:
5752 interval = The interval to check for intersection with this
5753 interval.
5754
5755 Example:
5756 --------------------
5757 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(
5758 PosInfInterval!Date(Date(1999, 5, 4))));
5759
5760 assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(
5761 PosInfInterval!Date(Date(2012, 3, 1))));
5762 --------------------
5763 +/
5764 bool intersects(in PosInfInterval!TP interval) const pure nothrow
5765 {
5766 return interval._begin < _end;
5767 }
5768
5769
5770 /++
5771 Whether the given interval overlaps this interval.
5772
5773 Always returns true because two intervals beginning at negative infinity
5774 always overlap.
5775
5776 Params:
5777 interval = The interval to check for intersection with this interval.
5778
5779 Example:
5780 --------------------
5781 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(
5782 NegInfInterval!Date(Date(1996, 5, 4))));
5783
5784 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(
5785 NegInfInterval!Date(Date(2013, 7, 9))));
5786 --------------------
5787 +/
5788 bool intersects(in NegInfInterval!TP interval) const pure nothrow
5789 {
5790 return true;
5791 }
5792
5793
5794 /++
5795 Returns the intersection of two intervals
5796
5797 Params:
5798 interval = The interval to intersect with this interval.
5799
5800 Throws:
5801 $(REF DateTimeException,std,datetime,date) if the two intervals do
5802 not intersect or if the given interval is empty.
5803
5804 Example:
5805 --------------------
5806 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(
5807 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
5808 Interval!Date(Date(1990, 7 , 6), Date(2000, 8, 2)));
5809
5810 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(
5811 Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==
5812 Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));
5813 --------------------
5814 +/
5815 Interval!TP intersection(in Interval!TP interval) const
5816 {
5817 import std.format : format;
5818
5819 enforce(this.intersects(interval),
5820 new DateTimeException(format("%s and %s do not intersect.", this, interval)));
5821
5822 auto end = _end < interval._end ? _end : interval._end;
5823
5824 return Interval!TP(interval._begin, end);
5825 }
5826
5827
5828 /++
5829 Returns the intersection of two intervals
5830
5831 Params:
5832 interval = The interval to intersect with this interval.
5833
5834 Throws:
5835 $(REF DateTimeException,std,datetime,date) if the two intervals do
5836 not intersect.
5837
5838 Example:
5839 --------------------
5840 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(
5841 PosInfInterval!Date(Date(1990, 7, 6))) ==
5842 Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));
5843
5844 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(
5845 PosInfInterval!Date(Date(1999, 1, 12))) ==
5846 Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));
5847 --------------------
5848 +/
5849 Interval!TP intersection(in PosInfInterval!TP interval) const
5850 {
5851 import std.format : format;
5852
5853 enforce(this.intersects(interval),
5854 new DateTimeException(format("%s and %s do not intersect.", this, interval)));
5855
5856 return Interval!TP(interval._begin, _end);
5857 }
5858
5859
5860 /++
5861 Returns the intersection of two intervals
5862
5863 Params:
5864 interval = The interval to intersect with this interval.
5865
5866 Example:
5867 --------------------
5868 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(
5869 NegInfInterval!Date(Date(1999, 7, 6))) ==
5870 NegInfInterval!Date(Date(1999, 7 , 6)));
5871
5872 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(
5873 NegInfInterval!Date(Date(2013, 1, 12))) ==
5874 NegInfInterval!Date(Date(2012, 3 , 1)));
5875 --------------------
5876 +/
5877 NegInfInterval intersection(in NegInfInterval interval) const nothrow
5878 {
5879 return NegInfInterval(_end < interval._end ? _end : interval._end);
5880 }
5881
5882
5883 /++
5884 Whether the given interval is adjacent to this interval.
5885
5886 Params:
5887 interval = The interval to check whether its adjecent to this
5888 interval.
5889
5890 Throws:
5891 $(REF DateTimeException,std,datetime,date) if the given interval
5892 is empty.
5893
5894 Example:
5895 --------------------
5896 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
5897 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
5898
5899 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
5900 Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1))));
5901
5902 assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
5903 Interval!Date(Date(2012, 3, 1), Date(2019, 2, 2))));
5904
5905 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
5906 Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
5907 --------------------
5908 +/
5909 bool isAdjacent(in Interval!TP interval) const pure
5910 {
5911 interval._enforceNotEmpty();
5912 return interval._begin == _end;
5913 }
5914
5915
5916 /++
5917 Whether the given interval is adjacent to this interval.
5918
5919 Params:
5920 interval = The interval to check whether its adjecent to this
5921 interval.
5922
5923 Example:
5924 --------------------
5925 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
5926 PosInfInterval!Date(Date(1999, 5, 4))));
5927
5928 assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
5929 PosInfInterval!Date(Date(2012, 3, 1))));
5930 --------------------
5931 +/
5932 bool isAdjacent(in PosInfInterval!TP interval) const pure nothrow
5933 {
5934 return interval._begin == _end;
5935 }
5936
5937
5938 /++
5939 Whether the given interval is adjacent to this interval.
5940
5941 Always returns false because two intervals beginning at negative
5942 infinity can never be adjacent to one another.
5943
5944 Params:
5945 interval = The interval to check whether its adjecent to this
5946 interval.
5947
5948 Example:
5949 --------------------
5950 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
5951 NegInfInterval!Date(Date(1996, 5, 4))));
5952
5953 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
5954 NegInfInterval!Date(Date(2012, 3, 1))));
5955 --------------------
5956 +/
5957 bool isAdjacent(in NegInfInterval interval) const pure nothrow
5958 {
5959 return false;
5960 }
5961
5962
5963 /++
5964 Returns the union of two intervals
5965
5966 Params:
5967 interval = The interval to merge with this interval.
5968
5969 Throws:
5970 $(REF DateTimeException,std,datetime,date) if the two intervals do
5971 not intersect and are not adjacent or if the given interval is empty.
5972
5973 Note:
5974 There is no overload for $(D merge) which takes a
5975 $(D PosInfInterval), because an interval
5976 going from negative infinity to positive infinity
5977 is not possible.
5978
5979 Example:
5980 --------------------
5981 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(
5982 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
5983 NegInfInterval!Date(Date(2012, 3 , 1)));
5984
5985 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(
5986 Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==
5987 NegInfInterval!Date(Date(2015, 9 , 2)));
5988 --------------------
5989 +/
5990 NegInfInterval merge(in Interval!TP interval) const
5991 {
5992 import std.format : format;
5993
5994 enforce(this.isAdjacent(interval) || this.intersects(interval),
5995 new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval)));
5996
5997 return NegInfInterval(_end > interval._end ? _end : interval._end);
5998 }
5999
6000
6001 /++
6002 Returns the union of two intervals
6003
6004 Params:
6005 interval = The interval to merge with this interval.
6006
6007 Note:
6008 There is no overload for $(D merge) which takes a
6009 $(D PosInfInterval), because an interval
6010 going from negative infinity to positive infinity
6011 is not possible.
6012
6013 Example:
6014 --------------------
6015 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(
6016 NegInfInterval!Date(Date(1999, 7, 6))) ==
6017 NegInfInterval!Date(Date(2012, 3 , 1)));
6018
6019 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(
6020 NegInfInterval!Date(Date(2013, 1, 12))) ==
6021 NegInfInterval!Date(Date(2013, 1 , 12)));
6022 --------------------
6023 +/
6024 NegInfInterval merge(in NegInfInterval interval) const pure nothrow
6025 {
6026 return NegInfInterval(_end > interval._end ? _end : interval._end);
6027 }
6028
6029
6030 /++
6031 Returns an interval that covers from the earliest time point of two
6032 intervals up to (but not including) the latest time point of two
6033 intervals.
6034
6035 Params:
6036 interval = The interval to create a span together with this
6037 interval.
6038
6039 Throws:
6040 $(REF DateTimeException,std,datetime,date) if the given interval
6041 is empty.
6042
6043 Note:
6044 There is no overload for $(D span) which takes a
6045 $(D PosInfInterval), because an interval
6046 going from negative infinity to positive infinity
6047 is not possible.
6048
6049 Example:
6050 --------------------
6051 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(
6052 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
6053 NegInfInterval!Date(Date(2012, 3 , 1)));
6054
6055 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(
6056 Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==
6057 NegInfInterval!Date(Date(2015, 9 , 2)));
6058
6059 assert(NegInfInterval!Date(Date(1600, 1, 7)).span(
6060 Interval!Date(Date(2012, 3, 11), Date(2017, 7, 1))) ==
6061 NegInfInterval!Date(Date(2017, 7 , 1)));
6062 --------------------
6063 +/
6064 NegInfInterval span(in Interval!TP interval) const pure
6065 {
6066 interval._enforceNotEmpty();
6067 return NegInfInterval(_end > interval._end ? _end : interval._end);
6068 }
6069
6070
6071 /++
6072 Returns an interval that covers from the earliest time point of two
6073 intervals up to (but not including) the latest time point of two
6074 intervals.
6075
6076 Params:
6077 interval = The interval to create a span together with this
6078 interval.
6079
6080 Note:
6081 There is no overload for $(D span) which takes a
6082 $(D PosInfInterval), because an interval
6083 going from negative infinity to positive infinity
6084 is not possible.
6085
6086 Example:
6087 --------------------
6088 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(
6089 NegInfInterval!Date(Date(1999, 7, 6))) ==
6090 NegInfInterval!Date(Date(2012, 3 , 1)));
6091
6092 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(
6093 NegInfInterval!Date(Date(2013, 1, 12))) ==
6094 NegInfInterval!Date(Date(2013, 1 , 12)));
6095 --------------------
6096 +/
6097 NegInfInterval span(in NegInfInterval interval) const pure nothrow
6098 {
6099 return NegInfInterval(_end > interval._end ? _end : interval._end);
6100 }
6101
6102
6103 /++
6104 Shifts the $(D end) of this interval forward or backwards in time by the
6105 given duration (a positive duration shifts the interval forward; a
6106 negative duration shifts it backward). Effectively, it does
6107 $(D end += duration).
6108
6109 Params:
6110 duration = The duration to shift the interval by.
6111
6112 Example:
6113 --------------------
6114 auto interval1 = NegInfInterval!Date(Date(2012, 4, 5));
6115 auto interval2 = NegInfInterval!Date(Date(2012, 4, 5));
6116
6117 interval1.shift(dur!"days"(50));
6118 assert(interval1 == NegInfInterval!Date(Date(2012, 5, 25)));
6119
6120 interval2.shift(dur!"days"(-50));
6121 assert(interval2 == NegInfInterval!Date( Date(2012, 2, 15)));
6122 --------------------
6123 +/
6124 void shift(D)(D duration) pure nothrow
6125 if (__traits(compiles, end + duration))
6126 {
6127 _end += duration;
6128 }
6129
6130
6131 static if (__traits(compiles, end.add!"months"(1)) &&
6132 __traits(compiles, end.add!"years"(1)))
6133 {
6134 /++
6135 Shifts the $(D end) of this interval forward or backwards in time by
6136 the given number of years and/or months (a positive number of years
6137 and months shifts the interval forward; a negative number shifts it
6138 backward). It adds the years the given years and months to end. It
6139 effectively calls $(D add!"years"()) and then $(D add!"months"())
6140 on end with the given number of years and months.
6141
6142 Params:
6143 years = The number of years to shift the interval by.
6144 months = The number of months to shift the interval by.
6145 allowOverflow = Whether the days should be allowed to overflow
6146 on $(D end), causing its month to increment.
6147
6148 Throws:
6149 $(REF DateTimeException,std,datetime,date) if empty is true or
6150 if the resulting interval would be invalid.
6151
6152 Example:
6153 --------------------
6154 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));
6155 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));
6156
6157 interval1.shift(2);
6158 assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1)));
6159
6160 interval2.shift(-2);
6161 assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1)));
6162 --------------------
6163 +/
6164 void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
6165 if (isIntegral!T)
6166 {
6167 auto end = _end;
6168
6169 end.add!"years"(years, allowOverflow);
6170 end.add!"months"(months, allowOverflow);
6171
6172 _end = end;
6173 }
6174 }
6175
6176
6177 /++
6178 Expands the interval forwards in time. Effectively, it does
6179 $(D end += duration).
6180
6181 Params:
6182 duration = The duration to expand the interval by.
6183
6184 Example:
6185 --------------------
6186 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));
6187 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));
6188
6189 interval1.expand(dur!"days"(2));
6190 assert(interval1 == NegInfInterval!Date(Date(2012, 3, 3)));
6191
6192 interval2.expand(dur!"days"(-2));
6193 assert(interval2 == NegInfInterval!Date(Date(2012, 2, 28)));
6194 --------------------
6195 +/
6196 void expand(D)(D duration) pure nothrow
6197 if (__traits(compiles, end + duration))
6198 {
6199 _end += duration;
6200 }
6201
6202
6203 static if (__traits(compiles, end.add!"months"(1)) &&
6204 __traits(compiles, end.add!"years"(1)))
6205 {
6206 /++
6207 Expands the interval forwards and/or backwards in time. Effectively,
6208 it adds the given number of months/years to end.
6209
6210 Params:
6211 years = The number of years to expand the interval by.
6212 months = The number of months to expand the interval by.
6213 allowOverflow = Whether the days should be allowed to overflow
6214 on $(D end), causing their month to increment.
6215
6216 Throws:
6217 $(REF DateTimeException,std,datetime,date) if empty is true or
6218 if the resulting interval would be invalid.
6219
6220 Example:
6221 --------------------
6222 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));
6223 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));
6224
6225 interval1.expand(2);
6226 assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1)));
6227
6228 interval2.expand(-2);
6229 assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1)));
6230 --------------------
6231 +/
6232 void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
6233 if (isIntegral!T)
6234 {
6235 auto end = _end;
6236
6237 end.add!"years"(years, allowOverflow);
6238 end.add!"months"(months, allowOverflow);
6239
6240 _end = end;
6241 }
6242 }
6243
6244
6245 /++
6246 Returns a range which iterates backwards over the interval, starting
6247 at $(D end), using $(D_PARAM func) to generate each successive time
6248 point.
6249
6250 The range's $(D front) is the interval's $(D end). $(D_PARAM func) is
6251 used to generate the next $(D front) when $(D popFront) is called. If
6252 $(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called
6253 before the range is returned (so that $(D front) is a time point which
6254 $(D_PARAM func) would generate).
6255
6256 If $(D_PARAM func) ever generates a time point greater than or equal to
6257 the current $(D front) of the range, then a
6258 $(REF DateTimeException,std,datetime,date) will be thrown.
6259
6260 There are helper functions in this module which generate common
6261 delegates to pass to $(D bwdRange). Their documentation starts with
6262 "Range-generating function," to make them easily searchable.
6263
6264 Params:
6265 func = The function used to generate the time points of the
6266 range over the interval.
6267 popFirst = Whether $(D popFront) should be called on the range
6268 before returning it.
6269
6270 Throws:
6271 $(REF DateTimeException,std,datetime,date) if this interval is
6272 empty.
6273
6274 Warning:
6275 $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func)
6276 would be a function pointer to a pure function, but forcing
6277 $(D_PARAM func) to be pure is far too restrictive to be useful, and
6278 in order to have the ease of use of having functions which generate
6279 functions to pass to $(D fwdRange), $(D_PARAM func) must be a
6280 delegate.
6281
6282 If $(D_PARAM func) retains state which changes as it is called, then
6283 some algorithms will not work correctly, because the range's
6284 $(D save) will have failed to have really saved the range's state.
6285 To avoid such bugs, don't pass a delegate which is
6286 not logically pure to $(D fwdRange). If $(D_PARAM func) is given the
6287 same time point with two different calls, it must return the same
6288 result both times.
6289
6290 Of course, none of the functions in this module have this problem,
6291 so it's only relevant for custom delegates.
6292
6293 Example:
6294 --------------------
6295 auto interval = NegInfInterval!Date(Date(2010, 9, 9));
6296 auto func = delegate (in Date date) //For iterating over even-numbered days.
6297 {
6298 if ((date.day & 1) == 0)
6299 return date - dur!"days"(2);
6300
6301 return date - dur!"days"(1);
6302 };
6303 auto range = interval.bwdRange(func);
6304
6305 assert(range.front == Date(2010, 9, 9)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8).
6306
6307 range.popFront();
6308 assert(range.front == Date(2010, 9, 8));
6309
6310 range.popFront();
6311 assert(range.front == Date(2010, 9, 6));
6312
6313 range.popFront();
6314 assert(range.front == Date(2010, 9, 4));
6315
6316 range.popFront();
6317 assert(range.front == Date(2010, 9, 2));
6318
6319 range.popFront();
6320 assert(!range.empty);
6321 --------------------
6322 +/
6323 NegInfIntervalRange!(TP) bwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const
6324 {
6325 auto range = NegInfIntervalRange!(TP)(this, func);
6326
6327 if (popFirst == PopFirst.yes)
6328 range.popFront();
6329
6330 return range;
6331 }
6332
6333
6334 /+
6335 Converts this interval to a string.
6336 +/
6337 //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
6338 //have versions of toString() with extra modifiers, so we define one version
6339 //with modifiers and one without.
6340 string toString()
6341 {
6342 return _toStringImpl();
6343 }
6344
6345
6346 /++
6347 Converts this interval to a string.
6348 +/
6349 //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
6350 //have versions of toString() with extra modifiers, so we define one version
6351 //with modifiers and one without.
6352 string toString() const nothrow
6353 {
6354 return _toStringImpl();
6355 }
6356
6357 private:
6358
6359 /+
6360 Since we have two versions of toString(), we have _toStringImpl()
6361 so that they can share implementations.
6362 +/
6363 string _toStringImpl() const nothrow
6364 {
6365 import std.format : format;
6366 try
6367 return format("[-∞ - %s)", _end);
6368 catch (Exception e)
6369 assert(0, "format() threw.");
6370 }
6371
6372
6373 TP _end;
6374 }
6375
6376 //Test NegInfInterval's constructor.
6377 @safe unittest
6378 {
6379 import std.datetime.date;
6380 import std.datetime.systime;
6381
6382 NegInfInterval!Date(Date.init);
6383 NegInfInterval!TimeOfDay(TimeOfDay.init);
6384 NegInfInterval!DateTime(DateTime.init);
6385 NegInfInterval!SysTime(SysTime(0));
6386 }
6387
6388 //Test NegInfInterval's end.
6389 @safe unittest
6390 {
6391 import std.datetime.date;
6392
6393 assert(NegInfInterval!Date(Date(2010, 1, 1)).end == Date(2010, 1, 1));
6394 assert(NegInfInterval!Date(Date(2010, 1, 1)).end == Date(2010, 1, 1));
6395 assert(NegInfInterval!Date(Date(1998, 1, 1)).end == Date(1998, 1, 1));
6396
6397 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6398 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6399 assert(cNegInfInterval.end != Date.init);
6400 assert(iNegInfInterval.end != Date.init);
6401
6402 //Verify Examples.
6403 assert(NegInfInterval!Date(Date(2012, 3, 1)).end == Date(2012, 3, 1));
6404 }
6405
6406 //Test NegInfInterval's empty.
6407 @safe unittest
6408 {
6409 import std.datetime.date;
6410 import std.datetime.systime;
6411
6412 assert(!NegInfInterval!Date(Date(2010, 1, 1)).empty);
6413 assert(!NegInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty);
6414 assert(!NegInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty);
6415 assert(!NegInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty);
6416
6417 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6418 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6419 assert(!cNegInfInterval.empty);
6420 assert(!iNegInfInterval.empty);
6421
6422 //Verify Examples.
6423 assert(!NegInfInterval!Date(Date(1996, 1, 2)).empty);
6424 }
6425
6426 //Test NegInfInterval's contains(time point).
6427 @safe unittest
6428 {
6429 import std.datetime.date;
6430
6431 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6432
6433 assert(negInfInterval.contains(Date(2009, 7, 4)));
6434 assert(negInfInterval.contains(Date(2010, 7, 3)));
6435 assert(negInfInterval.contains(Date(2010, 7, 4)));
6436 assert(negInfInterval.contains(Date(2010, 7, 5)));
6437 assert(negInfInterval.contains(Date(2011, 7, 1)));
6438 assert(negInfInterval.contains(Date(2012, 1, 6)));
6439 assert(!negInfInterval.contains(Date(2012, 1, 7)));
6440 assert(!negInfInterval.contains(Date(2012, 1, 8)));
6441 assert(!negInfInterval.contains(Date(2013, 1, 7)));
6442
6443 const cdate = Date(2010, 7, 6);
6444 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6445 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6446 assert(negInfInterval.contains(cdate));
6447 assert(cNegInfInterval.contains(cdate));
6448 assert(iNegInfInterval.contains(cdate));
6449
6450 //Verify Examples.
6451 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(1994, 12, 24)));
6452 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2000, 1, 5)));
6453 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2012, 3, 1)));
6454 }
6455
6456 //Test NegInfInterval's contains(Interval).
6457 @safe unittest
6458 {
6459 import std.datetime.date;
6460
6461 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6462
6463 static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval)
6464 {
6465 negInfInterval.contains(interval);
6466 }
6467
6468 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
6469
6470 assert(negInfInterval.contains(negInfInterval));
6471 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
6472 assert(!negInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
6473 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
6474 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
6475 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
6476 assert(!negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
6477 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
6478 assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
6479 assert(negInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
6480 assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
6481 assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
6482 assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
6483
6484 assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 3))));
6485 assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 4))));
6486 assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 5))));
6487 assert(negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 6))));
6488 assert(negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 7))));
6489 assert(!negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 8))));
6490
6491 assert(!NegInfInterval!Date(Date(2010, 7, 3)).contains(negInfInterval));
6492 assert(!NegInfInterval!Date(Date(2010, 7, 4)).contains(negInfInterval));
6493 assert(!NegInfInterval!Date(Date(2010, 7, 5)).contains(negInfInterval));
6494 assert(!NegInfInterval!Date(Date(2012, 1, 6)).contains(negInfInterval));
6495 assert(NegInfInterval!Date(Date(2012, 1, 7)).contains(negInfInterval));
6496 assert(NegInfInterval!Date(Date(2012, 1, 8)).contains(negInfInterval));
6497
6498 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 3))));
6499 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 4))));
6500 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 5))));
6501 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 6))));
6502 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 7))));
6503 assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 8))));
6504
6505 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6506 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6507 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6508 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6509 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6510 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6511 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6512 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6513 assert(negInfInterval.contains(interval));
6514 assert(negInfInterval.contains(cInterval));
6515 assert(negInfInterval.contains(iInterval));
6516 assert(!negInfInterval.contains(posInfInterval));
6517 assert(!negInfInterval.contains(cPosInfInterval));
6518 assert(!negInfInterval.contains(iPosInfInterval));
6519 assert(negInfInterval.contains(negInfInterval));
6520 assert(negInfInterval.contains(cNegInfInterval));
6521 assert(negInfInterval.contains(iNegInfInterval));
6522 assert(cNegInfInterval.contains(interval));
6523 assert(cNegInfInterval.contains(cInterval));
6524 assert(cNegInfInterval.contains(iInterval));
6525 assert(!cNegInfInterval.contains(posInfInterval));
6526 assert(!cNegInfInterval.contains(cPosInfInterval));
6527 assert(!cNegInfInterval.contains(iPosInfInterval));
6528 assert(cNegInfInterval.contains(negInfInterval));
6529 assert(cNegInfInterval.contains(cNegInfInterval));
6530 assert(cNegInfInterval.contains(iNegInfInterval));
6531 assert(iNegInfInterval.contains(interval));
6532 assert(iNegInfInterval.contains(cInterval));
6533 assert(iNegInfInterval.contains(iInterval));
6534 assert(!iNegInfInterval.contains(posInfInterval));
6535 assert(!iNegInfInterval.contains(cPosInfInterval));
6536 assert(!iNegInfInterval.contains(iPosInfInterval));
6537 assert(iNegInfInterval.contains(negInfInterval));
6538 assert(iNegInfInterval.contains(cNegInfInterval));
6539 assert(iNegInfInterval.contains(iNegInfInterval));
6540
6541 //Verify Examples.
6542 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
6543 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
6544 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));
6545
6546 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4))));
6547
6548 assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4))));
6549 assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(2013, 7, 9))));
6550 }
6551
6552 //Test NegInfInterval's isBefore(time point).
6553 @safe unittest
6554 {
6555 import std.datetime.date;
6556
6557 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6558
6559 assert(!negInfInterval.isBefore(Date(2009, 7, 4)));
6560 assert(!negInfInterval.isBefore(Date(2010, 7, 3)));
6561 assert(!negInfInterval.isBefore(Date(2010, 7, 4)));
6562 assert(!negInfInterval.isBefore(Date(2010, 7, 5)));
6563 assert(!negInfInterval.isBefore(Date(2011, 7, 1)));
6564 assert(!negInfInterval.isBefore(Date(2012, 1, 6)));
6565 assert(negInfInterval.isBefore(Date(2012, 1, 7)));
6566 assert(negInfInterval.isBefore(Date(2012, 1, 8)));
6567 assert(negInfInterval.isBefore(Date(2013, 1, 7)));
6568
6569 const cdate = Date(2010, 7, 6);
6570 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6571 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6572 assert(!negInfInterval.isBefore(cdate));
6573 assert(!cNegInfInterval.isBefore(cdate));
6574 assert(!iNegInfInterval.isBefore(cdate));
6575
6576 //Verify Examples.
6577 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(1994, 12, 24)));
6578 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2000, 1, 5)));
6579 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2012, 3, 1)));
6580 }
6581
6582 //Test NegInfInterval's isBefore(Interval).
6583 @safe unittest
6584 {
6585 import std.datetime.date;
6586
6587 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6588
6589 static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval)
6590 {
6591 negInfInterval.isBefore(interval);
6592 }
6593
6594 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
6595
6596 assert(!negInfInterval.isBefore(negInfInterval));
6597 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
6598 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
6599 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
6600 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
6601 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
6602 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
6603 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
6604 assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
6605 assert(!negInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
6606 assert(!negInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
6607 assert(negInfInterval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
6608 assert(negInfInterval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
6609
6610 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 3))));
6611 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 4))));
6612 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 5))));
6613 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 6))));
6614 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 7))));
6615 assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 8))));
6616
6617 assert(!NegInfInterval!Date(Date(2010, 7, 3)).isBefore(negInfInterval));
6618 assert(!NegInfInterval!Date(Date(2010, 7, 4)).isBefore(negInfInterval));
6619 assert(!NegInfInterval!Date(Date(2010, 7, 5)).isBefore(negInfInterval));
6620 assert(!NegInfInterval!Date(Date(2012, 1, 6)).isBefore(negInfInterval));
6621 assert(!NegInfInterval!Date(Date(2012, 1, 7)).isBefore(negInfInterval));
6622 assert(!NegInfInterval!Date(Date(2012, 1, 8)).isBefore(negInfInterval));
6623
6624 assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 3))));
6625 assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 4))));
6626 assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 5))));
6627 assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 6))));
6628 assert(negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 7))));
6629 assert(negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 8))));
6630
6631 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6632 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6633 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6634 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6635 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6636 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6637 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6638 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6639 assert(!negInfInterval.isBefore(interval));
6640 assert(!negInfInterval.isBefore(cInterval));
6641 assert(!negInfInterval.isBefore(iInterval));
6642 assert(!negInfInterval.isBefore(posInfInterval));
6643 assert(!negInfInterval.isBefore(cPosInfInterval));
6644 assert(!negInfInterval.isBefore(iPosInfInterval));
6645 assert(!negInfInterval.isBefore(negInfInterval));
6646 assert(!negInfInterval.isBefore(cNegInfInterval));
6647 assert(!negInfInterval.isBefore(iNegInfInterval));
6648 assert(!cNegInfInterval.isBefore(interval));
6649 assert(!cNegInfInterval.isBefore(cInterval));
6650 assert(!cNegInfInterval.isBefore(iInterval));
6651 assert(!cNegInfInterval.isBefore(posInfInterval));
6652 assert(!cNegInfInterval.isBefore(cPosInfInterval));
6653 assert(!cNegInfInterval.isBefore(iPosInfInterval));
6654 assert(!cNegInfInterval.isBefore(negInfInterval));
6655 assert(!cNegInfInterval.isBefore(cNegInfInterval));
6656 assert(!cNegInfInterval.isBefore(iNegInfInterval));
6657 assert(!iNegInfInterval.isBefore(interval));
6658 assert(!iNegInfInterval.isBefore(cInterval));
6659 assert(!iNegInfInterval.isBefore(iInterval));
6660 assert(!iNegInfInterval.isBefore(posInfInterval));
6661 assert(!iNegInfInterval.isBefore(cPosInfInterval));
6662 assert(!iNegInfInterval.isBefore(iPosInfInterval));
6663 assert(!iNegInfInterval.isBefore(negInfInterval));
6664 assert(!iNegInfInterval.isBefore(cNegInfInterval));
6665 assert(!iNegInfInterval.isBefore(iNegInfInterval));
6666
6667 //Verify Examples.
6668 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
6669 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
6670 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
6671
6672 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4))));
6673 assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2012, 3, 1))));
6674
6675 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4))));
6676 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(2013, 7, 9))));
6677 }
6678
6679 //Test NegInfInterval's isAfter(time point).
6680 @safe unittest
6681 {
6682 import std.datetime.date;
6683
6684 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6685
6686 assert(!negInfInterval.isAfter(Date(2009, 7, 4)));
6687 assert(!negInfInterval.isAfter(Date(2010, 7, 3)));
6688 assert(!negInfInterval.isAfter(Date(2010, 7, 4)));
6689 assert(!negInfInterval.isAfter(Date(2010, 7, 5)));
6690 assert(!negInfInterval.isAfter(Date(2011, 7, 1)));
6691 assert(!negInfInterval.isAfter(Date(2012, 1, 6)));
6692 assert(!negInfInterval.isAfter(Date(2012, 1, 7)));
6693 assert(!negInfInterval.isAfter(Date(2012, 1, 8)));
6694 assert(!negInfInterval.isAfter(Date(2013, 1, 7)));
6695
6696 const cdate = Date(2010, 7, 6);
6697 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6698 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6699 assert(!negInfInterval.isAfter(cdate));
6700 assert(!cNegInfInterval.isAfter(cdate));
6701 assert(!iNegInfInterval.isAfter(cdate));
6702 }
6703
6704 //Test NegInfInterval's isAfter(Interval).
6705 @safe unittest
6706 {
6707 import std.datetime.date;
6708
6709 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6710
6711 static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval)
6712 {
6713 negInfInterval.isAfter(interval);
6714 }
6715
6716 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
6717
6718 assert(!negInfInterval.isAfter(negInfInterval));
6719 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
6720 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
6721 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
6722 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
6723 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
6724 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
6725 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
6726 assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
6727 assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
6728 assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
6729 assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
6730 assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
6731
6732 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 3))));
6733 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 4))));
6734 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 5))));
6735 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 6))));
6736 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 7))));
6737 assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 8))));
6738
6739 assert(!NegInfInterval!Date(Date(2010, 7, 3)).isAfter(negInfInterval));
6740 assert(!NegInfInterval!Date(Date(2010, 7, 4)).isAfter(negInfInterval));
6741 assert(!NegInfInterval!Date(Date(2010, 7, 5)).isAfter(negInfInterval));
6742 assert(!NegInfInterval!Date(Date(2012, 1, 6)).isAfter(negInfInterval));
6743 assert(!NegInfInterval!Date(Date(2012, 1, 7)).isAfter(negInfInterval));
6744 assert(!NegInfInterval!Date(Date(2012, 1, 8)).isAfter(negInfInterval));
6745
6746 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 3))));
6747 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 4))));
6748 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 5))));
6749 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 6))));
6750 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 7))));
6751 assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 8))));
6752
6753 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6754 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6755 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6756 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6757 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6758 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6759 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6760 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6761 assert(!negInfInterval.isAfter(interval));
6762 assert(!negInfInterval.isAfter(cInterval));
6763 assert(!negInfInterval.isAfter(iInterval));
6764 assert(!negInfInterval.isAfter(posInfInterval));
6765 assert(!negInfInterval.isAfter(cPosInfInterval));
6766 assert(!negInfInterval.isAfter(iPosInfInterval));
6767 assert(!negInfInterval.isAfter(negInfInterval));
6768 assert(!negInfInterval.isAfter(cNegInfInterval));
6769 assert(!negInfInterval.isAfter(iNegInfInterval));
6770 assert(!cNegInfInterval.isAfter(interval));
6771 assert(!cNegInfInterval.isAfter(cInterval));
6772 assert(!cNegInfInterval.isAfter(iInterval));
6773 assert(!cNegInfInterval.isAfter(posInfInterval));
6774 assert(!cNegInfInterval.isAfter(cPosInfInterval));
6775 assert(!cNegInfInterval.isAfter(iPosInfInterval));
6776 assert(!cNegInfInterval.isAfter(negInfInterval));
6777 assert(!cNegInfInterval.isAfter(cNegInfInterval));
6778 assert(!cNegInfInterval.isAfter(iNegInfInterval));
6779 assert(!iNegInfInterval.isAfter(interval));
6780 assert(!iNegInfInterval.isAfter(cInterval));
6781 assert(!iNegInfInterval.isAfter(iInterval));
6782 assert(!iNegInfInterval.isAfter(posInfInterval));
6783 assert(!iNegInfInterval.isAfter(cPosInfInterval));
6784 assert(!iNegInfInterval.isAfter(iPosInfInterval));
6785 assert(!iNegInfInterval.isAfter(negInfInterval));
6786 assert(!iNegInfInterval.isAfter(cNegInfInterval));
6787 assert(!iNegInfInterval.isAfter(iNegInfInterval));
6788
6789 //Verify Examples.
6790 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(1994, 12, 24)));
6791 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2000, 1, 5)));
6792 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2012, 3, 1)));
6793
6794 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
6795 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
6796 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
6797
6798 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4))));
6799 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(2012, 3, 1))));
6800
6801 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 5, 4))));
6802 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(2013, 7, 9))));
6803 }
6804
6805 //Test NegInfInterval's intersects().
6806 @safe unittest
6807 {
6808 import std.datetime.date;
6809
6810 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6811
6812 static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval)
6813 {
6814 negInfInterval.intersects(interval);
6815 }
6816
6817 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
6818
6819 assert(negInfInterval.intersects(negInfInterval));
6820 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
6821 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
6822 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
6823 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
6824 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
6825 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
6826 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
6827 assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
6828 assert(negInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
6829 assert(negInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
6830 assert(!negInfInterval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
6831 assert(!negInfInterval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
6832
6833 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 3))));
6834 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 4))));
6835 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 5))));
6836 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 6))));
6837 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 7))));
6838 assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 8))));
6839
6840 assert(NegInfInterval!Date(Date(2010, 7, 3)).intersects(negInfInterval));
6841 assert(NegInfInterval!Date(Date(2010, 7, 4)).intersects(negInfInterval));
6842 assert(NegInfInterval!Date(Date(2010, 7, 5)).intersects(negInfInterval));
6843 assert(NegInfInterval!Date(Date(2012, 1, 6)).intersects(negInfInterval));
6844 assert(NegInfInterval!Date(Date(2012, 1, 7)).intersects(negInfInterval));
6845 assert(NegInfInterval!Date(Date(2012, 1, 8)).intersects(negInfInterval));
6846
6847 assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 3))));
6848 assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 4))));
6849 assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 5))));
6850 assert(negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 6))));
6851 assert(!negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 7))));
6852 assert(!negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 8))));
6853
6854 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6855 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6856 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6857 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6858 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6859 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6860 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6861 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6862 assert(negInfInterval.intersects(interval));
6863 assert(negInfInterval.intersects(cInterval));
6864 assert(negInfInterval.intersects(iInterval));
6865 assert(negInfInterval.intersects(posInfInterval));
6866 assert(negInfInterval.intersects(cPosInfInterval));
6867 assert(negInfInterval.intersects(iPosInfInterval));
6868 assert(negInfInterval.intersects(negInfInterval));
6869 assert(negInfInterval.intersects(cNegInfInterval));
6870 assert(negInfInterval.intersects(iNegInfInterval));
6871 assert(cNegInfInterval.intersects(interval));
6872 assert(cNegInfInterval.intersects(cInterval));
6873 assert(cNegInfInterval.intersects(iInterval));
6874 assert(cNegInfInterval.intersects(posInfInterval));
6875 assert(cNegInfInterval.intersects(cPosInfInterval));
6876 assert(cNegInfInterval.intersects(iPosInfInterval));
6877 assert(cNegInfInterval.intersects(negInfInterval));
6878 assert(cNegInfInterval.intersects(cNegInfInterval));
6879 assert(cNegInfInterval.intersects(iNegInfInterval));
6880 assert(iNegInfInterval.intersects(interval));
6881 assert(iNegInfInterval.intersects(cInterval));
6882 assert(iNegInfInterval.intersects(iInterval));
6883 assert(iNegInfInterval.intersects(posInfInterval));
6884 assert(iNegInfInterval.intersects(cPosInfInterval));
6885 assert(iNegInfInterval.intersects(iPosInfInterval));
6886 assert(iNegInfInterval.intersects(negInfInterval));
6887 assert(iNegInfInterval.intersects(cNegInfInterval));
6888 assert(iNegInfInterval.intersects(iNegInfInterval));
6889
6890 //Verify Examples.
6891 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
6892 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
6893 assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
6894
6895 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4))));
6896 assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1))));
6897
6898 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 5, 4))));
6899 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2013, 7, 9))));
6900 }
6901
6902 //Test NegInfInterval's intersection().
6903 @safe unittest
6904 {
6905 import std.datetime.date;
6906
6907 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6908
testInterval(I,J)6909 static void testInterval(I, J)(in I interval1, in J interval2)
6910 {
6911 interval1.intersection(interval2);
6912 }
6913
6914 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
6915
6916 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
6917 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
6918
6919 assertThrown!DateTimeException(testInterval(negInfInterval, PosInfInterval!Date(Date(2012, 1, 7))));
6920 assertThrown!DateTimeException(testInterval(negInfInterval, PosInfInterval!Date(Date(2012, 1, 8))));
6921
6922 assert(negInfInterval.intersection(negInfInterval) == negInfInterval);
6923 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) ==
6924 Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)));
6925 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==
6926 Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7)));
6927 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==
6928 Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)));
6929 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==
6930 Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)));
6931 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==
6932 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
6933 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==
6934 Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
6935 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==
6936 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)));
6937 assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==
6938 Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));
6939 assert(negInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==
6940 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
6941 assert(negInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==
6942 Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
6943
6944 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2010, 7, 3)));
6945 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2010, 7, 4)));
6946 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2010, 7, 5)));
6947 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 6)));
6948 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7)));
6949 assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 7)));
6950
6951 assert(NegInfInterval!Date(Date(2010, 7, 3)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 3)));
6952 assert(NegInfInterval!Date(Date(2010, 7, 4)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 4)));
6953 assert(NegInfInterval!Date(Date(2010, 7, 5)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 5)));
6954 assert(NegInfInterval!Date(Date(2012, 1, 6)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 6)));
6955 assert(NegInfInterval!Date(Date(2012, 1, 7)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));
6956 assert(NegInfInterval!Date(Date(2012, 1, 8)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));
6957
6958 assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) ==
6959 Interval!Date(Date(2010, 7, 3), Date(2012, 1 ,7)));
6960 assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) ==
6961 Interval!Date(Date(2010, 7, 4), Date(2012, 1 ,7)));
6962 assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) ==
6963 Interval!Date(Date(2010, 7, 5), Date(2012, 1 ,7)));
6964 assert(negInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) ==
6965 Interval!Date(Date(2012, 1, 6), Date(2012, 1 ,7)));
6966
6967 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6968 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6969 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
6970 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6971 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6972 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
6973 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6974 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
6975 assert(!negInfInterval.intersection(interval).empty);
6976 assert(!negInfInterval.intersection(cInterval).empty);
6977 assert(!negInfInterval.intersection(iInterval).empty);
6978 assert(!negInfInterval.intersection(posInfInterval).empty);
6979 assert(!negInfInterval.intersection(cPosInfInterval).empty);
6980 assert(!negInfInterval.intersection(iPosInfInterval).empty);
6981 assert(!negInfInterval.intersection(negInfInterval).empty);
6982 assert(!negInfInterval.intersection(cNegInfInterval).empty);
6983 assert(!negInfInterval.intersection(iNegInfInterval).empty);
6984 assert(!cNegInfInterval.intersection(interval).empty);
6985 assert(!cNegInfInterval.intersection(cInterval).empty);
6986 assert(!cNegInfInterval.intersection(iInterval).empty);
6987 assert(!cNegInfInterval.intersection(posInfInterval).empty);
6988 assert(!cNegInfInterval.intersection(cPosInfInterval).empty);
6989 assert(!cNegInfInterval.intersection(iPosInfInterval).empty);
6990 assert(!cNegInfInterval.intersection(negInfInterval).empty);
6991 assert(!cNegInfInterval.intersection(cNegInfInterval).empty);
6992 assert(!cNegInfInterval.intersection(iNegInfInterval).empty);
6993 assert(!iNegInfInterval.intersection(interval).empty);
6994 assert(!iNegInfInterval.intersection(cInterval).empty);
6995 assert(!iNegInfInterval.intersection(iInterval).empty);
6996 assert(!iNegInfInterval.intersection(posInfInterval).empty);
6997 assert(!iNegInfInterval.intersection(cPosInfInterval).empty);
6998 assert(!iNegInfInterval.intersection(iPosInfInterval).empty);
6999 assert(!iNegInfInterval.intersection(negInfInterval).empty);
7000 assert(!iNegInfInterval.intersection(cNegInfInterval).empty);
7001 assert(!iNegInfInterval.intersection(iNegInfInterval).empty);
7002
7003 //Verify Examples.
7004 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
7005 Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)));
7006 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==
7007 Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1)));
7008
7009 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) ==
7010 Interval!Date(Date(1990, 7, 6), Date(2012, 3, 1)));
7011 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) ==
7012 Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1)));
7013
7014 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) ==
7015 NegInfInterval!Date(Date(1999, 7, 6)));
7016 assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) ==
7017 NegInfInterval!Date(Date(2012, 3, 1)));
7018 }
7019
7020 //Test NegInfInterval's isAdjacent().
7021 @safe unittest
7022 {
7023 import std.datetime.date;
7024
7025 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7026
7027 static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval)
7028 {
7029 negInfInterval.isAdjacent(interval);
7030 }
7031
7032 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
7033
7034 assert(!negInfInterval.isAdjacent(negInfInterval));
7035 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
7036 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
7037 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
7038 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
7039 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
7040 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
7041 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
7042 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
7043 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
7044 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
7045 assert(negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
7046 assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
7047
7048 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3))));
7049 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4))));
7050 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5))));
7051 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6))));
7052 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7))));
7053 assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8))));
7054
7055 assert(!NegInfInterval!Date(Date(2010, 7, 3)).isAdjacent(negInfInterval));
7056 assert(!NegInfInterval!Date(Date(2010, 7, 4)).isAdjacent(negInfInterval));
7057 assert(!NegInfInterval!Date(Date(2010, 7, 5)).isAdjacent(negInfInterval));
7058 assert(!NegInfInterval!Date(Date(2012, 1, 6)).isAdjacent(negInfInterval));
7059 assert(!NegInfInterval!Date(Date(2012, 1, 7)).isAdjacent(negInfInterval));
7060 assert(!NegInfInterval!Date(Date(2012, 1, 8)).isAdjacent(negInfInterval));
7061
7062 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3))));
7063 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4))));
7064 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5))));
7065 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6))));
7066 assert(negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7))));
7067 assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8))));
7068
7069 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
7070 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
7071 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
7072 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
7073 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
7074 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
7075 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7076 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7077 assert(!negInfInterval.isAdjacent(interval));
7078 assert(!negInfInterval.isAdjacent(cInterval));
7079 assert(!negInfInterval.isAdjacent(iInterval));
7080 assert(!negInfInterval.isAdjacent(posInfInterval));
7081 assert(!negInfInterval.isAdjacent(cPosInfInterval));
7082 assert(!negInfInterval.isAdjacent(iPosInfInterval));
7083 assert(!negInfInterval.isAdjacent(negInfInterval));
7084 assert(!negInfInterval.isAdjacent(cNegInfInterval));
7085 assert(!negInfInterval.isAdjacent(iNegInfInterval));
7086 assert(!cNegInfInterval.isAdjacent(interval));
7087 assert(!cNegInfInterval.isAdjacent(cInterval));
7088 assert(!cNegInfInterval.isAdjacent(iInterval));
7089 assert(!cNegInfInterval.isAdjacent(posInfInterval));
7090 assert(!cNegInfInterval.isAdjacent(cPosInfInterval));
7091 assert(!cNegInfInterval.isAdjacent(iPosInfInterval));
7092 assert(!cNegInfInterval.isAdjacent(negInfInterval));
7093 assert(!cNegInfInterval.isAdjacent(cNegInfInterval));
7094 assert(!cNegInfInterval.isAdjacent(iNegInfInterval));
7095 assert(!iNegInfInterval.isAdjacent(interval));
7096 assert(!iNegInfInterval.isAdjacent(cInterval));
7097 assert(!iNegInfInterval.isAdjacent(iInterval));
7098 assert(!iNegInfInterval.isAdjacent(posInfInterval));
7099 assert(!iNegInfInterval.isAdjacent(cPosInfInterval));
7100 assert(!iNegInfInterval.isAdjacent(iPosInfInterval));
7101 assert(!iNegInfInterval.isAdjacent(negInfInterval));
7102 assert(!iNegInfInterval.isAdjacent(cNegInfInterval));
7103 assert(!iNegInfInterval.isAdjacent(iNegInfInterval));
7104
7105 //Verify Examples.
7106 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
7107 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1))));
7108 assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2012, 3, 1), Date(2019, 2, 2))));
7109 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
7110
7111 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4))));
7112 assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1))));
7113
7114 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 5, 4))));
7115 assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(2012, 3, 1))));
7116 }
7117
7118 //Test NegInfInterval's merge().
7119 @safe unittest
7120 {
7121 import std.datetime.date;
7122
7123 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7124
testInterval(I,J)7125 static void testInterval(I, J)(in I interval1, in J interval2)
7126 {
7127 interval1.merge(interval2);
7128 }
7129
7130 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
7131
7132 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
7133
7134 assert(negInfInterval.merge(negInfInterval) == negInfInterval);
7135 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) ==
7136 NegInfInterval!Date(Date(2012, 1, 7)));
7137 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==
7138 NegInfInterval!Date(Date(2013, 7, 3)));
7139 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==
7140 NegInfInterval!Date(Date(2012, 1, 7)));
7141 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==
7142 NegInfInterval!Date(Date(2012, 1, 7)));
7143 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==
7144 NegInfInterval!Date(Date(2012, 1, 7)));
7145 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==
7146 NegInfInterval!Date(Date(2012, 1, 8)));
7147 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==
7148 NegInfInterval!Date(Date(2012, 1, 7)));
7149 assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==
7150 NegInfInterval!Date(Date(2012, 1, 7)));
7151 assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==
7152 NegInfInterval!Date(Date(2012, 1, 7)));
7153 assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==
7154 NegInfInterval!Date(Date(2012, 1, 8)));
7155 assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==
7156 NegInfInterval!Date(Date(2012, 1, 8)));
7157
7158 assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7)));
7159 assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7)));
7160 assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7)));
7161 assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7)));
7162 assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7)));
7163 assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8)));
7164
7165 assert(NegInfInterval!Date(Date(2010, 7, 3)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));
7166 assert(NegInfInterval!Date(Date(2010, 7, 4)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));
7167 assert(NegInfInterval!Date(Date(2010, 7, 5)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));
7168 assert(NegInfInterval!Date(Date(2012, 1, 6)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));
7169 assert(NegInfInterval!Date(Date(2012, 1, 7)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));
7170 assert(NegInfInterval!Date(Date(2012, 1, 8)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 8)));
7171
7172 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 3)))));
7173 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 4)))));
7174 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 5)))));
7175 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 6)))));
7176 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 7)))));
7177 static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 8)))));
7178
7179 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
7180 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
7181 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
7182 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
7183 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
7184 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
7185 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7186 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7187 assert(!negInfInterval.merge(interval).empty);
7188 assert(!negInfInterval.merge(cInterval).empty);
7189 assert(!negInfInterval.merge(iInterval).empty);
7190 static assert(!__traits(compiles, negInfInterval.merge(posInfInterval)));
7191 static assert(!__traits(compiles, negInfInterval.merge(cPosInfInterval)));
7192 static assert(!__traits(compiles, negInfInterval.merge(iPosInfInterval)));
7193 assert(!negInfInterval.merge(negInfInterval).empty);
7194 assert(!negInfInterval.merge(cNegInfInterval).empty);
7195 assert(!negInfInterval.merge(iNegInfInterval).empty);
7196 assert(!cNegInfInterval.merge(interval).empty);
7197 assert(!cNegInfInterval.merge(cInterval).empty);
7198 assert(!cNegInfInterval.merge(iInterval).empty);
7199 static assert(!__traits(compiles, cNegInfInterval.merge(posInfInterval)));
7200 static assert(!__traits(compiles, cNegInfInterval.merge(cPosInfInterval)));
7201 static assert(!__traits(compiles, cNegInfInterval.merge(iPosInfInterval)));
7202 assert(!cNegInfInterval.merge(negInfInterval).empty);
7203 assert(!cNegInfInterval.merge(cNegInfInterval).empty);
7204 assert(!cNegInfInterval.merge(iNegInfInterval).empty);
7205 assert(!iNegInfInterval.merge(interval).empty);
7206 assert(!iNegInfInterval.merge(cInterval).empty);
7207 assert(!iNegInfInterval.merge(iInterval).empty);
7208 static assert(!__traits(compiles, iNegInfInterval.merge(posInfInterval)));
7209 static assert(!__traits(compiles, iNegInfInterval.merge(cPosInfInterval)));
7210 static assert(!__traits(compiles, iNegInfInterval.merge(iPosInfInterval)));
7211 assert(!iNegInfInterval.merge(negInfInterval).empty);
7212 assert(!iNegInfInterval.merge(cNegInfInterval).empty);
7213 assert(!iNegInfInterval.merge(iNegInfInterval).empty);
7214
7215 //Verify Examples.
7216 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
7217 NegInfInterval!Date(Date(2012, 3, 1)));
7218 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==
7219 NegInfInterval!Date(Date(2015, 9, 2)));
7220
7221 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1999, 7, 6))) ==
7222 NegInfInterval!Date(Date(2012, 3, 1)));
7223 assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) ==
7224 NegInfInterval!Date(Date(2013, 1, 12)));
7225 }
7226
7227 //Test NegInfInterval's span().
7228 @safe unittest
7229 {
7230 import std.datetime.date;
7231
7232 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7233
testInterval(I,J)7234 static void testInterval(I, J)(in I interval1, in J interval2)
7235 {
7236 interval1.span(interval2);
7237 }
7238
7239 assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
7240
7241 assert(negInfInterval.span(negInfInterval) == negInfInterval);
7242 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) ==
7243 NegInfInterval!Date(Date(2012, 1, 7)));
7244 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) ==
7245 NegInfInterval!Date(Date(2013, 7, 3)));
7246 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) ==
7247 NegInfInterval!Date(Date(2012, 1, 7)));
7248 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) ==
7249 NegInfInterval!Date(Date(2012, 1, 7)));
7250 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) ==
7251 NegInfInterval!Date(Date(2012, 1, 7)));
7252 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) ==
7253 NegInfInterval!Date(Date(2012, 1, 8)));
7254 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) ==
7255 NegInfInterval!Date(Date(2012, 1, 7)));
7256 assert(negInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) ==
7257 NegInfInterval!Date(Date(2012, 1, 7)));
7258 assert(negInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) ==
7259 NegInfInterval!Date(Date(2012, 1, 7)));
7260 assert(negInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) ==
7261 NegInfInterval!Date(Date(2012, 1, 8)));
7262 assert(negInfInterval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) ==
7263 NegInfInterval!Date(Date(2012, 1, 8)));
7264 assert(negInfInterval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) ==
7265 NegInfInterval!Date(Date(2012, 1, 9)));
7266
7267 assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7)));
7268 assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7)));
7269 assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7)));
7270 assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7)));
7271 assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7)));
7272 assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8)));
7273
7274 assert(NegInfInterval!Date(Date(2010, 7, 3)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));
7275 assert(NegInfInterval!Date(Date(2010, 7, 4)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));
7276 assert(NegInfInterval!Date(Date(2010, 7, 5)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));
7277 assert(NegInfInterval!Date(Date(2012, 1, 6)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));
7278 assert(NegInfInterval!Date(Date(2012, 1, 7)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7)));
7279 assert(NegInfInterval!Date(Date(2012, 1, 8)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 8)));
7280
7281 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 3)))));
7282 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 4)))));
7283 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 5)))));
7284 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 6)))));
7285 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 7)))));
7286 static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 8)))));
7287
7288 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
7289 const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
7290 immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
7291 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
7292 const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
7293 immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
7294 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7295 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7296 assert(!negInfInterval.span(interval).empty);
7297 assert(!negInfInterval.span(cInterval).empty);
7298 assert(!negInfInterval.span(iInterval).empty);
7299 static assert(!__traits(compiles, negInfInterval.span(posInfInterval)));
7300 static assert(!__traits(compiles, negInfInterval.span(cPosInfInterval)));
7301 static assert(!__traits(compiles, negInfInterval.span(iPosInfInterval)));
7302 assert(!negInfInterval.span(negInfInterval).empty);
7303 assert(!negInfInterval.span(cNegInfInterval).empty);
7304 assert(!negInfInterval.span(iNegInfInterval).empty);
7305 assert(!cNegInfInterval.span(interval).empty);
7306 assert(!cNegInfInterval.span(cInterval).empty);
7307 assert(!cNegInfInterval.span(iInterval).empty);
7308 static assert(!__traits(compiles, cNegInfInterval.span(posInfInterval)));
7309 static assert(!__traits(compiles, cNegInfInterval.span(cPosInfInterval)));
7310 static assert(!__traits(compiles, cNegInfInterval.span(iPosInfInterval)));
7311 assert(!cNegInfInterval.span(negInfInterval).empty);
7312 assert(!cNegInfInterval.span(cNegInfInterval).empty);
7313 assert(!cNegInfInterval.span(iNegInfInterval).empty);
7314 assert(!iNegInfInterval.span(interval).empty);
7315 assert(!iNegInfInterval.span(cInterval).empty);
7316 assert(!iNegInfInterval.span(iInterval).empty);
7317 static assert(!__traits(compiles, iNegInfInterval.span(posInfInterval)));
7318 static assert(!__traits(compiles, iNegInfInterval.span(cPosInfInterval)));
7319 static assert(!__traits(compiles, iNegInfInterval.span(iPosInfInterval)));
7320 assert(!iNegInfInterval.span(negInfInterval).empty);
7321 assert(!iNegInfInterval.span(cNegInfInterval).empty);
7322 assert(!iNegInfInterval.span(iNegInfInterval).empty);
7323
7324 //Verify Examples.
7325 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
7326 NegInfInterval!Date(Date(2012, 3, 1)));
7327 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==
7328 NegInfInterval!Date(Date(2015, 9, 2)));
7329 assert(NegInfInterval!Date(Date(1600, 1, 7)).span(Interval!Date(Date(2012, 3, 11), Date(2017, 7, 1))) ==
7330 NegInfInterval!Date(Date(2017, 7, 1)));
7331
7332 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1999, 7, 6))) ==
7333 NegInfInterval!Date(Date(2012, 3, 1)));
7334 assert(NegInfInterval!Date(Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) ==
7335 NegInfInterval!Date(Date(2013, 1, 12)));
7336 }
7337
7338 //Test NegInfInterval's shift().
7339 @safe unittest
7340 {
7341 import std.datetime.date;
7342
7343 auto interval = NegInfInterval!Date(Date(2012, 1, 7));
7344
testInterval(I)7345 static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__)
7346 {
7347 interval.shift(duration);
7348 assert(interval == expected);
7349 }
7350
7351 testInterval(interval, dur!"days"(22), NegInfInterval!Date(Date(2012, 1, 29)));
7352 testInterval(interval, dur!"days"(-22), NegInfInterval!Date(Date(2011, 12, 16)));
7353
7354 const cInterval = NegInfInterval!Date(Date(2012, 1, 7));
7355 immutable iInterval = NegInfInterval!Date(Date(2012, 1, 7));
7356 static assert(!__traits(compiles, cInterval.shift(dur!"days"(5))));
7357 static assert(!__traits(compiles, iInterval.shift(dur!"days"(5))));
7358
7359 //Verify Examples.
7360 auto interval1 = NegInfInterval!Date(Date(2012, 4, 5));
7361 auto interval2 = NegInfInterval!Date(Date(2012, 4, 5));
7362
7363 interval1.shift(dur!"days"(50));
7364 assert(interval1 == NegInfInterval!Date(Date(2012, 5, 25)));
7365
7366 interval2.shift(dur!"days"(-50));
7367 assert(interval2 == NegInfInterval!Date( Date(2012, 2, 15)));
7368 }
7369
7370 //Test NegInfInterval's shift(int, int, AllowDayOverflow).
7371 @safe unittest
7372 {
7373 import std.datetime.date;
7374
7375 {
7376 auto interval = NegInfInterval!Date(Date(2012, 1, 7));
7377
testIntervalFail(I)7378 static void testIntervalFail(I)(I interval, int years, int months)
7379 {
7380 interval.shift(years, months);
7381 }
7382
testInterval(I)7383 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow,
7384 in I expected, size_t line = __LINE__)
7385 {
7386 interval.shift(years, months, allow);
7387 assert(interval == expected);
7388 }
7389
7390 testInterval(interval, 5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2017, 1, 7)));
7391 testInterval(interval, -5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2007, 1, 7)));
7392
7393 auto interval2 = NegInfInterval!Date(Date(2010, 5, 31));
7394
7395 testInterval(interval2, 1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 7, 1)));
7396 testInterval(interval2, 1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 5, 1)));
7397 testInterval(interval2, -1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 5, 1)));
7398 testInterval(interval2, -1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 7, 1)));
7399
7400 testInterval(interval2, 1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 6, 30)));
7401 testInterval(interval2, 1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 4, 30)));
7402 testInterval(interval2, -1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 4, 30)));
7403 testInterval(interval2, -1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 6, 30)));
7404 }
7405
7406 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7407 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7408 static assert(!__traits(compiles, cNegInfInterval.shift(1)));
7409 static assert(!__traits(compiles, iNegInfInterval.shift(1)));
7410
7411 //Verify Examples.
7412 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));
7413 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));
7414
7415 interval1.shift(2);
7416 assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1)));
7417
7418 interval2.shift(-2);
7419 assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1)));
7420 }
7421
7422 //Test NegInfInterval's expand().
7423 @safe unittest
7424 {
7425 import std.datetime.date;
7426
7427 auto interval = NegInfInterval!Date(Date(2012, 1, 7));
7428
testInterval(I)7429 static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__)
7430 {
7431 interval.expand(duration);
7432 assert(interval == expected);
7433 }
7434
7435 testInterval(interval, dur!"days"(22), NegInfInterval!Date(Date(2012, 1, 29)));
7436 testInterval(interval, dur!"days"(-22), NegInfInterval!Date(Date(2011, 12, 16)));
7437
7438 const cInterval = NegInfInterval!Date(Date(2012, 1, 7));
7439 immutable iInterval = NegInfInterval!Date(Date(2012, 1, 7));
7440 static assert(!__traits(compiles, cInterval.expand(dur!"days"(5))));
7441 static assert(!__traits(compiles, iInterval.expand(dur!"days"(5))));
7442
7443 //Verify Examples.
7444 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));
7445 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));
7446
7447 interval1.expand(dur!"days"(2));
7448 assert(interval1 == NegInfInterval!Date(Date(2012, 3, 3)));
7449
7450 interval2.expand(dur!"days"(-2));
7451 assert(interval2 == NegInfInterval!Date(Date(2012, 2, 28)));
7452 }
7453
7454 //Test NegInfInterval's expand(int, int, AllowDayOverflow).
7455 @safe unittest
7456 {
7457 import std.datetime.date;
7458
7459 {
7460 auto interval = NegInfInterval!Date(Date(2012, 1, 7));
7461
testInterval(I)7462 static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow,
7463 in I expected, size_t line = __LINE__)
7464 {
7465 interval.expand(years, months, allow);
7466 assert(interval == expected);
7467 }
7468
7469 testInterval(interval, 5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2017, 1, 7)));
7470 testInterval(interval, -5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2007, 1, 7)));
7471
7472 auto interval2 = NegInfInterval!Date(Date(2010, 5, 31));
7473
7474 testInterval(interval2, 1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 7, 1)));
7475 testInterval(interval2, 1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 5, 1)));
7476 testInterval(interval2, -1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 5, 1)));
7477 testInterval(interval2, -1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 7, 1)));
7478
7479 testInterval(interval2, 1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 6, 30)));
7480 testInterval(interval2, 1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 4, 30)));
7481 testInterval(interval2, -1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 4, 30)));
7482 testInterval(interval2, -1, 1, AllowDayOverflow.no, NegInfInterval!Date( Date(2009, 6, 30)));
7483 }
7484
7485 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7486 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7487 static assert(!__traits(compiles, cNegInfInterval.expand(1)));
7488 static assert(!__traits(compiles, iNegInfInterval.expand(1)));
7489
7490 //Verify Examples.
7491 auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));
7492 auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));
7493
7494 interval1.expand(2);
7495 assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1)));
7496
7497 interval2.expand(-2);
7498 assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1)));
7499 }
7500
7501 //Test NegInfInterval's bwdRange().
7502 @system unittest
7503 {
7504 import std.datetime.date;
7505
7506 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7507
7508 static void testInterval(NegInfInterval!Date negInfInterval)
7509 {
7510 negInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront();
7511 }
7512
7513 assertThrown!DateTimeException(testInterval(negInfInterval));
7514
7515 assert(NegInfInterval!Date(Date(2010, 10, 1)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front ==
7516 Date(2010, 10, 1));
7517
7518 assert(NegInfInterval!Date(Date(2010, 10, 1)).bwdRange(
7519 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 24));
7520
7521 //Verify Examples.
7522 auto interval = NegInfInterval!Date(Date(2010, 9, 9));
delegate(in Date date)7523 auto func = delegate (in Date date)
7524 {
7525 if ((date.day & 1) == 0)
7526 return date - dur!"days"(2);
7527 return date - dur!"days"(1);
7528 };
7529 auto range = interval.bwdRange(func);
7530
7531 //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8).
7532 assert(range.front == Date(2010, 9, 9));
7533
7534 range.popFront();
7535 assert(range.front == Date(2010, 9, 8));
7536
7537 range.popFront();
7538 assert(range.front == Date(2010, 9, 6));
7539
7540 range.popFront();
7541 assert(range.front == Date(2010, 9, 4));
7542
7543 range.popFront();
7544 assert(range.front == Date(2010, 9, 2));
7545
7546 range.popFront();
7547 assert(!range.empty);
7548
7549 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7550 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7551 assert(!cNegInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty);
7552 assert(!iNegInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty);
7553 }
7554
7555 //Test NegInfInterval's toString().
7556 @safe unittest
7557 {
7558 import std.datetime.date;
7559
7560 assert(NegInfInterval!Date(Date(2012, 1, 7)).toString() == "[-∞ - 2012-Jan-07)");
7561
7562 const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7563 immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
7564 assert(cNegInfInterval.toString());
7565 assert(iNegInfInterval.toString());
7566 }
7567
7568
7569 /++
7570 Range-generating function.
7571
7572 Returns a delegate which returns the next time point with the given
7573 $(D DayOfWeek) in a range.
7574
7575 Using this delegate allows iteration over successive time points which
7576 are all the same day of the week. e.g. passing $(D DayOfWeek.mon) to
7577 $(D everyDayOfWeek) would result in a delegate which could be used to
7578 iterate over all of the Mondays in a range.
7579
7580 Params:
7581 dir = The direction to iterate in. If passing the return value to
7582 $(D fwdRange), use $(D Direction.fwd). If passing it to
7583 $(D bwdRange), use $(D Direction.bwd).
7584 dayOfWeek = The week that each time point in the range will be.
7585 +/
7586 TP delegate(in TP) everyDayOfWeek(TP, Direction dir = Direction.fwd)(DayOfWeek dayOfWeek) nothrow
7587 if (isTimePoint!TP &&
7588 (dir == Direction.fwd || dir == Direction.bwd) &&
7589 __traits(hasMember, TP, "dayOfWeek") &&
7590 !__traits(isStaticFunction, TP.dayOfWeek) &&
7591 is(typeof(TP.dayOfWeek) == DayOfWeek))
7592 {
func(in TP tp)7593 TP func(in TP tp)
7594 {
7595 TP retval = cast(TP) tp;
7596 immutable days = daysToDayOfWeek(retval.dayOfWeek, dayOfWeek);
7597
7598 static if (dir == Direction.fwd)
7599 immutable adjustedDays = days == 0 ? 7 : days;
7600 else
7601 immutable adjustedDays = days == 0 ? -7 : days - 7;
7602
7603 return retval += dur!"days"(adjustedDays);
7604 }
7605
7606 return &func;
7607 }
7608
7609 ///
7610 @system unittest
7611 {
7612 import std.datetime.date : Date, DayOfWeek;
7613
7614 auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27));
7615 auto func = everyDayOfWeek!Date(DayOfWeek.mon);
7616 auto range = interval.fwdRange(func);
7617
7618 // A Thursday. Using PopFirst.yes would have made this Date(2010, 9, 6).
7619 assert(range.front == Date(2010, 9, 2));
7620
7621 range.popFront();
7622 assert(range.front == Date(2010, 9, 6));
7623
7624 range.popFront();
7625 assert(range.front == Date(2010, 9, 13));
7626
7627 range.popFront();
7628 assert(range.front == Date(2010, 9, 20));
7629
7630 range.popFront();
7631 assert(range.empty);
7632 }
7633
7634 @system unittest
7635 {
7636 import std.datetime.date;
7637 import std.datetime.systime;
7638
7639 auto funcFwd = everyDayOfWeek!Date(DayOfWeek.mon);
7640 auto funcBwd = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.mon);
7641
7642 assert(funcFwd(Date(2010, 8, 28)) == Date(2010, 8, 30));
7643 assert(funcFwd(Date(2010, 8, 29)) == Date(2010, 8, 30));
7644 assert(funcFwd(Date(2010, 8, 30)) == Date(2010, 9, 6));
7645 assert(funcFwd(Date(2010, 8, 31)) == Date(2010, 9, 6));
7646 assert(funcFwd(Date(2010, 9, 1)) == Date(2010, 9, 6));
7647 assert(funcFwd(Date(2010, 9, 2)) == Date(2010, 9, 6));
7648 assert(funcFwd(Date(2010, 9, 3)) == Date(2010, 9, 6));
7649 assert(funcFwd(Date(2010, 9, 4)) == Date(2010, 9, 6));
7650 assert(funcFwd(Date(2010, 9, 5)) == Date(2010, 9, 6));
7651 assert(funcFwd(Date(2010, 9, 6)) == Date(2010, 9, 13));
7652 assert(funcFwd(Date(2010, 9, 7)) == Date(2010, 9, 13));
7653
7654 assert(funcBwd(Date(2010, 8, 28)) == Date(2010, 8, 23));
7655 assert(funcBwd(Date(2010, 8, 29)) == Date(2010, 8, 23));
7656 assert(funcBwd(Date(2010, 8, 30)) == Date(2010, 8, 23));
7657 assert(funcBwd(Date(2010, 8, 31)) == Date(2010, 8, 30));
7658 assert(funcBwd(Date(2010, 9, 1)) == Date(2010, 8, 30));
7659 assert(funcBwd(Date(2010, 9, 2)) == Date(2010, 8, 30));
7660 assert(funcBwd(Date(2010, 9, 3)) == Date(2010, 8, 30));
7661 assert(funcBwd(Date(2010, 9, 4)) == Date(2010, 8, 30));
7662 assert(funcBwd(Date(2010, 9, 5)) == Date(2010, 8, 30));
7663 assert(funcBwd(Date(2010, 9, 6)) == Date(2010, 8, 30));
7664 assert(funcBwd(Date(2010, 9, 7)) == Date(2010, 9, 6));
7665
7666 static assert(!__traits(compiles, everyDayOfWeek!TimeOfDay(DayOfWeek.mon)));
7667 assert(everyDayOfWeek!DateTime(DayOfWeek.mon) !is null);
7668 assert(everyDayOfWeek!SysTime(DayOfWeek.mon) !is null);
7669 }
7670
7671
7672 /++
7673 Range-generating function.
7674
7675 Returns a delegate which returns the next time point with the given month
7676 which would be reached by adding months to the given time point.
7677
7678 So, using this delegate allows iteration over successive time points
7679 which are in the same month but different years. For example,
7680 iterate over each successive December 25th in an interval by starting with a
7681 date which had the 25th as its day and passed $(D Month.dec) to
7682 $(D everyMonth) to create the delegate.
7683
7684 Since it wouldn't really make sense to be iterating over a specific month
7685 and end up with some of the time points in the succeeding month or two years
7686 after the previous time point, $(D AllowDayOverflow.no) is always used when
7687 calculating the next time point.
7688
7689 Params:
7690 dir = The direction to iterate in. If passing the return value to
7691 $(D fwdRange), use $(D Direction.fwd). If passing it to
7692 $(D bwdRange), use $(D Direction.bwd).
7693 month = The month that each time point in the range will be in
7694 (January is 1).
7695 +/
7696 TP delegate(in TP) everyMonth(TP, Direction dir = Direction.fwd)(int month)
7697 if (isTimePoint!TP &&
7698 (dir == Direction.fwd || dir == Direction.bwd) &&
7699 __traits(hasMember, TP, "month") &&
7700 !__traits(isStaticFunction, TP.month) &&
7701 is(typeof(TP.month) == Month))
7702 {
7703 import std.datetime.date : enforceValid, monthsToMonth;
7704
7705 enforceValid!"months"(month);
7706
func(in TP tp)7707 TP func(in TP tp)
7708 {
7709 TP retval = cast(TP) tp;
7710 immutable months = monthsToMonth(retval.month, month);
7711
7712 static if (dir == Direction.fwd)
7713 immutable adjustedMonths = months == 0 ? 12 : months;
7714 else
7715 immutable adjustedMonths = months == 0 ? -12 : months - 12;
7716
7717 retval.add!"months"(adjustedMonths, AllowDayOverflow.no);
7718
7719 if (retval.month != month)
7720 {
7721 retval.add!"months"(-1);
7722 assert(retval.month == month);
7723 }
7724
7725 return retval;
7726 }
7727
7728 return &func;
7729 }
7730
7731 ///
7732 @system unittest
7733 {
7734 import std.datetime.date : Date, Month;
7735
7736 auto interval = Interval!Date(Date(2000, 1, 30), Date(2004, 8, 5));
7737 auto func = everyMonth!Date(Month.feb);
7738 auto range = interval.fwdRange(func);
7739
7740 // Using PopFirst.yes would have made this Date(2010, 2, 29).
7741 assert(range.front == Date(2000, 1, 30));
7742
7743 range.popFront();
7744 assert(range.front == Date(2000, 2, 29));
7745
7746 range.popFront();
7747 assert(range.front == Date(2001, 2, 28));
7748
7749 range.popFront();
7750 assert(range.front == Date(2002, 2, 28));
7751
7752 range.popFront();
7753 assert(range.front == Date(2003, 2, 28));
7754
7755 range.popFront();
7756 assert(range.front == Date(2004, 2, 28));
7757
7758 range.popFront();
7759 assert(range.empty);
7760 }
7761
7762 @system unittest
7763 {
7764 import std.datetime.date;
7765 import std.datetime.systime;
7766
7767 auto funcFwd = everyMonth!Date(Month.jun);
7768 auto funcBwd = everyMonth!(Date, Direction.bwd)(Month.jun);
7769
7770 assert(funcFwd(Date(2010, 5, 31)) == Date(2010, 6, 30));
7771 assert(funcFwd(Date(2010, 6, 30)) == Date(2011, 6, 30));
7772 assert(funcFwd(Date(2010, 7, 31)) == Date(2011, 6, 30));
7773 assert(funcFwd(Date(2010, 8, 31)) == Date(2011, 6, 30));
7774 assert(funcFwd(Date(2010, 9, 30)) == Date(2011, 6, 30));
7775 assert(funcFwd(Date(2010, 10, 31)) == Date(2011, 6, 30));
7776 assert(funcFwd(Date(2010, 11, 30)) == Date(2011, 6, 30));
7777 assert(funcFwd(Date(2010, 12, 31)) == Date(2011, 6, 30));
7778 assert(funcFwd(Date(2011, 1, 31)) == Date(2011, 6, 30));
7779 assert(funcFwd(Date(2011, 2, 28)) == Date(2011, 6, 28));
7780 assert(funcFwd(Date(2011, 3, 31)) == Date(2011, 6, 30));
7781 assert(funcFwd(Date(2011, 4, 30)) == Date(2011, 6, 30));
7782 assert(funcFwd(Date(2011, 5, 31)) == Date(2011, 6, 30));
7783 assert(funcFwd(Date(2011, 6, 30)) == Date(2012, 6, 30));
7784 assert(funcFwd(Date(2011, 7, 31)) == Date(2012, 6, 30));
7785
7786 assert(funcBwd(Date(2010, 5, 31)) == Date(2009, 6, 30));
7787 assert(funcBwd(Date(2010, 6, 30)) == Date(2009, 6, 30));
7788 assert(funcBwd(Date(2010, 7, 31)) == Date(2010, 6, 30));
7789 assert(funcBwd(Date(2010, 8, 31)) == Date(2010, 6, 30));
7790 assert(funcBwd(Date(2010, 9, 30)) == Date(2010, 6, 30));
7791 assert(funcBwd(Date(2010, 10, 31)) == Date(2010, 6, 30));
7792 assert(funcBwd(Date(2010, 11, 30)) == Date(2010, 6, 30));
7793 assert(funcBwd(Date(2010, 12, 31)) == Date(2010, 6, 30));
7794 assert(funcBwd(Date(2011, 1, 31)) == Date(2010, 6, 30));
7795 assert(funcBwd(Date(2011, 2, 28)) == Date(2010, 6, 28));
7796 assert(funcBwd(Date(2011, 3, 31)) == Date(2010, 6, 30));
7797 assert(funcBwd(Date(2011, 4, 30)) == Date(2010, 6, 30));
7798 assert(funcBwd(Date(2011, 5, 31)) == Date(2010, 6, 30));
7799 assert(funcBwd(Date(2011, 6, 30)) == Date(2010, 6, 30));
7800 assert(funcBwd(Date(2011, 7, 30)) == Date(2011, 6, 30));
7801
7802 static assert(!__traits(compiles, everyMonth!TimeOfDay(Month.jan)));
7803 assert(everyMonth!DateTime(Month.jan) !is null);
7804 assert(everyMonth!SysTime(Month.jan) !is null);
7805 }
7806
7807
7808 /++
7809 Range-generating function.
7810
7811 Returns a delegate which returns the next time point which is the given
7812 duration later.
7813
7814 Using this delegate allows iteration over successive time points which
7815 are apart by the given duration e.g. passing $(D dur!"days"(3)) to
7816 $(D everyDuration) would result in a delegate which could be used to iterate
7817 over a range of days which are each 3 days apart.
7818
7819 Params:
7820 dir = The direction to iterate in. If passing the return value to
7821 $(D fwdRange), use $(D Direction.fwd). If passing it to
7822 $(D bwdRange), use $(D Direction.bwd).
7823 duration = The duration which separates each successive time point in
7824 the range.
7825 +/
7826 TP delegate(in TP) everyDuration(TP, Direction dir = Direction.fwd, D)(D duration) nothrow
7827 if (isTimePoint!TP &&
7828 __traits(compiles, TP.init + duration) &&
7829 (dir == Direction.fwd || dir == Direction.bwd))
7830 {
7831 TP func(in TP tp)
7832 {
7833 static if (dir == Direction.fwd)
7834 return tp + duration;
7835 else
7836 return tp - duration;
7837 }
7838
7839 return &func;
7840 }
7841
7842 ///
7843 @system unittest
7844 {
7845 import core.time : dur;
7846 import std.datetime.date : Date;
7847
7848 auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27));
7849 auto func = everyDuration!Date(dur!"days"(8));
7850 auto range = interval.fwdRange(func);
7851
7852 // Using PopFirst.yes would have made this Date(2010, 9, 10).
7853 assert(range.front == Date(2010, 9, 2));
7854
7855 range.popFront();
7856 assert(range.front == Date(2010, 9, 10));
7857
7858 range.popFront();
7859 assert(range.front == Date(2010, 9, 18));
7860
7861 range.popFront();
7862 assert(range.front == Date(2010, 9, 26));
7863
7864 range.popFront();
7865 assert(range.empty);
7866 }
7867
7868 @system unittest
7869 {
7870 import std.datetime.date;
7871 import std.datetime.systime;
7872
7873 auto funcFwd = everyDuration!Date(dur!"days"(27));
7874 auto funcBwd = everyDuration!(Date, Direction.bwd)(dur!"days"(27));
7875
7876 assert(funcFwd(Date(2009, 12, 25)) == Date(2010, 1, 21));
7877 assert(funcFwd(Date(2009, 12, 26)) == Date(2010, 1, 22));
7878 assert(funcFwd(Date(2009, 12, 27)) == Date(2010, 1, 23));
7879 assert(funcFwd(Date(2009, 12, 28)) == Date(2010, 1, 24));
7880
7881 assert(funcBwd(Date(2010, 1, 21)) == Date(2009, 12, 25));
7882 assert(funcBwd(Date(2010, 1, 22)) == Date(2009, 12, 26));
7883 assert(funcBwd(Date(2010, 1, 23)) == Date(2009, 12, 27));
7884 assert(funcBwd(Date(2010, 1, 24)) == Date(2009, 12, 28));
7885
7886 assert(everyDuration!Date(dur!"hnsecs"(1)) !is null);
7887 assert(everyDuration!TimeOfDay(dur!"hnsecs"(1)) !is null);
7888 assert(everyDuration!DateTime(dur!"hnsecs"(1)) !is null);
7889 assert(everyDuration!SysTime(dur!"hnsecs"(1)) !is null);
7890 }
7891
7892
7893 /++
7894 Range-generating function.
7895
7896 Returns a delegate which returns the next time point which is the given
7897 number of years, month, and duration later.
7898
7899 The difference between this version of $(D everyDuration) and the version
7900 which just takes a $(REF Duration, core,time) is that this one also takes
7901 the number of years and months (along with an $(D AllowDayOverflow) to
7902 indicate whether adding years and months should allow the days to overflow).
7903
7904 Note that if iterating forward, $(D add!"years"()) is called on the given
7905 time point, then $(D add!"months"()), and finally the duration is added
7906 to it. However, if iterating backwards, the duration is added first, then
7907 $(D add!"months"()) is called, and finally $(D add!"years"()) is called.
7908 That way, going backwards generates close to the same time points that
7909 iterating forward does, but since adding years and months is not entirely
7910 reversible (due to possible day overflow, regardless of whether
7911 $(D AllowDayOverflow.yes) or $(D AllowDayOverflow.no) is used), it can't be
7912 guaranteed that iterating backwards will give the same time points as
7913 iterating forward would have (even assuming that the end of the range is a
7914 time point which would be returned by the delegate when iterating forward
7915 from $(D begin)).
7916
7917 Params:
7918 dir = The direction to iterate in. If passing the return
7919 value to $(D fwdRange), use $(D Direction.fwd). If
7920 passing it to $(D bwdRange), use $(D Direction.bwd).
7921 years = The number of years to add to the time point passed to
7922 the delegate.
7923 months = The number of months to add to the time point passed to
7924 the delegate.
7925 allowOverflow = Whether the days should be allowed to overflow on
7926 $(D begin) and $(D end), causing their month to
7927 increment.
7928 duration = The duration to add to the time point passed to the
7929 delegate.
7930 +/
7931 TP delegate(in TP) everyDuration(TP, Direction dir = Direction.fwd, D)
7932 (int years,
7933 int months = 0,
7934 AllowDayOverflow allowOverflow = AllowDayOverflow.yes,
7935 D duration = dur!"days"(0)) nothrow
7936 if (isTimePoint!TP &&
7937 __traits(compiles, TP.init + duration) &&
7938 __traits(compiles, TP.init.add!"years"(years)) &&
7939 __traits(compiles, TP.init.add!"months"(months)) &&
7940 (dir == Direction.fwd || dir == Direction.bwd))
7941 {
7942 TP func(in TP tp)
7943 {
7944 static if (dir == Direction.fwd)
7945 {
7946 TP retval = cast(TP) tp;
7947
7948 retval.add!"years"(years, allowOverflow);
7949 retval.add!"months"(months, allowOverflow);
7950
7951 return retval + duration;
7952 }
7953 else
7954 {
7955 TP retval = tp - duration;
7956
7957 retval.add!"months"(-months, allowOverflow);
7958 retval.add!"years"(-years, allowOverflow);
7959
7960 return retval;
7961 }
7962 }
7963
7964 return &func;
7965 }
7966
7967 ///
7968 @system unittest
7969 {
7970 import core.time : dur;
7971 import std.datetime.date : AllowDayOverflow, Date;
7972
7973 auto interval = Interval!Date(Date(2010, 9, 2), Date(2025, 9, 27));
7974 auto func = everyDuration!Date(4, 1, AllowDayOverflow.yes, dur!"days"(2));
7975 auto range = interval.fwdRange(func);
7976
7977 // Using PopFirst.yes would have made this Date(2014, 10, 12).
7978 assert(range.front == Date(2010, 9, 2));
7979
7980 range.popFront();
7981 assert(range.front == Date(2014, 10, 4));
7982
7983 range.popFront();
7984 assert(range.front == Date(2018, 11, 6));
7985
7986 range.popFront();
7987 assert(range.front == Date(2022, 12, 8));
7988
7989 range.popFront();
7990 assert(range.empty);
7991 }
7992
7993 @system unittest
7994 {
7995 import std.datetime.date;
7996 import std.datetime.systime;
7997
7998 {
7999 auto funcFwd = everyDuration!Date(1, 2, AllowDayOverflow.yes, dur!"days"(3));
8000 auto funcBwd = everyDuration!(Date, Direction.bwd)(1, 2, AllowDayOverflow.yes, dur!"days"(3));
8001
8002 assert(funcFwd(Date(2009, 12, 25)) == Date(2011, 2, 28));
8003 assert(funcFwd(Date(2009, 12, 26)) == Date(2011, 3, 1));
8004 assert(funcFwd(Date(2009, 12, 27)) == Date(2011, 3, 2));
8005 assert(funcFwd(Date(2009, 12, 28)) == Date(2011, 3, 3));
8006 assert(funcFwd(Date(2009, 12, 29)) == Date(2011, 3, 4));
8007
8008 assert(funcBwd(Date(2011, 2, 28)) == Date(2009, 12, 25));
8009 assert(funcBwd(Date(2011, 3, 1)) == Date(2009, 12, 26));
8010 assert(funcBwd(Date(2011, 3, 2)) == Date(2009, 12, 27));
8011 assert(funcBwd(Date(2011, 3, 3)) == Date(2009, 12, 28));
8012 assert(funcBwd(Date(2011, 3, 4)) == Date(2010, 1, 1));
8013 }
8014
8015 {
8016 auto funcFwd = everyDuration!Date(1, 2, AllowDayOverflow.no, dur!"days"(3));
8017 auto funcBwd = everyDuration!(Date, Direction.bwd)(1, 2, AllowDayOverflow.yes, dur!"days"(3));
8018
8019 assert(funcFwd(Date(2009, 12, 25)) == Date(2011, 2, 28));
8020 assert(funcFwd(Date(2009, 12, 26)) == Date(2011, 3, 1));
8021 assert(funcFwd(Date(2009, 12, 27)) == Date(2011, 3, 2));
8022 assert(funcFwd(Date(2009, 12, 28)) == Date(2011, 3, 3));
8023 assert(funcFwd(Date(2009, 12, 29)) == Date(2011, 3, 3));
8024
8025 assert(funcBwd(Date(2011, 2, 28)) == Date(2009, 12, 25));
8026 assert(funcBwd(Date(2011, 3, 1)) == Date(2009, 12, 26));
8027 assert(funcBwd(Date(2011, 3, 2)) == Date(2009, 12, 27));
8028 assert(funcBwd(Date(2011, 3, 3)) == Date(2009, 12, 28));
8029 assert(funcBwd(Date(2011, 3, 4)) == Date(2010, 1, 1));
8030 }
8031
8032 assert(everyDuration!Date(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)) !is null);
8033 static assert(!__traits(compiles, everyDuration!TimeOfDay(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1))));
8034 assert(everyDuration!DateTime(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)) !is null);
8035 assert(everyDuration!SysTime(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)) !is null);
8036 }
8037
8038
8039 /++
8040 A range over an $(LREF Interval).
8041
8042 $(D IntervalRange) is only ever constructed by $(LREF Interval). However, when
8043 it is constructed, it is given a function, $(D func), which is used to
8044 generate the time points which are iterated over. $(D func) takes a time
8045 point and returns a time point of the same type. For instance,
8046 to iterate over all of the days in
8047 the interval $(D Interval!Date), pass a function to $(LREF Interval)'s
8048 $(D fwdRange) where that function took a $(REF Date,std,datetime,date) and
8049 returned a $(REF Date,std,datetime,date) which was one day later. That
8050 function would then be used by $(D IntervalRange)'s $(D popFront) to iterate
8051 over the $(REF Date,std,datetime,date)s in the interval.
8052
8053 If $(D dir == Direction.fwd), then a range iterates forward in time, whereas
8054 if $(D dir == Direction.bwd), then it iterates backwards in time. So, if
8055 $(D dir == Direction.fwd) then $(D front == interval.begin), whereas if
8056 $(D dir == Direction.bwd) then $(D front == interval.end). $(D func) must
8057 generate a time point going in the proper direction of iteration, or a
8058 $(REF DateTimeException,std,datetime,date) will be thrown. So, to iterate
8059 forward in time, the time point that $(D func) generates must be later in
8060 time than the one passed to it. If it's either identical or earlier in time,
8061 then a $(REF DateTimeException,std,datetime,date) will be thrown. To
8062 iterate backwards, then the generated time point must be before the time
8063 point which was passed in.
8064
8065 If the generated time point is ever passed the edge of the range in the
8066 proper direction, then the edge of that range will be used instead. So, if
8067 iterating forward, and the generated time point is past the interval's
8068 $(D end), then $(D front) becomes $(D end). If iterating backwards, and the
8069 generated time point is before $(D begin), then $(D front) becomes
8070 $(D begin). In either case, the range would then be empty.
8071
8072 Also note that while normally the $(D begin) of an interval is included in
8073 it and its $(D end) is excluded from it, if $(D dir == Direction.bwd), then
8074 $(D begin) is treated as excluded and $(D end) is treated as included. This
8075 allows for the same behavior in both directions. This works because none of
8076 $(LREF Interval)'s functions which care about whether $(D begin) or $(D end)
8077 is included or excluded are ever called by $(D IntervalRange). $(D interval)
8078 returns a normal interval, regardless of whether $(D dir == Direction.fwd)
8079 or if $(D dir == Direction.bwd), so any $(LREF Interval) functions which are
8080 called on it which care about whether $(D begin) or $(D end) are included or
8081 excluded will treat $(D begin) as included and $(D end) as excluded.
8082 +/
8083 struct IntervalRange(TP, Direction dir)
8084 if (isTimePoint!TP && dir != Direction.both)
8085 {
8086 public:
8087
8088 /++
8089 Params:
8090 rhs = The $(D IntervalRange) to assign to this one.
8091 +/
opAssign(ref IntervalRange rhs)8092 ref IntervalRange opAssign(ref IntervalRange rhs) pure nothrow
8093 {
8094 _interval = rhs._interval;
8095 _func = rhs._func;
8096 return this;
8097 }
8098
8099
8100 /++ Ditto +/
8101 ref IntervalRange opAssign(IntervalRange rhs) pure nothrow
8102 {
8103 return this = rhs;
8104 }
8105
8106
8107 /++
8108 Whether this $(D IntervalRange) is empty.
8109 +/
8110 @property bool empty() const pure nothrow
8111 {
8112 return _interval.empty;
8113 }
8114
8115
8116 /++
8117 The first time point in the range.
8118
8119 Throws:
8120 $(REF DateTimeException,std,datetime,date) if the range is empty.
8121 +/
8122 @property TP front() const pure
8123 {
8124 _enforceNotEmpty();
8125
8126 static if (dir == Direction.fwd)
8127 return _interval.begin;
8128 else
8129 return _interval.end;
8130 }
8131
8132
8133 /++
8134 Pops $(D front) from the range, using $(D func) to generate the next
8135 time point in the range. If the generated time point is beyond the edge
8136 of the range, then $(D front) is set to that edge, and the range is then
8137 empty. So, if iterating forwards, and the generated time point is
8138 greater than the interval's $(D end), then $(D front) is set to
8139 $(D end). If iterating backwards, and the generated time point is less
8140 than the interval's $(D begin), then $(D front) is set to $(D begin).
8141
8142 Throws:
8143 $(REF DateTimeException,std,datetime,date) if the range is empty
8144 or if the generated time point is in the wrong direction (i.e. if
8145 iterating forward and the generated time point is before $(D front),
8146 or if iterating backwards and the generated time point is after
8147 $(D front)).
8148 +/
8149 void popFront()
8150 {
8151 _enforceNotEmpty();
8152
8153 static if (dir == Direction.fwd)
8154 {
8155 auto begin = _func(_interval.begin);
8156
8157 if (begin > _interval.end)
8158 begin = _interval.end;
8159
8160 _enforceCorrectDirection(begin);
8161
8162 _interval.begin = begin;
8163 }
8164 else
8165 {
8166 auto end = _func(_interval.end);
8167
8168 if (end < _interval.begin)
8169 end = _interval.begin;
8170
8171 _enforceCorrectDirection(end);
8172
8173 _interval.end = end;
8174 }
8175 }
8176
8177
8178 /++
8179 Returns a copy of $(D this).
8180 +/
8181 @property IntervalRange save() pure nothrow
8182 {
8183 return this;
8184 }
8185
8186
8187 /++
8188 The interval that this $(D IntervalRange) currently covers.
8189 +/
8190 @property Interval!TP interval() const pure nothrow
8191 {
8192 return cast(Interval!TP)_interval;
8193 }
8194
8195
8196 /++
8197 The function used to generate the next time point in the range.
8198 +/
8199 TP delegate(in TP) func() pure nothrow @property
8200 {
8201 return _func;
8202 }
8203
8204
8205 /++
8206 The $(D Direction) that this range iterates in.
8207 +/
8208 @property Direction direction() const pure nothrow
8209 {
8210 return dir;
8211 }
8212
8213
8214 private:
8215
8216 /+
8217 Params:
8218 interval = The interval that this range covers.
8219 func = The function used to generate the time points which are
8220 iterated over.
8221 +/
8222 this(in Interval!TP interval, TP delegate(in TP) func) pure nothrow
8223 {
8224 _func = func;
8225 _interval = interval;
8226 }
8227
8228
8229 /+
8230 Throws:
8231 $(REF DateTimeException,std,datetime,date) if this interval is
8232 empty.
8233 +/
8234 void _enforceNotEmpty(size_t line = __LINE__) const pure
8235 {
8236 if (empty)
8237 throw new DateTimeException("Invalid operation for an empty IntervalRange.", __FILE__, line);
8238 }
8239
8240
8241 /+
8242 Throws:
8243 $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is
8244 in the wrong direction.
8245 +/
8246 void _enforceCorrectDirection(in TP newTP, size_t line = __LINE__) const
8247 {
8248 import std.format : format;
8249
8250 static if (dir == Direction.fwd)
8251 {
8252 enforce(newTP > _interval._begin,
8253 new DateTimeException(format("Generated time point is before previous begin: prev [%s] new [%s]",
8254 interval._begin,
8255 newTP),
8256 __FILE__,
8257 line));
8258 }
8259 else
8260 {
8261 enforce(newTP < _interval._end,
8262 new DateTimeException(format("Generated time point is after previous end: prev [%s] new [%s]",
8263 interval._end,
8264 newTP),
8265 __FILE__,
8266 line));
8267 }
8268 }
8269
8270
8271 Interval!TP _interval;
8272 TP delegate(in TP) _func;
8273 }
8274
8275 //Test that IntervalRange satisfies the range predicates that it's supposed to satisfy.
8276 @safe unittest
8277 {
8278 import std.datetime.date;
8279 import std.datetime.systime;
8280 import std.range.primitives;
8281
8282 static assert(isInputRange!(IntervalRange!(Date, Direction.fwd)));
8283 static assert(isForwardRange!(IntervalRange!(Date, Direction.fwd)));
8284
8285 //Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=4895
8286 //static assert(!isOutputRange!(IntervalRange!(Date, Direction.fwd), Date));
8287
8288 static assert(!isBidirectionalRange!(IntervalRange!(Date, Direction.fwd)));
8289 static assert(!isRandomAccessRange!(IntervalRange!(Date, Direction.fwd)));
8290 static assert(!hasSwappableElements!(IntervalRange!(Date, Direction.fwd)));
8291 static assert(!hasAssignableElements!(IntervalRange!(Date, Direction.fwd)));
8292 static assert(!hasLength!(IntervalRange!(Date, Direction.fwd)));
8293 static assert(!isInfinite!(IntervalRange!(Date, Direction.fwd)));
8294 static assert(!hasSlicing!(IntervalRange!(Date, Direction.fwd)));
8295
8296 static assert(is(ElementType!(IntervalRange!(Date, Direction.fwd)) == Date));
8297 static assert(is(ElementType!(IntervalRange!(TimeOfDay, Direction.fwd)) == TimeOfDay));
8298 static assert(is(ElementType!(IntervalRange!(DateTime, Direction.fwd)) == DateTime));
8299 static assert(is(ElementType!(IntervalRange!(SysTime, Direction.fwd)) == SysTime));
8300 }
8301
8302 //Test construction of IntervalRange.
8303 @safe unittest
8304 {
8305 import std.datetime.date;
8306 import std.datetime.systime;
8307
8308 {
dateFunc(in Date date)8309 Date dateFunc(in Date date) { return date; }
8310 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
8311 auto ir = IntervalRange!(Date, Direction.fwd)(interval, &dateFunc);
8312 }
8313
8314 {
todFunc(in TimeOfDay tod)8315 TimeOfDay todFunc(in TimeOfDay tod) { return tod; }
8316 auto interval = Interval!TimeOfDay(TimeOfDay(12, 1, 7), TimeOfDay(14, 0, 0));
8317 auto ir = IntervalRange!(TimeOfDay, Direction.fwd)(interval, &todFunc);
8318 }
8319
8320 {
dtFunc(in DateTime dt)8321 DateTime dtFunc(in DateTime dt) { return dt; }
8322 auto interval = Interval!DateTime(DateTime(2010, 7, 4, 12, 1, 7), DateTime(2012, 1, 7, 14, 0, 0));
8323 auto ir = IntervalRange!(DateTime, Direction.fwd)(interval, &dtFunc);
8324 }
8325
8326 {
stFunc(in SysTime st)8327 SysTime stFunc(in SysTime st) { return cast(SysTime) st; }
8328 auto interval = Interval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)),
8329 SysTime(DateTime(2012, 1, 7, 14, 0, 0)));
8330 auto ir = IntervalRange!(SysTime, Direction.fwd)(interval, &stFunc);
8331 }
8332 }
8333
8334 //Test IntervalRange's empty().
8335 @system unittest
8336 {
8337 import std.datetime.date;
8338
8339 //fwd
8340 {
8341 auto range = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
8342
8343 assert(!range.empty);
8344 range.popFront();
8345 assert(range.empty);
8346
8347 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
8348 assert(!cRange.empty);
8349
8350 //Apparently, creating an immutable IntervalRange!Date doesn't work, so we can't test if
8351 //empty works with it. However, since an immutable range is pretty useless, it's no great loss.
8352 }
8353
8354 //bwd
8355 {
8356 auto range = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)).bwdRange(
8357 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
8358
8359 assert(!range.empty);
8360 range.popFront();
8361 assert(range.empty);
8362
8363 const cRange = Interval!Date( Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(
8364 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
8365 assert(!cRange.empty);
8366
8367 //Apparently, creating an immutable IntervalRange!Date doesn't work, so we can't test if
8368 //empty works with it. However, since an immutable range is pretty useless, it's no great loss.
8369 }
8370 }
8371
8372 //Test IntervalRange's front.
8373 @system unittest
8374 {
8375 import std.datetime.date;
8376
8377 //fwd
8378 {
8379 auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).fwdRange(
8380 everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);
8381 assertThrown!DateTimeException((in IntervalRange!(Date, Direction.fwd) range){range.front;}(emptyRange));
8382
8383 auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed));
8384 assert(range.front == Date(2010, 7, 4));
8385
8386 auto poppedRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(
8387 everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);
8388 assert(poppedRange.front == Date(2010, 7, 7));
8389
8390 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
8391 assert(cRange.front != Date.init);
8392 }
8393
8394 //bwd
8395 {
8396 auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).bwdRange(
8397 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);
8398 assertThrown!DateTimeException((in IntervalRange!(Date, Direction.bwd) range){range.front;}(emptyRange));
8399
8400 auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(
8401 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed));
8402 assert(range.front == Date(2012, 1, 7));
8403
8404 auto poppedRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(
8405 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);
8406 assert(poppedRange.front == Date(2012, 1, 4));
8407
8408 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(
8409 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
8410 assert(cRange.front != Date.init);
8411 }
8412 }
8413
8414 //Test IntervalRange's popFront().
8415 @system unittest
8416 {
8417 import std.datetime.date;
8418 import std.range.primitives : walkLength;
8419
8420 //fwd
8421 {
8422 auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).fwdRange(
8423 everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);
8424 assertThrown!DateTimeException((IntervalRange!(Date, Direction.fwd) range){range.popFront();}(emptyRange));
8425
8426 auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(
8427 everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);
8428 auto expected = range.front;
8429
foreach(date;range)8430 foreach (date; range)
8431 {
8432 assert(date == expected);
8433 expected += dur!"days"(7);
8434 }
8435
8436 assert(walkLength(range) == 79);
8437
8438 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
8439 assert(cRange.front != Date.init);
8440 }
8441
8442 //bwd
8443 {
8444 auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).bwdRange(
8445 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);
8446 assertThrown!DateTimeException((IntervalRange!(Date, Direction.bwd) range){range.popFront();}(emptyRange));
8447
8448 auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(
8449 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);
8450 auto expected = range.front;
8451
foreach(date;range)8452 foreach (date; range)
8453 {
8454 assert(date == expected);
8455 expected += dur!"days"(-7);
8456 }
8457
8458 assert(walkLength(range) == 79);
8459
8460 const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(
8461 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
8462 static assert(!__traits(compiles, cRange.popFront()));
8463 }
8464 }
8465
8466 //Test IntervalRange's save.
8467 @system unittest
8468 {
8469 import std.datetime.date;
8470
8471 //fwd
8472 {
8473 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
8474 auto func = everyDayOfWeek!Date(DayOfWeek.fri);
8475 auto range = interval.fwdRange(func);
8476
8477 assert(range.save == range);
8478 }
8479
8480 //bwd
8481 {
8482 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
8483 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
8484 auto range = interval.bwdRange(func);
8485
8486 assert(range.save == range);
8487 }
8488 }
8489
8490 //Test IntervalRange's interval.
8491 @system unittest
8492 {
8493 import std.datetime.date;
8494
8495 //fwd
8496 {
8497 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
8498 auto func = everyDayOfWeek!Date(DayOfWeek.fri);
8499 auto range = interval.fwdRange(func);
8500
8501 assert(range.interval == interval);
8502
8503 const cRange = range;
8504 assert(!cRange.interval.empty);
8505 }
8506
8507 //bwd
8508 {
8509 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
8510 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
8511 auto range = interval.bwdRange(func);
8512
8513 assert(range.interval == interval);
8514
8515 const cRange = range;
8516 assert(!cRange.interval.empty);
8517 }
8518 }
8519
8520 //Test IntervalRange's func.
8521 @system unittest
8522 {
8523 import std.datetime.date;
8524
8525 //fwd
8526 {
8527 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
8528 auto func = everyDayOfWeek!Date(DayOfWeek.fri);
8529 auto range = interval.fwdRange(func);
8530
8531 assert(range.func == func);
8532 }
8533
8534 //bwd
8535 {
8536 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
8537 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
8538 auto range = interval.bwdRange(func);
8539
8540 assert(range.func == func);
8541 }
8542 }
8543
8544 //Test IntervalRange's direction.
8545 @system unittest
8546 {
8547 import std.datetime.date;
8548
8549 //fwd
8550 {
8551 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
8552 auto func = everyDayOfWeek!Date(DayOfWeek.fri);
8553 auto range = interval.fwdRange(func);
8554
8555 assert(range.direction == Direction.fwd);
8556
8557 const cRange = range;
8558 assert(cRange.direction == Direction.fwd);
8559 }
8560
8561 //bwd
8562 {
8563 auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
8564 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
8565 auto range = interval.bwdRange(func);
8566
8567 assert(range.direction == Direction.bwd);
8568
8569 const cRange = range;
8570 assert(cRange.direction == Direction.bwd);
8571 }
8572 }
8573
8574
8575 /++
8576 A range over a $(D PosInfInterval). It is an infinite range.
8577
8578 $(D PosInfIntervalRange) is only ever constructed by $(D PosInfInterval).
8579 However, when it is constructed, it is given a function, $(D func), which
8580 is used to generate the time points which are iterated over. $(D func)
8581 takes a time point and returns a time point of the same type. For
8582 instance, to iterate
8583 over all of the days in the interval $(D PosInfInterval!Date), pass a
8584 function to $(D PosInfInterval)'s $(D fwdRange) where that function took a
8585 $(REF Date,std,datetime,date) and returned a $(REF Date,std,datetime,date)
8586 which was one day later. That function would then be used by
8587 $(D PosInfIntervalRange)'s $(D popFront) to iterate over the
8588 $(REF Date,std,datetime,date)s in the interval - though obviously, since the
8589 range is infinite, use a function such as $(D std.range.take) with it rather
8590 than iterating over $(I all) of the dates.
8591
8592 As the interval goes to positive infinity, the range is always iterated over
8593 forwards, never backwards. $(D func) must generate a time point going in
8594 the proper direction of iteration, or a
8595 $(REF DateTimeException,std,datetime,date) will be thrown. So, the time
8596 points that $(D func) generates must be later in time than the one passed to
8597 it. If it's either identical or earlier in time, then a
8598 $(REF DateTimeException,std,datetime,date) will be thrown.
8599 +/
8600 struct PosInfIntervalRange(TP)
8601 if (isTimePoint!TP)
8602 {
8603 public:
8604
8605 /++
8606 Params:
8607 rhs = The $(D PosInfIntervalRange) to assign to this one.
8608 +/
opAssign(ref PosInfIntervalRange rhs)8609 ref PosInfIntervalRange opAssign(ref PosInfIntervalRange rhs) pure nothrow
8610 {
8611 _interval = rhs._interval;
8612 _func = rhs._func;
8613 return this;
8614 }
8615
8616
8617 /++ Ditto +/
8618 ref PosInfIntervalRange opAssign(PosInfIntervalRange rhs) pure nothrow
8619 {
8620 return this = rhs;
8621 }
8622
8623
8624 /++
8625 This is an infinite range, so it is never empty.
8626 +/
8627 enum bool empty = false;
8628
8629
8630 /++
8631 The first time point in the range.
8632 +/
8633 @property TP front() const pure nothrow
8634 {
8635 return _interval.begin;
8636 }
8637
8638
8639 /++
8640 Pops $(D front) from the range, using $(D func) to generate the next
8641 time point in the range.
8642
8643 Throws:
8644 $(REF DateTimeException,std,datetime,date) if the generated time
8645 point is less than $(D front).
8646 +/
8647 void popFront()
8648 {
8649 auto begin = _func(_interval.begin);
8650 _enforceCorrectDirection(begin);
8651 _interval.begin = begin;
8652 }
8653
8654
8655 /++
8656 Returns a copy of $(D this).
8657 +/
8658 @property PosInfIntervalRange save() pure nothrow
8659 {
8660 return this;
8661 }
8662
8663
8664 /++
8665 The interval that this range currently covers.
8666 +/
8667 @property PosInfInterval!TP interval() const pure nothrow
8668 {
8669 return cast(PosInfInterval!TP)_interval;
8670 }
8671
8672
8673 /++
8674 The function used to generate the next time point in the range.
8675 +/
8676 TP delegate(in TP) func() pure nothrow @property
8677 {
8678 return _func;
8679 }
8680
8681
8682 private:
8683
8684 /+
8685 Params:
8686 interval = The interval that this range covers.
8687 func = The function used to generate the time points which are
8688 iterated over.
8689 +/
8690 this(in PosInfInterval!TP interval, TP delegate(in TP) func) pure nothrow
8691 {
8692 _func = func;
8693 _interval = interval;
8694 }
8695
8696
8697 /+
8698 Throws:
8699 $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is
8700 in the wrong direction.
8701 +/
8702 void _enforceCorrectDirection(in TP newTP, size_t line = __LINE__) const
8703 {
8704 import std.format : format;
8705
8706 enforce(newTP > _interval._begin,
8707 new DateTimeException(format("Generated time point is before previous begin: prev [%s] new [%s]",
8708 interval._begin,
8709 newTP),
8710 __FILE__,
8711 line));
8712 }
8713
8714
8715 PosInfInterval!TP _interval;
8716 TP delegate(in TP) _func;
8717 }
8718
8719 //Test that PosInfIntervalRange satisfies the range predicates that it's supposed to satisfy.
8720 @safe unittest
8721 {
8722 import std.datetime.date;
8723 import std.datetime.systime;
8724 import std.range.primitives;
8725
8726 static assert(isInputRange!(PosInfIntervalRange!Date));
8727 static assert(isForwardRange!(PosInfIntervalRange!Date));
8728 static assert(isInfinite!(PosInfIntervalRange!Date));
8729
8730 //Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=4895
8731 //static assert(!isOutputRange!(PosInfIntervalRange!Date, Date));
8732 static assert(!isBidirectionalRange!(PosInfIntervalRange!Date));
8733 static assert(!isRandomAccessRange!(PosInfIntervalRange!Date));
8734 static assert(!hasSwappableElements!(PosInfIntervalRange!Date));
8735 static assert(!hasAssignableElements!(PosInfIntervalRange!Date));
8736 static assert(!hasLength!(PosInfIntervalRange!Date));
8737 static assert(!hasSlicing!(PosInfIntervalRange!Date));
8738
8739 static assert(is(ElementType!(PosInfIntervalRange!Date) == Date));
8740 static assert(is(ElementType!(PosInfIntervalRange!TimeOfDay) == TimeOfDay));
8741 static assert(is(ElementType!(PosInfIntervalRange!DateTime) == DateTime));
8742 static assert(is(ElementType!(PosInfIntervalRange!SysTime) == SysTime));
8743 }
8744
8745 //Test construction of PosInfIntervalRange.
8746 @safe unittest
8747 {
8748 import std.datetime.date;
8749 import std.datetime.systime;
8750
8751 {
dateFunc(in Date date)8752 Date dateFunc(in Date date) { return date; }
8753 auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
8754 auto ir = PosInfIntervalRange!Date(posInfInterval, &dateFunc);
8755 }
8756
8757 {
todFunc(in TimeOfDay tod)8758 TimeOfDay todFunc(in TimeOfDay tod) { return tod; }
8759 auto posInfInterval = PosInfInterval!TimeOfDay(TimeOfDay(12, 1, 7));
8760 auto ir = PosInfIntervalRange!(TimeOfDay)(posInfInterval, &todFunc);
8761 }
8762
8763 {
dtFunc(in DateTime dt)8764 DateTime dtFunc(in DateTime dt) { return dt; }
8765 auto posInfInterval = PosInfInterval!DateTime(DateTime(2010, 7, 4, 12, 1, 7));
8766 auto ir = PosInfIntervalRange!(DateTime)(posInfInterval, &dtFunc);
8767 }
8768
8769 {
stFunc(in SysTime st)8770 SysTime stFunc(in SysTime st) { return cast(SysTime) st; }
8771 auto posInfInterval = PosInfInterval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)));
8772 auto ir = PosInfIntervalRange!SysTime(posInfInterval, &stFunc);
8773 }
8774 }
8775
8776 //Test PosInfIntervalRange's front.
8777 @system unittest
8778 {
8779 import std.datetime.date;
8780
8781 auto range = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed));
8782 assert(range.front == Date(2010, 7, 4));
8783
8784 auto poppedRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);
8785 assert(poppedRange.front == Date(2010, 7, 7));
8786
8787 const cRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
8788 assert(cRange.front != Date.init);
8789 }
8790
8791 //Test PosInfIntervalRange's popFront().
8792 @system unittest
8793 {
8794 import std.datetime.date;
8795 import std.range : take;
8796
8797 auto range = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);
8798 auto expected = range.front;
8799
8800 foreach (date; take(range, 79))
8801 {
8802 assert(date == expected);
8803 expected += dur!"days"(7);
8804 }
8805
8806 const cRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
8807 static assert(!__traits(compiles, cRange.popFront()));
8808 }
8809
8810 //Test PosInfIntervalRange's save.
8811 @system unittest
8812 {
8813 import std.datetime.date;
8814
8815 auto interval = PosInfInterval!Date(Date(2010, 7, 4));
8816 auto func = everyDayOfWeek!Date(DayOfWeek.fri);
8817 auto range = interval.fwdRange(func);
8818
8819 assert(range.save == range);
8820 }
8821
8822 //Test PosInfIntervalRange's interval.
8823 @system unittest
8824 {
8825 import std.datetime.date;
8826
8827 auto interval = PosInfInterval!Date(Date(2010, 7, 4));
8828 auto func = everyDayOfWeek!Date(DayOfWeek.fri);
8829 auto range = interval.fwdRange(func);
8830
8831 assert(range.interval == interval);
8832
8833 const cRange = range;
8834 assert(!cRange.interval.empty);
8835 }
8836
8837 //Test PosInfIntervalRange's func.
8838 @system unittest
8839 {
8840 import std.datetime.date;
8841
8842 auto interval = PosInfInterval!Date(Date(2010, 7, 4));
8843 auto func = everyDayOfWeek!Date(DayOfWeek.fri);
8844 auto range = interval.fwdRange(func);
8845
8846 assert(range.func == func);
8847 }
8848
8849
8850 /++
8851 A range over a $(D NegInfInterval). It is an infinite range.
8852
8853 $(D NegInfIntervalRange) is only ever constructed by $(D NegInfInterval).
8854 However, when it is constructed, it is given a function, $(D func), which
8855 is used to generate the time points which are iterated over. $(D func)
8856 takes a time point and returns a time point of the same type. For
8857 instance, to iterate over all of the days in the interval
8858 $(D NegInfInterval!Date), pass a function to $(D NegInfInterval)'s
8859 $(D bwdRange) where that function took a $(REF Date,std,datetime,date) and
8860 returned a $(REF Date,std,datetime,date) which was one day earlier. That
8861 function would then be used by $(D NegInfIntervalRange)'s $(D popFront) to
8862 iterate over the $(REF Date,std,datetime,date)s in the interval - though
8863 obviously, since the range is infinite, use a function such as
8864 $(D std.range.take) with it rather than iterating over $(I all) of the dates.
8865
8866 As the interval goes to negative infinity, the range is always iterated over
8867 backwards, never forwards. $(D func) must generate a time point going in
8868 the proper direction of iteration, or a
8869 $(REF DateTimeException,std,datetime,date) will be thrown. So, the time
8870 points that $(D func) generates must be earlier in time than the one passed
8871 to it. If it's either identical or later in time, then a
8872 $(REF DateTimeException,std,datetime,date) will be thrown.
8873
8874 Also note that while normally the $(D end) of an interval is excluded from
8875 it, $(D NegInfIntervalRange) treats it as if it were included. This allows
8876 for the same behavior as with $(D PosInfIntervalRange). This works
8877 because none of $(D NegInfInterval)'s functions which care about whether
8878 $(D end) is included or excluded are ever called by
8879 $(D NegInfIntervalRange). $(D interval) returns a normal interval, so any
8880 $(D NegInfInterval) functions which are called on it which care about
8881 whether $(D end) is included or excluded will treat $(D end) as excluded.
8882 +/
8883 struct NegInfIntervalRange(TP)
8884 if (isTimePoint!TP)
8885 {
8886 public:
8887
8888 /++
8889 Params:
8890 rhs = The $(D NegInfIntervalRange) to assign to this one.
8891 +/
opAssign(ref NegInfIntervalRange rhs)8892 ref NegInfIntervalRange opAssign(ref NegInfIntervalRange rhs) pure nothrow
8893 {
8894 _interval = rhs._interval;
8895 _func = rhs._func;
8896
8897 return this;
8898 }
8899
8900
8901 /++ Ditto +/
opAssign(NegInfIntervalRange rhs)8902 ref NegInfIntervalRange opAssign(NegInfIntervalRange rhs) pure nothrow
8903 {
8904 return this = rhs;
8905 }
8906
8907
8908 /++
8909 This is an infinite range, so it is never empty.
8910 +/
8911 enum bool empty = false;
8912
8913
8914 /++
8915 The first time point in the range.
8916 +/
front()8917 @property TP front() const pure nothrow
8918 {
8919 return _interval.end;
8920 }
8921
8922
8923 /++
8924 Pops $(D front) from the range, using $(D func) to generate the next
8925 time point in the range.
8926
8927 Throws:
8928 $(REF DateTimeException,std,datetime,date) if the generated time
8929 point is greater than $(D front).
8930 +/
popFront()8931 void popFront()
8932 {
8933 auto end = _func(_interval.end);
8934 _enforceCorrectDirection(end);
8935 _interval.end = end;
8936 }
8937
8938
8939 /++
8940 Returns a copy of $(D this).
8941 +/
save()8942 @property NegInfIntervalRange save() pure nothrow
8943 {
8944 return this;
8945 }
8946
8947
8948 /++
8949 The interval that this range currently covers.
8950 +/
8951 @property NegInfInterval!TP interval() const pure nothrow
8952 {
8953 return cast(NegInfInterval!TP)_interval;
8954 }
8955
8956
8957 /++
8958 The function used to generate the next time point in the range.
8959 +/
delegate(in TP)8960 TP delegate(in TP) func() pure nothrow @property
8961 {
8962 return _func;
8963 }
8964
8965
8966 private:
8967
8968 /+
8969 Params:
8970 interval = The interval that this range covers.
8971 func = The function used to generate the time points which are
8972 iterated over.
8973 +/
8974 this(in NegInfInterval!TP interval, TP delegate(in TP) func) pure nothrow
8975 {
8976 _func = func;
8977 _interval = interval;
8978 }
8979
8980
8981 /+
8982 Throws:
8983 $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is
8984 in the wrong direction.
8985 +/
8986 void _enforceCorrectDirection(in TP newTP, size_t line = __LINE__) const
8987 {
8988 import std.format : format;
8989
8990 enforce(newTP < _interval._end,
8991 new DateTimeException(format("Generated time point is before previous end: prev [%s] new [%s]",
8992 interval._end,
8993 newTP),
8994 __FILE__,
8995 line));
8996 }
8997
8998
8999 NegInfInterval!TP _interval;
9000 TP delegate(in TP) _func;
9001 }
9002
9003 //Test that NegInfIntervalRange satisfies the range predicates that it's supposed to satisfy.
9004 @safe unittest
9005 {
9006 import std.datetime.date;
9007 import std.range.primitives;
9008
9009 static assert(isInputRange!(NegInfIntervalRange!Date));
9010 static assert(isForwardRange!(NegInfIntervalRange!Date));
9011 static assert(isInfinite!(NegInfIntervalRange!Date));
9012
9013 //Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=4895
9014 //static assert(!isOutputRange!(NegInfIntervalRange!Date, Date));
9015 static assert(!isBidirectionalRange!(NegInfIntervalRange!Date));
9016 static assert(!isRandomAccessRange!(NegInfIntervalRange!Date));
9017 static assert(!hasSwappableElements!(NegInfIntervalRange!Date));
9018 static assert(!hasAssignableElements!(NegInfIntervalRange!Date));
9019 static assert(!hasLength!(NegInfIntervalRange!Date));
9020 static assert(!hasSlicing!(NegInfIntervalRange!Date));
9021
9022 static assert(is(ElementType!(NegInfIntervalRange!Date) == Date));
9023 static assert(is(ElementType!(NegInfIntervalRange!TimeOfDay) == TimeOfDay));
9024 static assert(is(ElementType!(NegInfIntervalRange!DateTime) == DateTime));
9025 }
9026
9027 //Test construction of NegInfIntervalRange.
9028 @safe unittest
9029 {
9030 import std.datetime.date;
9031 import std.datetime.systime;
9032
9033 {
dateFunc(in Date date)9034 Date dateFunc(in Date date) { return date; }
9035 auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
9036 auto ir = NegInfIntervalRange!Date(negInfInterval, &dateFunc);
9037 }
9038
9039 {
todFunc(in TimeOfDay tod)9040 TimeOfDay todFunc(in TimeOfDay tod) { return tod; }
9041 auto negInfInterval = NegInfInterval!TimeOfDay(TimeOfDay(14, 0, 0));
9042 auto ir = NegInfIntervalRange!(TimeOfDay)(negInfInterval, &todFunc);
9043 }
9044
9045 {
dtFunc(in DateTime dt)9046 DateTime dtFunc(in DateTime dt) { return dt; }
9047 auto negInfInterval = NegInfInterval!DateTime(DateTime(2012, 1, 7, 14, 0, 0));
9048 auto ir = NegInfIntervalRange!(DateTime)(negInfInterval, &dtFunc);
9049 }
9050
9051 {
stFunc(in SysTime st)9052 SysTime stFunc(in SysTime st) { return cast(SysTime)(st); }
9053 auto negInfInterval = NegInfInterval!SysTime(SysTime(DateTime(2012, 1, 7, 14, 0, 0)));
9054 auto ir = NegInfIntervalRange!(SysTime)(negInfInterval, &stFunc);
9055 }
9056 }
9057
9058 //Test NegInfIntervalRange's front.
9059 @system unittest
9060 {
9061 import std.datetime.date;
9062
9063 auto range = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed));
9064 assert(range.front == Date(2012, 1, 7));
9065
9066 auto poppedRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(
9067 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);
9068 assert(poppedRange.front == Date(2012, 1, 4));
9069
9070 const cRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
9071 assert(cRange.front != Date.init);
9072 }
9073
9074 //Test NegInfIntervalRange's popFront().
9075 @system unittest
9076 {
9077 import std.datetime.date;
9078 import std.range : take;
9079
9080 auto range = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(
9081 everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);
9082 auto expected = range.front;
9083
9084 foreach (date; take(range, 79))
9085 {
9086 assert(date == expected);
9087 expected += dur!"days"(-7);
9088 }
9089
9090 const cRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
9091 static assert(!__traits(compiles, cRange.popFront()));
9092 }
9093
9094 //Test NegInfIntervalRange's save.
9095 @system unittest
9096 {
9097 import std.datetime.date;
9098
9099 auto interval = NegInfInterval!Date(Date(2012, 1, 7));
9100 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
9101 auto range = interval.bwdRange(func);
9102
9103 assert(range.save == range);
9104 }
9105
9106 //Test NegInfIntervalRange's interval.
9107 @system unittest
9108 {
9109 import std.datetime.date;
9110
9111 auto interval = NegInfInterval!Date(Date(2012, 1, 7));
9112 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
9113 auto range = interval.bwdRange(func);
9114
9115 assert(range.interval == interval);
9116
9117 const cRange = range;
9118 assert(!cRange.interval.empty);
9119 }
9120
9121 //Test NegInfIntervalRange's func.
9122 @system unittest
9123 {
9124 import std.datetime.date;
9125
9126 auto interval = NegInfInterval!Date(Date(2012, 1, 7));
9127 auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
9128 auto range = interval.bwdRange(func);
9129
9130 assert(range.func == func);
9131 }
9132