diff --git a/std/datetime/interval.d b/std/datetime/interval.d index d1236fe17..2b10ecba7 100644 --- a/std/datetime/interval.d +++ b/std/datetime/interval.d @@ -8,3 +8,3062 @@ LREF2=$(D $2) +/ module std.datetime.interval; + +import core.time : Duration; +import std.datetime.common; +import std.exception : enforce; +import std.traits : isIntegral, Unqual; +import std.typecons : Flag; + +version(unittest) import std.exception : assertThrown; + +import core.time : dur; // temporary +import std.datetime : Date, DateTime, SysTime, TimeOfDay; // temporary +import std.datetime : PosInfInterval, NegInfInterval, IntervalRange, PosInfIntervalRange, NegInfIntervalRange; // temporary +import std.datetime : everyDayOfWeek; // temporary + +/++ + Indicates a direction in time. One example of its use is $(LREF2 .Interval, Interval)'s + $(LREF expand, expand) function which uses it to indicate whether the interval should + be expanded backwards (into the past), forwards (into the future), or both. + +/ +enum Direction +{ + /// Backward. + bwd, + + /// Forward. + fwd, + + /// Both backward and forward. + both +} + + +/++ + Used to indicate whether $(D popFront) should be called immediately upon + creating a range. The idea is that for some functions used to generate a + range for an interval, $(D front) is not necessarily a time point which + would ever be generated by the range (e.g. if the range were every Sunday + within an interval, but the interval started on a Monday), so there needs + to be a way to deal with that. To get the first time point in the range to + match what the function generates, then use $(D PopFirst.yes) to indicate + that the range should have $(D popFront) called on it before the range is + returned so that $(D front) is a time point which the function would + generate. To let the first time point not match the generator function, + use $(D PopFront.no). + + For instance, if the function used to generate a range of time points + generated successive Easters (i.e. you're iterating over all of the Easters + within the interval), the initial date probably isn't an Easter. Using + $(D PopFirst.yes) would tell the function which returned the range that + $(D popFront) was to be called so that front would then be an Easter - the + next one generated by the function (which when iterating forward would be + the Easter following the original $(D front), while when iterating backward, + it would be the Easter prior to the original $(D front)). If + $(D PopFirst.no) were used, then $(D front) would remain the original time + point and it would not necessarily be a time point which would be generated + by the range-generating function (which in many cases is exactly what is + desired - e.g. if iterating over every day starting at the beginning of the + interval). + + If set to $(D PopFirst.no), then popFront is not called before returning + the range. + + Otherwise, if set to $(D PopFirst.yes), then popFront is called before + returning the range. + +/ +alias PopFirst = Flag!"popFirst"; + + +/++ + Represents an interval of time. + + An $(D Interval) has a starting point and an end point. The interval of time + is therefore the time starting at the starting point up to, but not + including, the end point. e.g. + + $(BOOKTABLE, + $(TR $(TD [January 5th, 2010 - March 10th, 2010$(RPAREN))) + $(TR $(TD [05:00:30 - 12:00:00$(RPAREN))) + $(TR $(TD [1982-01-04T08:59:00 - 2010-07-04T12:00:00$(RPAREN))) + ) + + A range can be obtained from an $(D Interval), allowing iteration over + that interval, with the exact time points which are iterated over depending + on the function which generates the range. + +/ +struct Interval(TP) +{ +public: + + /++ + Params: + begin = The time point which begins the interval. + end = The time point which ends (but is not included in) the + interval. + + Throws: + $(LREF DateTimeException) if $(D_PARAM end) is before $(D_PARAM begin). + + Example: + -------------------- + Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + -------------------- + +/ + this(U)(in TP begin, in U end) pure + if (is(Unqual!TP == Unqual!U)) + { + if (!_valid(begin, end)) + throw new DateTimeException("Arguments would result in an invalid Interval."); + _begin = cast(TP) begin; + _end = cast(TP) end; + } + + + /++ + Params: + begin = The time point which begins the interval. + duration = The duration from the starting point to the end point. + + Throws: + $(LREF DateTimeException) if the resulting $(D end) is before + $(D begin). + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), dur!"days"(3)) == + Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5))); + -------------------- + +/ + this(D)(in TP begin, in D duration) pure + if (__traits(compiles, begin + duration)) + { + _begin = cast(TP) begin; + _end = begin + duration; + if (!_valid(_begin, _end)) + throw new DateTimeException("Arguments would result in an invalid Interval."); + } + + + /++ + Params: + rhs = The $(LREF2 .Interval, Interval) to assign to this one. + +/ + ref Interval opAssign(const ref Interval rhs) pure nothrow + { + _begin = cast(TP) rhs._begin; + _end = cast(TP) rhs._end; + return this; + } + + + /++ + Params: + rhs = The $(LREF2 .Interval, Interval) to assign to this one. + +/ + ref Interval opAssign(Interval rhs) pure nothrow + { + _begin = cast(TP) rhs._begin; + _end = cast(TP) rhs._end; + return this; + } + + + /++ + The starting point of the interval. It is included in the interval. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == + Date(1996, 1, 2)); + -------------------- + +/ + @property TP begin() const pure nothrow + { + return cast(TP) _begin; + } + + + /++ + The starting point of the interval. It is included in the interval. + + Params: + timePoint = The time point to set $(D begin) to. + + Throws: + $(LREF DateTimeException) if the resulting interval would be invalid. + +/ + @property void begin(TP timePoint) pure + { + if (!_valid(timePoint, _end)) + throw new DateTimeException("Arguments would result in an invalid Interval."); + _begin = timePoint; + } + + + /++ + The end point of the interval. It is excluded from the interval. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == + Date(2012, 3, 1)); + -------------------- + +/ + @property TP end() const pure nothrow + { + return cast(TP) _end; + } + + + /++ + The end point of the interval. It is excluded from the interval. + + Params: + timePoint = The time point to set end to. + + Throws: + $(LREF DateTimeException) if the resulting interval would be invalid. + +/ + @property void end(TP timePoint) pure + { + if (!_valid(_begin, timePoint)) + throw new DateTimeException("Arguments would result in an invalid Interval."); + _end = timePoint; + } + + + /++ + Returns the duration between $(D begin) and $(D end). + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == + dur!"days"(5903)); + -------------------- + +/ + @property auto length() const pure nothrow + { + return _end - _begin; + } + + + /++ + Whether the interval's length is 0, that is, whether $(D begin == end). + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty); + -------------------- + +/ + @property bool empty() const pure nothrow + { + return _begin == _end; + } + + + /++ + Whether the given time point is within this interval. + + Params: + timePoint = The time point to check for inclusion in this interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( + Date(1994, 12, 24))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( + Date(2000, 1, 5))); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( + Date(2012, 3, 1))); + -------------------- + +/ + bool contains(in TP timePoint) const pure + { + _enforceNotEmpty(); + return timePoint >= _begin && timePoint < _end; + } + + + /++ + Whether the given interval is completely within this interval. + + Params: + interval = The interval to check for inclusion in this interval. + + Throws: + $(LREF DateTimeException) if either interval is empty. + + Example: + -------------------- + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( + Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( + Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( + Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); + -------------------- + +/ + bool contains(in Interval interval) const pure + { + _enforceNotEmpty(); + interval._enforceNotEmpty(); + return interval._begin >= _begin && + interval._begin < _end && + interval._end <= _end; + } + + + /++ + Whether the given interval is completely within this interval. + + Always returns false (unless this interval is empty), because an + interval going to positive infinity can never be contained in a finite + interval. + + Params: + interval = The interval to check for inclusion in this interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( + PosInfInterval!Date(Date(1999, 5, 4)))); + -------------------- + +/ + bool contains(in PosInfInterval!TP interval) const pure + { + _enforceNotEmpty(); + return false; + } + + + /++ + Whether the given interval is completely within this interval. + + Always returns false (unless this interval is empty), because an + interval beginning at negative infinity can never be contained in a + finite interval. + + Params: + interval = The interval to check for inclusion in this interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( + NegInfInterval!Date(Date(1996, 5, 4)))); + -------------------- + +/ + bool contains(in NegInfInterval!TP interval) const pure + { + _enforceNotEmpty(); + return false; + } + + + /++ + Whether this interval is before the given time point. + + Params: + timePoint = The time point to check whether this interval is before + it. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( + Date(1994, 12, 24))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( + Date(2000, 1, 5))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( + Date(2012, 3, 1))); + -------------------- + +/ + bool isBefore(in TP timePoint) const pure + { + _enforceNotEmpty(); + return _end <= timePoint; + } + + + /++ + Whether this interval is before the given interval and does not + intersect with it. + + Params: + interval = The interval to check for against this interval. + + Throws: + $(LREF DateTimeException) if either interval is empty. + + Example: + -------------------- + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( + Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( + Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( + Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1)))); + -------------------- + +/ + bool isBefore(in Interval interval) const pure + { + _enforceNotEmpty(); + interval._enforceNotEmpty(); + return _end <= interval._begin; + } + + + /++ + Whether this interval is before the given interval and does not + intersect with it. + + Params: + interval = The interval to check for against this interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( + PosInfInterval!Date(Date(1999, 5, 4)))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( + PosInfInterval!Date(Date(2013, 3, 7)))); + -------------------- + +/ + bool isBefore(in PosInfInterval!TP interval) const pure + { + _enforceNotEmpty(); + return _end <= interval._begin; + } + + + /++ + Whether this interval is before the given interval and does not + intersect with it. + + Always returns false (unless this interval is empty) because a finite + interval can never be before an interval beginning at negative infinity. + + Params: + interval = The interval to check for against this interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( + NegInfInterval!Date(Date(1996, 5, 4)))); + -------------------- + +/ + bool isBefore(in NegInfInterval!TP interval) const pure + { + _enforceNotEmpty(); + return false; + } + + + /++ + Whether this interval is after the given time point. + + Params: + timePoint = The time point to check whether this interval is after + it. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( + Date(1994, 12, 24))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( + Date(2000, 1, 5))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( + Date(2012, 3, 1))); + -------------------- + +/ + bool isAfter(in TP timePoint) const pure + { + _enforceNotEmpty(); + return timePoint < _begin; + } + + + /++ + Whether this interval is after the given interval and does not intersect + it. + + Params: + interval = The interval to check against this interval. + + Throws: + $(LREF DateTimeException) if either interval is empty. + + Example: + -------------------- + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( + Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( + Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( + Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); + -------------------- + +/ + bool isAfter(in Interval interval) const pure + { + _enforceNotEmpty(); + interval._enforceNotEmpty(); + return _begin >= interval._end; + } + + + /++ + Whether this interval is after the given interval and does not intersect + it. + + Always returns false (unless this interval is empty) because a finite + interval can never be after an interval going to positive infinity. + + Params: + interval = The interval to check against this interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( + PosInfInterval!Date(Date(1999, 5, 4)))); + -------------------- + +/ + bool isAfter(in PosInfInterval!TP interval) const pure + { + _enforceNotEmpty(); + return false; + } + + + /++ + Whether this interval is after the given interval and does not intersect + it. + + Params: + interval = The interval to check against this interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( + NegInfInterval!Date(Date(1996, 1, 2)))); + -------------------- + +/ + bool isAfter(in NegInfInterval!TP interval) const pure + { + _enforceNotEmpty(); + return _begin >= interval._end; + } + + + /++ + Whether the given interval overlaps this interval. + + Params: + interval = The interval to check for intersection with this interval. + + Throws: + $(LREF DateTimeException) if either interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( + Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( + Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( + Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); + -------------------- + +/ + bool intersects(in Interval interval) const pure + { + _enforceNotEmpty(); + interval._enforceNotEmpty(); + return interval._begin < _end && interval._end > _begin; + } + + + /++ + Whether the given interval overlaps this interval. + + Params: + interval = The interval to check for intersection with this interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( + PosInfInterval!Date(Date(1999, 5, 4)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( + PosInfInterval!Date(Date(2012, 3, 1)))); + -------------------- + +/ + bool intersects(in PosInfInterval!TP interval) const pure + { + _enforceNotEmpty(); + return _end > interval._begin; + } + + + /++ + Whether the given interval overlaps this interval. + + Params: + interval = The interval to check for intersection with this interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( + NegInfInterval!Date(Date(1996, 1, 2)))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( + NegInfInterval!Date(Date(2000, 1, 2)))); + -------------------- + +/ + bool intersects(in NegInfInterval!TP interval) const pure + { + _enforceNotEmpty(); + return _begin < interval._end; + } + + + /++ + Returns the intersection of two intervals + + Params: + interval = The interval to intersect with this interval. + + Throws: + $(LREF DateTimeException) if the two intervals do not intersect or if + either interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( + Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == + Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( + Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == + Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); + -------------------- + +/ + Interval intersection(in Interval interval) const + { + import std.format : format; + + enforce(this.intersects(interval), + new DateTimeException(format("%s and %s do not intersect.", this, interval))); + + auto begin = _begin > interval._begin ? _begin : interval._begin; + auto end = _end < interval._end ? _end : interval._end; + + return Interval(begin, end); + } + + + /++ + Returns the intersection of two intervals + + Params: + interval = The interval to intersect with this interval. + + Throws: + $(LREF DateTimeException) if the two intervals do not intersect or if + this interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( + PosInfInterval!Date(Date(1990, 7, 6))) == + Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( + PosInfInterval!Date(Date(1999, 1, 12))) == + Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); + -------------------- + +/ + Interval intersection(in PosInfInterval!TP interval) const + { + import std.format : format; + + enforce(this.intersects(interval), + new DateTimeException(format("%s and %s do not intersect.", this, interval))); + + return Interval(_begin > interval._begin ? _begin : interval._begin, _end); + } + + + /++ + Returns the intersection of two intervals + + Params: + interval = The interval to intersect with this interval. + + Throws: + $(LREF DateTimeException) if the two intervals do not intersect or if + this interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( + NegInfInterval!Date(Date(1999, 7, 6))) == + Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( + NegInfInterval!Date(Date(2013, 1, 12))) == + Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); + -------------------- + +/ + Interval intersection(in NegInfInterval!TP interval) const + { + import std.format : format; + + enforce(this.intersects(interval), + new DateTimeException(format("%s and %s do not intersect.", this, interval))); + + return Interval(_begin, _end < interval._end ? _end : interval._end); + } + + + /++ + Whether the given interval is adjacent to this interval. + + Params: + interval = The interval to check whether its adjecent to this + interval. + + Throws: + $(LREF DateTimeException) if either interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( + Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2)))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( + Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( + Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1)))); + -------------------- + +/ + bool isAdjacent(in Interval interval) const pure + { + _enforceNotEmpty(); + interval._enforceNotEmpty(); + return _begin == interval._end || _end == interval._begin; + } + + + /++ + Whether the given interval is adjacent to this interval. + + Params: + interval = The interval to check whether its adjecent to this + interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( + PosInfInterval!Date(Date(1999, 5, 4)))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( + PosInfInterval!Date(Date(2012, 3, 1)))); + -------------------- + +/ + bool isAdjacent(in PosInfInterval!TP interval) const pure + { + _enforceNotEmpty(); + return _end == interval._begin; + } + + + /++ + Whether the given interval is adjacent to this interval. + + Params: + interval = The interval to check whether its adjecent to this + interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( + NegInfInterval!Date(Date(1996, 1, 2)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( + NegInfInterval!Date(Date(2000, 1, 2)))); + -------------------- + +/ + bool isAdjacent(in NegInfInterval!TP interval) const pure + { + _enforceNotEmpty(); + return _begin == interval._end; + } + + + /++ + Returns the union of two intervals + + Params: + interval = The interval to merge with this interval. + + Throws: + $(LREF DateTimeException) if the two intervals do not intersect and are + not adjacent or if either interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( + Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == + Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( + Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == + Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); + -------------------- + +/ + Interval merge(in Interval interval) const + { + import std.format : format; + + enforce(this.isAdjacent(interval) || this.intersects(interval), + new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); + + auto begin = _begin < interval._begin ? _begin : interval._begin; + auto end = _end > interval._end ? _end : interval._end; + + return Interval(begin, end); + } + + + /++ + Returns the union of two intervals + + Params: + interval = The interval to merge with this interval. + + Throws: + $(LREF DateTimeException) if the two intervals do not intersect and are + not adjacent or if this interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( + PosInfInterval!Date(Date(1990, 7, 6))) == + PosInfInterval!Date(Date(1990, 7 , 6))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( + PosInfInterval!Date(Date(2012, 3, 1))) == + PosInfInterval!Date(Date(1996, 1 , 2))); + -------------------- + +/ + PosInfInterval!TP merge(in PosInfInterval!TP interval) const + { + import std.format : format; + + enforce(this.isAdjacent(interval) || this.intersects(interval), + new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); + + return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin); + } + + + /++ + Returns the union of two intervals + + Params: + interval = The interval to merge with this interval. + + Throws: + $(LREF DateTimeException) if the two intervals do not intersect and are not + adjacent or if this interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( + NegInfInterval!Date(Date(1996, 1, 2))) == + NegInfInterval!Date(Date(2012, 3 , 1))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( + NegInfInterval!Date(Date(2013, 1, 12))) == + NegInfInterval!Date(Date(2013, 1 , 12))); + -------------------- + +/ + NegInfInterval!TP merge(in NegInfInterval!TP interval) const + { + import std.format : format; + + enforce(this.isAdjacent(interval) || this.intersects(interval), + new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); + + return NegInfInterval!TP(_end > interval._end ? _end : interval._end); + } + + + /++ + Returns an interval that covers from the earliest time point of two + intervals up to (but not including) the latest time point of two + intervals. + + Params: + interval = The interval to create a span together with this interval. + + Throws: + $(LREF DateTimeException) if either interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( + Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) == + Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( + Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == + Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); + -------------------- + +/ + Interval span(in Interval interval) const pure + { + _enforceNotEmpty(); + interval._enforceNotEmpty(); + + auto begin = _begin < interval._begin ? _begin : interval._begin; + auto end = _end > interval._end ? _end : interval._end; + + return Interval(begin, end); + } + + + /++ + Returns an interval that covers from the earliest time point of two + intervals up to (but not including) the latest time point of two + intervals. + + Params: + interval = The interval to create a span together with this interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( + PosInfInterval!Date(Date(1990, 7, 6))) == + PosInfInterval!Date(Date(1990, 7 , 6))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( + PosInfInterval!Date(Date(2050, 1, 1))) == + PosInfInterval!Date(Date(1996, 1 , 2))); + -------------------- + +/ + PosInfInterval!TP span(in PosInfInterval!TP interval) const pure + { + _enforceNotEmpty(); + return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin); + } + + + /++ + Returns an interval that covers from the earliest time point of two + intervals up to (but not including) the latest time point of two + intervals. + + Params: + interval = The interval to create a span together with this interval. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Example: + -------------------- + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( + NegInfInterval!Date(Date(1602, 5, 21))) == + NegInfInterval!Date(Date(2012, 3 , 1))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( + NegInfInterval!Date(Date(2013, 1, 12))) == + NegInfInterval!Date(Date(2013, 1 , 12))); + -------------------- + +/ + NegInfInterval!TP span(in NegInfInterval!TP interval) const pure + { + _enforceNotEmpty(); + return NegInfInterval!TP(_end > interval._end ? _end : interval._end); + } + + + /++ + Shifts the interval forward or backwards in time by the given duration + (a positive duration shifts the interval forward; a negative duration + shifts it backward). Effectively, it does $(D begin += duration) and + $(D end += duration). + + Params: + duration = The duration to shift the interval by. + + Throws: + $(LREF DateTimeException) this interval is empty or if the resulting + interval would be invalid. + + Example: + -------------------- + auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); + auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); + + interval1.shift(dur!"days"(50)); + assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25))); + + interval2.shift(dur!"days"(-50)); + assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15))); + -------------------- + +/ + void shift(D)(D duration) pure + if (__traits(compiles, begin + duration)) + { + _enforceNotEmpty(); + + auto begin = _begin + duration; + auto end = _end + duration; + + if (!_valid(begin, end)) + throw new DateTimeException("Argument would result in an invalid Interval."); + + _begin = begin; + _end = end; + } + + + static if (__traits(compiles, begin.add!"months"(1)) && + __traits(compiles, begin.add!"years"(1))) + { + /++ + Shifts the interval forward or backwards in time by the given number + of years and/or months (a positive number of years and months shifts + the interval forward; a negative number shifts it backward). + It adds the years the given years and months to both begin and end. + It effectively calls $(D add!"years"()) and then $(D add!"months"()) + on begin and end with the given number of years and months. + + Params: + years = The number of years to shift the interval by. + months = The number of months to shift the interval by. + allowOverflow = Whether the days should be allowed to overflow + on $(D begin) and $(D end), causing their month + to increment. + + Throws: + $(LREF DateTimeException) if this interval is empty or if the + resulting interval would be invalid. + + Example: + -------------------- + auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + + interval1.shift(2); + assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1))); + + interval2.shift(-2); + assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1))); + -------------------- + +/ + void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) + if (isIntegral!T) + { + _enforceNotEmpty(); + + auto begin = _begin; + auto end = _end; + + begin.add!"years"(years, allowOverflow); + begin.add!"months"(months, allowOverflow); + end.add!"years"(years, allowOverflow); + end.add!"months"(months, allowOverflow); + + enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval.")); + + _begin = begin; + _end = end; + } + } + + + /++ + Expands the interval forwards and/or backwards in time. Effectively, + it does $(D begin -= duration) and/or $(D end += duration). Whether + it expands forwards and/or backwards in time is determined by + $(D_PARAM dir). + + Params: + duration = The duration to expand the interval by. + dir = The direction in time to expand the interval. + + Throws: + $(LREF DateTimeException) this interval is empty or if the resulting + interval would be invalid. + + Example: + -------------------- + auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + + interval1.expand(2); + assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); + + interval2.expand(-2); + assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); + -------------------- + +/ + void expand(D)(D duration, Direction dir = Direction.both) pure + if (__traits(compiles, begin + duration)) + { + _enforceNotEmpty(); + + switch (dir) + { + case Direction.both: + { + auto begin = _begin - duration; + auto end = _end + duration; + + if (!_valid(begin, end)) + throw new DateTimeException("Argument would result in an invalid Interval."); + + _begin = begin; + _end = end; + + return; + } + case Direction.fwd: + { + auto end = _end + duration; + + if (!_valid(_begin, end)) + throw new DateTimeException("Argument would result in an invalid Interval."); + _end = end; + + return; + } + case Direction.bwd: + { + auto begin = _begin - duration; + + if (!_valid(begin, _end)) + throw new DateTimeException("Argument would result in an invalid Interval."); + _begin = begin; + + return; + } + default: + assert(0, "Invalid Direction."); + } + } + + static if (__traits(compiles, begin.add!"months"(1)) && + __traits(compiles, begin.add!"years"(1))) + { + /++ + Expands the interval forwards and/or backwards in time. Effectively, + it subtracts the given number of months/years from $(D begin) and + adds them to $(D end). Whether it expands forwards and/or backwards + in time is determined by $(D_PARAM dir). + + Params: + years = The number of years to expand the interval by. + months = The number of months to expand the interval by. + allowOverflow = Whether the days should be allowed to overflow + on $(D begin) and $(D end), causing their month + to increment. + dir = The direction in time to expand the interval. + + Throws: + $(LREF DateTimeException) if this interval is empty or if the + resulting interval would be invalid. + + Example: + -------------------- + auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + + interval1.expand(2); + assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); + + interval2.expand(-2); + assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); + -------------------- + +/ + void expand(T)(T years, + T months = 0, + AllowDayOverflow allowOverflow = AllowDayOverflow.yes, + Direction dir = Direction.both) + if (isIntegral!T) + { + _enforceNotEmpty(); + + switch (dir) + { + case Direction.both: + { + auto begin = _begin; + auto end = _end; + + begin.add!"years"(-years, allowOverflow); + begin.add!"months"(-months, allowOverflow); + end.add!"years"(years, allowOverflow); + end.add!"months"(months, allowOverflow); + + enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval.")); + _begin = begin; + _end = end; + + return; + } + case Direction.fwd: + { + auto end = _end; + + end.add!"years"(years, allowOverflow); + end.add!"months"(months, allowOverflow); + + enforce(_valid(_begin, end), + new DateTimeException("Argument would result in an invalid Interval.")); + _end = end; + + return; + } + case Direction.bwd: + { + auto begin = _begin; + + begin.add!"years"(-years, allowOverflow); + begin.add!"months"(-months, allowOverflow); + + enforce(_valid(begin, _end), + new DateTimeException("Argument would result in an invalid Interval.")); + _begin = begin; + + return; + } + default: + assert(0, "Invalid Direction."); + } + } + } + + + /++ + Returns a range which iterates forward over the interval, starting + at $(D begin), using $(D_PARAM func) to generate each successive time + point. + + The range's $(D front) is the interval's $(D begin). $(D_PARAM func) is + used to generate the next $(D front) when $(D popFront) is called. If + $(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called + before the range is returned (so that $(D front) is a time point which + $(D_PARAM func) would generate). + + If $(D_PARAM func) ever generates a time point less than or equal to the + current $(D front) of the range, then a $(LREF DateTimeException) will be + thrown. The range will be empty and iteration complete when + $(D_PARAM func) generates a time point equal to or beyond the $(D end) + of the interval. + + There are helper functions in this module which generate common + delegates to pass to $(D fwdRange). Their documentation starts with + "Range-generating function," making them easily searchable. + + Params: + func = The function used to generate the time points of the + range over the interval. + popFirst = Whether $(D popFront) should be called on the range + before returning it. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Warning: + $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) + would be a function pointer to a pure function, but forcing + $(D_PARAM func) to be pure is far too restrictive to be useful, and + in order to have the ease of use of having functions which generate + functions to pass to $(D fwdRange), $(D_PARAM func) must be a + delegate. + + If $(D_PARAM func) retains state which changes as it is called, then + some algorithms will not work correctly, because the range's + $(D save) will have failed to have really saved the range's state. + To avoid such bugs, don't pass a delegate which is + not logically pure to $(D fwdRange). If $(D_PARAM func) is given the + same time point with two different calls, it must return the same + result both times. + + Of course, none of the functions in this module have this problem, + so it's only relevant if when creating a custom delegate. + + Example: + -------------------- + auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); + auto func = delegate (in Date date) // For iterating over even-numbered days. + { + if ((date.day & 1) == 0) + return date + dur!"days"(2); + + return date + dur!"days"(1); + }; + auto range = interval.fwdRange(func); + + // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). + assert(range.front == Date(2010, 9, 1)); + + range.popFront(); + assert(range.front == Date(2010, 9, 2)); + + range.popFront(); + assert(range.front == Date(2010, 9, 4)); + + range.popFront(); + assert(range.front == Date(2010, 9, 6)); + + range.popFront(); + assert(range.front == Date(2010, 9, 8)); + + range.popFront(); + assert(range.empty); + -------------------- + +/ + IntervalRange!(TP, Direction.fwd) fwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const + { + _enforceNotEmpty(); + + auto range = IntervalRange!(TP, Direction.fwd)(this, func); + + if (popFirst == PopFirst.yes) + range.popFront(); + + return range; + } + + + /++ + Returns a range which iterates backwards over the interval, starting + at $(D end), using $(D_PARAM func) to generate each successive time + point. + + The range's $(D front) is the interval's $(D end). $(D_PARAM func) is + used to generate the next $(D front) when $(D popFront) is called. If + $(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called + before the range is returned (so that $(D front) is a time point which + $(D_PARAM func) would generate). + + If $(D_PARAM func) ever generates a time point greater than or equal to + the current $(D front) of the range, then a $(LREF DateTimeException) will + be thrown. The range will be empty and iteration complete when + $(D_PARAM func) generates a time point equal to or less than the + $(D begin) of the interval. + + There are helper functions in this module which generate common + delegates to pass to $(D bwdRange). Their documentation starts with + "Range-generating function," making them easily searchable. + + Params: + func = The function used to generate the time points of the + range over the interval. + popFirst = Whether $(D popFront) should be called on the range + before returning it. + + Throws: + $(LREF DateTimeException) if this interval is empty. + + Warning: + $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) + would be a function pointer to a pure function, but forcing + $(D_PARAM func) to be pure is far too restrictive to be useful, and + in order to have the ease of use of having functions which generate + functions to pass to $(D fwdRange), $(D_PARAM func) must be a + delegate. + + If $(D_PARAM func) retains state which changes as it is called, then + some algorithms will not work correctly, because the range's + $(D save) will have failed to have really saved the range's state. + To avoid such bugs, don't pass a delegate which is + not logically pure to $(D fwdRange). If $(D_PARAM func) is given the + same time point with two different calls, it must return the same + result both times. + + Of course, none of the functions in this module have this problem, + so it's only relevant for custom delegates. + + Example: + -------------------- + auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); + auto func = delegate (in Date date) // For iterating over even-numbered days. + { + if ((date.day & 1) == 0) + return date - dur!"days"(2); + + return date - dur!"days"(1); + }; + auto range = interval.bwdRange(func); + + // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). + assert(range.front == Date(2010, 9, 9)); + + range.popFront(); + assert(range.front == Date(2010, 9, 8)); + + range.popFront(); + assert(range.front == Date(2010, 9, 6)); + + range.popFront(); + assert(range.front == Date(2010, 9, 4)); + + range.popFront(); + assert(range.front == Date(2010, 9, 2)); + + range.popFront(); + assert(range.empty); + -------------------- + +/ + IntervalRange!(TP, Direction.bwd) bwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const + { + _enforceNotEmpty(); + + auto range = IntervalRange!(TP, Direction.bwd)(this, func); + + if (popFirst == PopFirst.yes) + range.popFront(); + + return range; + } + + + /+ + Converts this interval to a string. + +/ + // Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't + // have versions of toString() with extra modifiers, so we define one version + // with modifiers and one without. + string toString() + { + return _toStringImpl(); + } + + + /++ + Converts this interval to a string. + +/ + // Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't + // have versions of toString() with extra modifiers, so we define one version + // with modifiers and one without. + string toString() const nothrow + { + return _toStringImpl(); + } + + +private: +package: // temporary + + /+ + Since we have two versions of toString, we have _toStringImpl + so that they can share implementations. + +/ + string _toStringImpl() const nothrow + { + import std.format : format; + try + return format("[%s - %s)", _begin, _end); + catch (Exception e) + assert(0, "format() threw."); + } + + + /+ + Throws: + $(LREF DateTimeException) if this interval is empty. + +/ + void _enforceNotEmpty(size_t line = __LINE__) const pure + { + if (empty) + throw new DateTimeException("Invalid operation for an empty Interval.", __FILE__, line); + } + + + /+ + Whether the given values form a valid time interval. + + Params: + begin = The starting point of the interval. + end = The end point of the interval. + +/ + static bool _valid(in TP begin, in TP end) pure nothrow + { + return begin <= end; + } + + + pure invariant() + { + assert(_valid(_begin, _end), "Invariant Failure: begin is not before or equal to end."); + } + + + TP _begin; + TP _end; +} + +// Test Interval's constructors. +@safe unittest +{ + assertThrown!DateTimeException(Interval!Date(Date(2010, 1, 1), Date(1, 1, 1))); + + Interval!Date(Date.init, Date.init); + Interval!TimeOfDay(TimeOfDay.init, TimeOfDay.init); + Interval!DateTime(DateTime.init, DateTime.init); + Interval!SysTime(SysTime(0), SysTime(0)); + + Interval!DateTime(DateTime.init, dur!"days"(7)); + + // Verify Examples. + Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + assert(Interval!Date(Date(1996, 1, 2), dur!"weeks"(3)) == + Interval!Date(Date(1996, 1, 2), Date(1996, 1, 23))); + assert(Interval!Date(Date(1996, 1, 2), dur!"days"(3)) == + Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5))); + assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"hours"(3)) == + Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 15, 0, 0))); + assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"minutes"(3)) == + Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 3, 0))); + assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"seconds"(3)) == + Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3))); + assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"msecs"(3000)) == + Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3))); +} + +// Test Interval's begin. +@safe unittest +{ + assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).begin == Date(1, 1, 1)); + assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).begin == Date(2010, 1, 1)); + assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).begin == Date(1997, 12, 31)); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + assert(cInterval.begin == Date(2010, 7, 4)); + assert(iInterval.begin == Date(2010, 7, 4)); + + // Verify Examples. + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == Date(1996, 1, 2)); +} + +// Test Interval's end. +@safe unittest +{ + assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1)); + assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1)); + assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).end == Date(1998, 1, 1)); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + assert(cInterval.end == Date(2012, 1, 7)); + assert(iInterval.end == Date(2012, 1, 7)); + + // Verify Examples. + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == Date(2012, 3, 1)); +} + +// Test Interval's length. +@safe unittest +{ + assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).length == dur!"days"(0)); + assert(Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).length == dur!"days"(90)); + assert(Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).length == dur!"seconds"(42_727)); + assert(Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).length == + dur!"seconds"(129_127)); + assert(Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)),SysTime(DateTime(2010, 1, 2, 12, 22, 7))).length == + dur!"seconds"(129_127)); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + assert(cInterval.length != Duration.zero); + assert(iInterval.length != Duration.zero); + + // Verify Examples. + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == dur!"days"(5903)); +} + +// Test Interval's empty. +@safe unittest +{ + assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).empty); + assert(!Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).empty); + assert(!Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).empty); + assert(!Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).empty); + assert(!Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)), SysTime(DateTime(2010, 1, 2, 12, 22, 7))).empty); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + assert(!cInterval.empty); + assert(!iInterval.empty); + + // Verify Examples. + assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty); +} + +// Test Interval's contains(time point). +@safe unittest +{ + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(Date(2010, 7, 4))); + + assert(!interval.contains(Date(2009, 7, 4))); + assert(!interval.contains(Date(2010, 7, 3))); + assert(interval.contains(Date(2010, 7, 4))); + assert(interval.contains(Date(2010, 7, 5))); + assert(interval.contains(Date(2011, 7, 1))); + assert(interval.contains(Date(2012, 1, 6))); + assert(!interval.contains(Date(2012, 1, 7))); + assert(!interval.contains(Date(2012, 1, 8))); + assert(!interval.contains(Date(2013, 1, 7))); + + const cdate = Date(2010, 7, 6); + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + assert(interval.contains(cdate)); + assert(cInterval.contains(cdate)); + assert(iInterval.contains(cdate)); + + // Verify Examples. + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(1994, 12, 24))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2000, 1, 5))); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2012, 3, 1))); +} + +// Test Interval's contains(Interval). +@safe unittest +{ + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + assertThrown!DateTimeException(interval.contains(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(interval)); + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4),dur!"days"(0)).contains( + Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + + assert(interval.contains(interval)); + assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); + assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); + assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); + assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); + assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); + assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); + assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); + assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); + assert(interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); + assert(!interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); + assert(!interval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); + assert(!interval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); + + assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).contains(interval)); + assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).contains(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).contains(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).contains(interval)); + assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).contains(interval)); + assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).contains(interval)); + assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).contains(interval)); + assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).contains(interval)); + assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).contains(interval)); + assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).contains(interval)); + assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).contains(interval)); + assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).contains(interval)); + + assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 3)))); + assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 4)))); + assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 5)))); + assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 6)))); + assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 7)))); + assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 8)))); + + assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 3)))); + assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 4)))); + assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 5)))); + assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 6)))); + assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 7)))); + assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 8)))); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + assert(interval.contains(interval)); + assert(interval.contains(cInterval)); + assert(interval.contains(iInterval)); + assert(!interval.contains(posInfInterval)); + assert(!interval.contains(cPosInfInterval)); + assert(!interval.contains(iPosInfInterval)); + assert(!interval.contains(negInfInterval)); + assert(!interval.contains(cNegInfInterval)); + assert(!interval.contains(iNegInfInterval)); + assert(cInterval.contains(interval)); + assert(cInterval.contains(cInterval)); + assert(cInterval.contains(iInterval)); + assert(!cInterval.contains(posInfInterval)); + assert(!cInterval.contains(cPosInfInterval)); + assert(!cInterval.contains(iPosInfInterval)); + assert(!cInterval.contains(negInfInterval)); + assert(!cInterval.contains(cNegInfInterval)); + assert(!cInterval.contains(iNegInfInterval)); + assert(iInterval.contains(interval)); + assert(iInterval.contains(cInterval)); + assert(iInterval.contains(iInterval)); + assert(!iInterval.contains(posInfInterval)); + assert(!iInterval.contains(cPosInfInterval)); + assert(!iInterval.contains(iPosInfInterval)); + assert(!iInterval.contains(negInfInterval)); + assert(!iInterval.contains(cNegInfInterval)); + assert(!iInterval.contains(iNegInfInterval)); + + // Verify Examples. + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( + Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( + Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( + Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4)))); +} + +// Test Interval's isBefore(time point). +@safe unittest +{ + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(Date(2010, 7, 4))); + + assert(!interval.isBefore(Date(2009, 7, 3))); + assert(!interval.isBefore(Date(2010, 7, 3))); + assert(!interval.isBefore(Date(2010, 7, 4))); + assert(!interval.isBefore(Date(2010, 7, 5))); + assert(!interval.isBefore(Date(2011, 7, 1))); + assert(!interval.isBefore(Date(2012, 1, 6))); + assert(interval.isBefore(Date(2012, 1, 7))); + assert(interval.isBefore(Date(2012, 1, 8))); + assert(interval.isBefore(Date(2013, 1, 7))); + + const cdate = Date(2010, 7, 6); + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + assert(!interval.isBefore(cdate)); + assert(!cInterval.isBefore(cdate)); + assert(!iInterval.isBefore(cdate)); + + // Verify Examples. + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(1994, 12, 24))); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2000, 1, 5))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2012, 3, 1))); +} + +// Test Interval's isBefore(Interval). +@safe unittest +{ + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + assertThrown!DateTimeException(interval.isBefore(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(interval)); + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore( + Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + + assert(!interval.isBefore(interval)); + assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); + assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); + assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); + assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); + assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); + assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); + assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); + assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); + assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); + assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); + assert(interval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); + assert(interval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); + + assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isBefore(interval)); + assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isBefore(interval)); + assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isBefore(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isBefore(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isBefore(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isBefore(interval)); + assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isBefore(interval)); + assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isBefore(interval)); + assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isBefore(interval)); + assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isBefore(interval)); + assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isBefore(interval)); + assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isBefore(interval)); + + assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 3)))); + assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 4)))); + assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 5)))); + assert(!interval.isBefore(PosInfInterval!Date(Date(2012, 1, 6)))); + assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 7)))); + assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 8)))); + + assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 3)))); + assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 4)))); + assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 5)))); + assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 6)))); + assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 7)))); + assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 8)))); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + assert(!interval.isBefore(interval)); + assert(!interval.isBefore(cInterval)); + assert(!interval.isBefore(iInterval)); + assert(!interval.isBefore(posInfInterval)); + assert(!interval.isBefore(cPosInfInterval)); + assert(!interval.isBefore(iPosInfInterval)); + assert(!interval.isBefore(negInfInterval)); + assert(!interval.isBefore(cNegInfInterval)); + assert(!interval.isBefore(iNegInfInterval)); + assert(!cInterval.isBefore(interval)); + assert(!cInterval.isBefore(cInterval)); + assert(!cInterval.isBefore(iInterval)); + assert(!cInterval.isBefore(posInfInterval)); + assert(!cInterval.isBefore(cPosInfInterval)); + assert(!cInterval.isBefore(iPosInfInterval)); + assert(!cInterval.isBefore(negInfInterval)); + assert(!cInterval.isBefore(cNegInfInterval)); + assert(!cInterval.isBefore(iNegInfInterval)); + assert(!iInterval.isBefore(interval)); + assert(!iInterval.isBefore(cInterval)); + assert(!iInterval.isBefore(iInterval)); + assert(!iInterval.isBefore(posInfInterval)); + assert(!iInterval.isBefore(cPosInfInterval)); + assert(!iInterval.isBefore(iPosInfInterval)); + assert(!iInterval.isBefore(negInfInterval)); + assert(!iInterval.isBefore(cNegInfInterval)); + assert(!iInterval.isBefore(iNegInfInterval)); + + // Verify Examples. + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( + Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( + Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( + Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4)))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2013, 3, 7)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4)))); +} + +// Test Interval's isAfter(time point). +@safe unittest +{ + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(Date(2010, 7, 4))); + + assert(interval.isAfter(Date(2009, 7, 4))); + assert(interval.isAfter(Date(2010, 7, 3))); + assert(!interval.isAfter(Date(2010, 7, 4))); + assert(!interval.isAfter(Date(2010, 7, 5))); + assert(!interval.isAfter(Date(2011, 7, 1))); + assert(!interval.isAfter(Date(2012, 1, 6))); + assert(!interval.isAfter(Date(2012, 1, 7))); + assert(!interval.isAfter(Date(2012, 1, 8))); + assert(!interval.isAfter(Date(2013, 1, 7))); + + const cdate = Date(2010, 7, 6); + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + assert(!interval.isAfter(cdate)); + assert(!cInterval.isAfter(cdate)); + assert(!iInterval.isAfter(cdate)); + + // Verify Examples. + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(1994, 12, 24))); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2000, 1, 5))); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2012, 3, 1))); +} + +// Test Interval's isAfter(Interval). +@safe unittest +{ + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + assertThrown!DateTimeException(interval.isAfter(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(interval)); + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter( + Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + + assert(!interval.isAfter(interval)); + assert(interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); + assert(!interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); + assert(interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); + assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); + assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); + assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); + assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); + assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); + assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); + assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); + assert(!interval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); + assert(!interval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); + + assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAfter(interval)); + assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAfter(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAfter(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAfter(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAfter(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAfter(interval)); + assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAfter(interval)); + assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAfter(interval)); + assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAfter(interval)); + assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAfter(interval)); + assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAfter(interval)); + assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAfter(interval)); + + assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 3)))); + assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 4)))); + assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 5)))); + assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 6)))); + assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 7)))); + assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 8)))); + + assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 3)))); + assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 4)))); + assert(!interval.isAfter(NegInfInterval!Date(Date(2010, 7, 5)))); + assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 6)))); + assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 7)))); + assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 8)))); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + assert(!interval.isAfter(interval)); + assert(!interval.isAfter(cInterval)); + assert(!interval.isAfter(iInterval)); + assert(!interval.isAfter(posInfInterval)); + assert(!interval.isAfter(cPosInfInterval)); + assert(!interval.isAfter(iPosInfInterval)); + assert(!interval.isAfter(negInfInterval)); + assert(!interval.isAfter(cNegInfInterval)); + assert(!interval.isAfter(iNegInfInterval)); + assert(!cInterval.isAfter(interval)); + assert(!cInterval.isAfter(cInterval)); + assert(!cInterval.isAfter(iInterval)); + assert(!cInterval.isAfter(posInfInterval)); + assert(!cInterval.isAfter(cPosInfInterval)); + assert(!cInterval.isAfter(iPosInfInterval)); + assert(!cInterval.isAfter(negInfInterval)); + assert(!cInterval.isAfter(cNegInfInterval)); + assert(!cInterval.isAfter(iNegInfInterval)); + assert(!iInterval.isAfter(interval)); + assert(!iInterval.isAfter(cInterval)); + assert(!iInterval.isAfter(iInterval)); + assert(!iInterval.isAfter(posInfInterval)); + assert(!iInterval.isAfter(cPosInfInterval)); + assert(!iInterval.isAfter(iPosInfInterval)); + assert(!iInterval.isAfter(negInfInterval)); + assert(!iInterval.isAfter(cNegInfInterval)); + assert(!iInterval.isAfter(iNegInfInterval)); + + // Verify Examples. + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( + Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( + Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( + Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4)))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 1, 2)))); +} + +// Test Interval's intersects(). +@safe unittest +{ + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + assertThrown!DateTimeException(interval.intersects(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects(interval)); + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects( + Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + + assert(interval.intersects(interval)); + assert(!interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); + assert(interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); + assert(!interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); + assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); + assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); + assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); + assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); + assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); + assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); + assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); + assert(!interval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); + assert(!interval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); + + assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersects(interval)); + assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersects(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersects(interval)); + assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersects(interval)); + assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersects(interval)); + assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersects(interval)); + assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersects(interval)); + assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersects(interval)); + assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersects(interval)); + assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersects(interval)); + assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersects(interval)); + assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersects(interval)); + + assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 3)))); + assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 4)))); + assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 5)))); + assert(interval.intersects(PosInfInterval!Date(Date(2012, 1, 6)))); + assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 7)))); + assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 8)))); + + assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 3)))); + assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 4)))); + assert(interval.intersects(NegInfInterval!Date(Date(2010, 7, 5)))); + assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 6)))); + assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 7)))); + assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 8)))); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + assert(interval.intersects(interval)); + assert(interval.intersects(cInterval)); + assert(interval.intersects(iInterval)); + assert(interval.intersects(posInfInterval)); + assert(interval.intersects(cPosInfInterval)); + assert(interval.intersects(iPosInfInterval)); + assert(interval.intersects(negInfInterval)); + assert(interval.intersects(cNegInfInterval)); + assert(interval.intersects(iNegInfInterval)); + assert(cInterval.intersects(interval)); + assert(cInterval.intersects(cInterval)); + assert(cInterval.intersects(iInterval)); + assert(cInterval.intersects(posInfInterval)); + assert(cInterval.intersects(cPosInfInterval)); + assert(cInterval.intersects(iPosInfInterval)); + assert(cInterval.intersects(negInfInterval)); + assert(cInterval.intersects(cNegInfInterval)); + assert(cInterval.intersects(iNegInfInterval)); + assert(iInterval.intersects(interval)); + assert(iInterval.intersects(cInterval)); + assert(iInterval.intersects(iInterval)); + assert(iInterval.intersects(posInfInterval)); + assert(iInterval.intersects(cPosInfInterval)); + assert(iInterval.intersects(iPosInfInterval)); + assert(iInterval.intersects(negInfInterval)); + assert(iInterval.intersects(cNegInfInterval)); + assert(iInterval.intersects(iNegInfInterval)); + + // Verify Examples. + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( + Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( + Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( + Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4)))); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 1, 2)))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2000, 1, 2)))); +} + +// Test Interval's intersection(). +@safe unittest +{ + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection(interval)); + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection( + Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + + assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); + assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); + assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); + assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); + + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersection(interval)); + assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersection(interval)); + assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersection(interval)); + assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersection(interval)); + + assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 7)))); + assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 8)))); + + assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 3)))); + assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 4)))); + + assert(interval.intersection(interval) == interval); + assert(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == + Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); + assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == + Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); + assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == + Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); + assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == + Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); + assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == + Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); + + assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersection(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersection(interval) == + Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); + assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersection(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersection(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersection(interval) == + Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); + assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersection(interval) == + Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); + assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersection(interval) == + Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); + assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersection(interval) == + Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); + + assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == + Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); + assert(interval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == + Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); + + assert(interval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == + Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); + assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6))); + assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + assert(!interval.intersection(interval).empty); + assert(!interval.intersection(cInterval).empty); + assert(!interval.intersection(iInterval).empty); + assert(!interval.intersection(posInfInterval).empty); + assert(!interval.intersection(cPosInfInterval).empty); + assert(!interval.intersection(iPosInfInterval).empty); + assert(!interval.intersection(negInfInterval).empty); + assert(!interval.intersection(cNegInfInterval).empty); + assert(!interval.intersection(iNegInfInterval).empty); + assert(!cInterval.intersection(interval).empty); + assert(!cInterval.intersection(cInterval).empty); + assert(!cInterval.intersection(iInterval).empty); + assert(!cInterval.intersection(posInfInterval).empty); + assert(!cInterval.intersection(cPosInfInterval).empty); + assert(!cInterval.intersection(iPosInfInterval).empty); + assert(!cInterval.intersection(negInfInterval).empty); + assert(!cInterval.intersection(cNegInfInterval).empty); + assert(!cInterval.intersection(iNegInfInterval).empty); + assert(!iInterval.intersection(interval).empty); + assert(!iInterval.intersection(cInterval).empty); + assert(!iInterval.intersection(iInterval).empty); + assert(!iInterval.intersection(posInfInterval).empty); + assert(!iInterval.intersection(cPosInfInterval).empty); + assert(!iInterval.intersection(iPosInfInterval).empty); + assert(!iInterval.intersection(negInfInterval).empty); + assert(!iInterval.intersection(cNegInfInterval).empty); + assert(!iInterval.intersection(iNegInfInterval).empty); + + // Verify Examples. + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( + Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == + Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( + Interval!Date(Date(1999, 1, 12),Date(2011, 9, 17))) == + Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( + PosInfInterval!Date(Date(1990, 7, 6))) == + Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( + PosInfInterval!Date(Date(1999, 1, 12))) == + Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( + NegInfInterval!Date(Date(1999, 7, 6))) == + Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( + NegInfInterval!Date(Date(2013, 1, 12))) == + Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); +} + +// Test Interval's isAdjacent(). +@safe unittest +{ + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + static void testInterval(in Interval!Date interval1, in Interval!Date interval2) + { + interval1.isAdjacent(interval2); + } + + assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval)); + assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), + Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + + assert(!interval.isAdjacent(interval)); + assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); + assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); + assert(interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); + assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); + assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); + assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); + assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); + assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); + assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); + assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); + assert(interval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); + assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); + + assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAdjacent(interval)); + assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAdjacent(interval)); + assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAdjacent(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAdjacent(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAdjacent(interval)); + assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAdjacent(interval)); + assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAdjacent(interval)); + assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAdjacent(interval)); + assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAdjacent(interval)); + assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAdjacent(interval)); + assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAdjacent(interval)); + assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAdjacent(interval)); + + assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3)))); + assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4)))); + assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5)))); + assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6)))); + assert(interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7)))); + assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8)))); + + assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3)))); + assert(interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4)))); + assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5)))); + assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6)))); + assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7)))); + assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8)))); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + assert(!interval.isAdjacent(interval)); + assert(!interval.isAdjacent(cInterval)); + assert(!interval.isAdjacent(iInterval)); + assert(!interval.isAdjacent(posInfInterval)); + assert(!interval.isAdjacent(cPosInfInterval)); + assert(!interval.isAdjacent(iPosInfInterval)); + assert(!interval.isAdjacent(negInfInterval)); + assert(!interval.isAdjacent(cNegInfInterval)); + assert(!interval.isAdjacent(iNegInfInterval)); + assert(!cInterval.isAdjacent(interval)); + assert(!cInterval.isAdjacent(cInterval)); + assert(!cInterval.isAdjacent(iInterval)); + assert(!cInterval.isAdjacent(posInfInterval)); + assert(!cInterval.isAdjacent(cPosInfInterval)); + assert(!cInterval.isAdjacent(iPosInfInterval)); + assert(!cInterval.isAdjacent(negInfInterval)); + assert(!cInterval.isAdjacent(cNegInfInterval)); + assert(!cInterval.isAdjacent(iNegInfInterval)); + assert(!iInterval.isAdjacent(interval)); + assert(!iInterval.isAdjacent(cInterval)); + assert(!iInterval.isAdjacent(iInterval)); + assert(!iInterval.isAdjacent(posInfInterval)); + assert(!iInterval.isAdjacent(cPosInfInterval)); + assert(!iInterval.isAdjacent(iPosInfInterval)); + assert(!iInterval.isAdjacent(negInfInterval)); + assert(!iInterval.isAdjacent(cNegInfInterval)); + assert(!iInterval.isAdjacent(iNegInfInterval)); + + // Verify Examples. + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( + Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2)))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( + Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17)))); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( + Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1)))); + + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4)))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1)))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2)))); + assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)) .isAdjacent(NegInfInterval!Date(Date(2000, 1, 2)))); +} + +// Test Interval's merge(). +@safe unittest +{ + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + static void testInterval(I)(in Interval!Date interval1, in I interval2) + { + interval1.merge(interval2); + } + + assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval)); + assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), + Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + + assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); + assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); + + assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)), interval)); + assertThrown!DateTimeException(testInterval(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)), interval)); + + assertThrown!DateTimeException(testInterval(interval, PosInfInterval!Date(Date(2012, 1, 8)))); + + assertThrown!DateTimeException(testInterval(interval, NegInfInterval!Date(Date(2010, 7, 3)))); + + assert(interval.merge(interval) == interval); + assert(interval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == + Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); + assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); + assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); + assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); + assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); + assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); + assert(interval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); + + assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).merge(interval) == + Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); + assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).merge(interval) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); + assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).merge(interval) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); + assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).merge(interval) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); + assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).merge(interval) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); + assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).merge(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).merge(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).merge(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).merge(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); + assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).merge(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); + + assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 3))) == + PosInfInterval!Date(Date(2010, 7, 3))); + assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 4))) == + PosInfInterval!Date(Date(2010, 7, 4))); + assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 5))) == + PosInfInterval!Date(Date(2010, 7, 4))); + assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 6))) == + PosInfInterval!Date(Date(2010, 7, 4))); + assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 7))) == + PosInfInterval!Date(Date(2010, 7, 4))); + + assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 4))) == + NegInfInterval!Date(Date(2012, 1, 7))); + assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 5))) == + NegInfInterval!Date(Date(2012, 1, 7))); + assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 6))) == + NegInfInterval!Date(Date(2012, 1, 7))); + assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 7))) == + NegInfInterval!Date(Date(2012, 1, 7))); + assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 8))) == + NegInfInterval!Date(Date(2012, 1, 8))); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + assert(!interval.merge(interval).empty); + assert(!interval.merge(cInterval).empty); + assert(!interval.merge(iInterval).empty); + assert(!interval.merge(posInfInterval).empty); + assert(!interval.merge(cPosInfInterval).empty); + assert(!interval.merge(iPosInfInterval).empty); + assert(!interval.merge(negInfInterval).empty); + assert(!interval.merge(cNegInfInterval).empty); + assert(!interval.merge(iNegInfInterval).empty); + assert(!cInterval.merge(interval).empty); + assert(!cInterval.merge(cInterval).empty); + assert(!cInterval.merge(iInterval).empty); + assert(!cInterval.merge(posInfInterval).empty); + assert(!cInterval.merge(cPosInfInterval).empty); + assert(!cInterval.merge(iPosInfInterval).empty); + assert(!cInterval.merge(negInfInterval).empty); + assert(!cInterval.merge(cNegInfInterval).empty); + assert(!cInterval.merge(iNegInfInterval).empty); + assert(!iInterval.merge(interval).empty); + assert(!iInterval.merge(cInterval).empty); + assert(!iInterval.merge(iInterval).empty); + assert(!iInterval.merge(posInfInterval).empty); + assert(!iInterval.merge(cPosInfInterval).empty); + assert(!iInterval.merge(iPosInfInterval).empty); + assert(!iInterval.merge(negInfInterval).empty); + assert(!iInterval.merge(cNegInfInterval).empty); + assert(!iInterval.merge(iNegInfInterval).empty); + + // Verify Examples. + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == + Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == + Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(1990, 7, 6))) == + PosInfInterval!Date(Date(1990, 7 , 6))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(2012, 3, 1))) == + PosInfInterval!Date(Date(1996, 1 , 2))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1996, 1, 2))) == + NegInfInterval!Date(Date(2012, 3 , 1))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) == + NegInfInterval!Date(Date(2013, 1 , 12))); +} + +// Test Interval's span(). +@safe unittest +{ + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + static void testInterval(in Interval!Date interval1, in Interval!Date interval2) + { + interval1.span(interval2); + } + + assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)),interval)); + assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), + Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + + assert(interval.span(interval) == interval); + assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == + Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); + assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == + Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); + assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); + assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); + assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); + assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); + assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); + assert(interval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); + assert(interval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9))); + + assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).span(interval) == + Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); + assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).span(interval) == + Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); + assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).span(interval) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); + assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).span(interval) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); + assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).span(interval) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); + assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).span(interval) == + Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); + assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).span(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).span(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).span(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); + assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).span(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); + assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).span(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); + assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).span(interval) == + Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9))); + + assert(interval.span(PosInfInterval!Date(Date(2010, 7, 3))) == + PosInfInterval!Date(Date(2010, 7, 3))); + assert(interval.span(PosInfInterval!Date(Date(2010, 7, 4))) == + PosInfInterval!Date(Date(2010, 7, 4))); + assert(interval.span(PosInfInterval!Date(Date(2010, 7, 5))) == + PosInfInterval!Date(Date(2010, 7, 4))); + assert(interval.span(PosInfInterval!Date(Date(2012, 1, 6))) == + PosInfInterval!Date(Date(2010, 7, 4))); + assert(interval.span(PosInfInterval!Date(Date(2012, 1, 7))) == + PosInfInterval!Date(Date(2010, 7, 4))); + assert(interval.span(PosInfInterval!Date(Date(2012, 1, 8))) == + PosInfInterval!Date(Date(2010, 7, 4))); + + assert(interval.span(NegInfInterval!Date(Date(2010, 7, 3))) == + NegInfInterval!Date(Date(2012, 1, 7))); + assert(interval.span(NegInfInterval!Date(Date(2010, 7, 4))) == + NegInfInterval!Date(Date(2012, 1, 7))); + assert(interval.span(NegInfInterval!Date(Date(2010, 7, 5))) == + NegInfInterval!Date(Date(2012, 1, 7))); + assert(interval.span(NegInfInterval!Date(Date(2012, 1, 6))) == + NegInfInterval!Date(Date(2012, 1, 7))); + assert(interval.span(NegInfInterval!Date(Date(2012, 1, 7))) == + NegInfInterval!Date(Date(2012, 1, 7))); + assert(interval.span(NegInfInterval!Date(Date(2012, 1, 8))) == + NegInfInterval!Date(Date(2012, 1, 8))); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); + auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); + assert(!interval.span(interval).empty); + assert(!interval.span(cInterval).empty); + assert(!interval.span(iInterval).empty); + assert(!interval.span(posInfInterval).empty); + assert(!interval.span(cPosInfInterval).empty); + assert(!interval.span(iPosInfInterval).empty); + assert(!interval.span(negInfInterval).empty); + assert(!interval.span(cNegInfInterval).empty); + assert(!interval.span(iNegInfInterval).empty); + assert(!cInterval.span(interval).empty); + assert(!cInterval.span(cInterval).empty); + assert(!cInterval.span(iInterval).empty); + assert(!cInterval.span(posInfInterval).empty); + assert(!cInterval.span(cPosInfInterval).empty); + assert(!cInterval.span(iPosInfInterval).empty); + assert(!cInterval.span(negInfInterval).empty); + assert(!cInterval.span(cNegInfInterval).empty); + assert(!cInterval.span(iNegInfInterval).empty); + assert(!iInterval.span(interval).empty); + assert(!iInterval.span(cInterval).empty); + assert(!iInterval.span(iInterval).empty); + assert(!iInterval.span(posInfInterval).empty); + assert(!iInterval.span(cPosInfInterval).empty); + assert(!iInterval.span(iPosInfInterval).empty); + assert(!iInterval.span(negInfInterval).empty); + assert(!iInterval.span(cNegInfInterval).empty); + assert(!iInterval.span(iNegInfInterval).empty); + + // Verify Examples. + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) == + Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == + Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(1990, 7, 6))) == + PosInfInterval!Date(Date(1990, 7 , 6))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(2050, 1, 1))) == + PosInfInterval!Date(Date(1996, 1 , 2))); + + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1602, 5, 21))) == + NegInfInterval!Date(Date(2012, 3 , 1))); + assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) == + NegInfInterval!Date(Date(2013, 1 , 12))); +} + +// Test Interval's shift(duration). +@safe unittest +{ + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + static void testIntervalFail(Interval!Date interval, in Duration duration) + { + interval.shift(duration); + } + + assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1))); + + static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__) + { + interval.shift(duration); + assert(interval == expected); + } + + testInterval(interval, dur!"days"(22), Interval!Date(Date(2010, 7, 26), Date(2012, 1, 29))); + testInterval(interval, dur!"days"(-22), Interval!Date(Date(2010, 6, 12), Date(2011, 12, 16))); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + static assert(!__traits(compiles, cInterval.shift(dur!"days"(5)))); + static assert(!__traits(compiles, iInterval.shift(dur!"days"(5)))); + + // Verify Examples. + auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); + auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); + + interval1.shift(dur!"days"(50)); + assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25))); + + interval2.shift(dur!"days"(-50)); + assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15))); +} + +// Test Interval's shift(int, int, AllowDayOverflow). +@safe unittest +{ + { + auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + + static void testIntervalFail(Interval!Date interval, int years, int months) + { + interval.shift(years, months); + } + + assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0)); + + static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, + in I expected, size_t line = __LINE__) + { + interval.shift(years, months, allow); + assert(interval == expected); + } + + testInterval(interval, 5, 0, AllowDayOverflow.yes, Interval!Date(Date(2015, 7, 4), Date(2017, 1, 7))); + testInterval(interval, -5, 0, AllowDayOverflow.yes, Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7))); + + auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31)); + + testInterval(interval2, 1, 1, AllowDayOverflow.yes, Interval!Date(Date(2001, 3, 1), Date(2011, 7, 1))); + testInterval(interval2, 1, -1, AllowDayOverflow.yes, Interval!Date(Date(2000, 12, 29), Date(2011, 5, 1))); + testInterval(interval2, -1, -1, AllowDayOverflow.yes, Interval!Date(Date(1998, 12, 29), Date(2009, 5, 1))); + testInterval(interval2, -1, 1, AllowDayOverflow.yes, Interval!Date(Date(1999, 3, 1), Date(2009, 7, 1))); + + testInterval(interval2, 1, 1, AllowDayOverflow.no, Interval!Date(Date(2001, 2, 28), Date(2011, 6, 30))); + testInterval(interval2, 1, -1, AllowDayOverflow.no, Interval!Date(Date(2000, 12, 29), Date(2011, 4, 30))); + testInterval(interval2, -1, -1, AllowDayOverflow.no, Interval!Date(Date(1998, 12, 29), Date(2009, 4, 30))); + testInterval(interval2, -1, 1, AllowDayOverflow.no, Interval!Date(Date(1999, 2, 28), Date(2009, 6, 30))); + } + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + static assert(!__traits(compiles, cInterval.shift(5))); + static assert(!__traits(compiles, iInterval.shift(5))); + + // Verify Examples. + auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + + interval1.shift(2); + assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1))); + + interval2.shift(-2); + assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1))); +} + +// Test Interval's expand(Duration). +@safe unittest +{ + auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7)); + + static void testIntervalFail(I)(I interval, in Duration duration) + { + interval.expand(duration); + } + + assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1))); + assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)), dur!"days"(-5))); + + static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__) + { + interval.expand(duration); + assert(interval == expected); + } + + testInterval(interval, dur!"days"(22), Interval!Date(Date(2000, 6, 12), Date(2012, 1, 29))); + testInterval(interval, dur!"days"(-22), Interval!Date(Date(2000, 7, 26), Date(2011, 12, 16))); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + static assert(!__traits(compiles, cInterval.expand(dur!"days"(5)))); + static assert(!__traits(compiles, iInterval.expand(dur!"days"(5)))); + + // Verify Examples. + auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + + interval1.expand(dur!"days"(2)); + assert(interval1 == Interval!Date(Date(1995, 12, 31), Date(2012, 3, 3))); + + interval2.expand(dur!"days"(-2)); + assert(interval2 == Interval!Date(Date(1996, 1, 4), Date(2012, 2, 28))); +} + +// Test Interval's expand(int, int, AllowDayOverflow, Direction) +@safe unittest +{ + { + auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7)); + + static void testIntervalFail(Interval!Date interval, int years, int months) + { + interval.expand(years, months); + } + + assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0)); + assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)), -5, 0)); + + static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, Direction dir, + in I expected, size_t line = __LINE__) + { + interval.expand(years, months, allow, dir); + assert(interval == expected); + } + + testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.both, + Interval!Date(Date(1995, 7, 4), Date(2017, 1, 7))); + testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.both, + Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7))); + + testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.fwd, + Interval!Date(Date(2000, 7, 4), Date(2017, 1, 7))); + testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.fwd, + Interval!Date(Date(2000, 7, 4), Date(2007, 1, 7))); + + testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.bwd, + Interval!Date(Date(1995, 7, 4), Date(2012, 1, 7))); + testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.bwd, + Interval!Date(Date(2005, 7, 4), Date(2012, 1, 7))); + + auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31)); + + testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.both, + Interval!Date(Date(1998, 12, 29), Date(2011, 7, 1))); + testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.both, + Interval!Date(Date(1999, 3, 1), Date(2011, 5, 1))); + testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.both, + Interval!Date(Date(2001, 3, 1), Date(2009, 5, 1))); + testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.both, + Interval!Date(Date(2000, 12, 29), Date(2009, 7, 1))); + + testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.both, + Interval!Date(Date(1998, 12, 29), Date(2011, 6, 30))); + testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.both, + Interval!Date(Date(1999, 2, 28), Date(2011, 4, 30))); + testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.both, + Interval!Date(Date(2001, 2, 28), Date(2009, 4, 30))); + testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.both, + Interval!Date(Date(2000, 12, 29), Date(2009, 6, 30))); + + testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.fwd, + Interval!Date(Date(2000, 1, 29), Date(2011, 7, 1))); + testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.fwd, + Interval!Date(Date(2000, 1, 29), Date(2011, 5, 1))); + testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.fwd, + Interval!Date(Date(2000, 1, 29), Date(2009, 5, 1))); + testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.fwd, + Interval!Date(Date(2000, 1, 29), Date(2009, 7, 1))); + + testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.fwd, + Interval!Date(Date(2000, 1, 29), Date(2011, 6, 30))); + testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.fwd, + Interval!Date(Date(2000, 1, 29), Date(2011, 4, 30))); + testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.fwd, + Interval!Date(Date(2000, 1, 29), Date(2009, 4, 30))); + testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.fwd, + Interval!Date(Date(2000, 1, 29), Date(2009, 6, 30))); + + testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.bwd, + Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31))); + testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.bwd, + Interval!Date(Date(1999, 3, 1), Date(2010, 5, 31))); + testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.bwd, + Interval!Date(Date(2001, 3, 1), Date(2010, 5, 31))); + testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.bwd, + Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31))); + + testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.bwd, + Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31))); + testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.bwd, + Interval!Date(Date(1999, 2, 28), Date(2010, 5, 31))); + testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.bwd, + Interval!Date(Date(2001, 2, 28), Date(2010, 5, 31))); + testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.bwd, + Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31))); + } + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + static assert(!__traits(compiles, cInterval.expand(5))); + static assert(!__traits(compiles, iInterval.expand(5))); + + // Verify Examples. + auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); + + interval1.expand(2); + assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); + + interval2.expand(-2); + assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); +} + +// Test Interval's fwdRange. +@system unittest +{ + { + auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)); + + static void testInterval1(Interval!Date interval) + { + interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); + } + + assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + + static void testInterval2(Interval!Date interval) + { + interval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront(); + } + + assertThrown!DateTimeException(testInterval2(interval)); + + assert(!interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); + assert(interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).empty); + + assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front == + Date(2010, 9, 12)); + + assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange( + everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 17)); + } + + // Verify Examples. + { + auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); + auto func = delegate (in Date date) + { + if ((date.day & 1) == 0) + return date + dur!"days"(2); + return date + dur!"days"(1); + }; + auto range = interval.fwdRange(func); + + // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). + assert(range.front == Date(2010, 9, 1)); + + range.popFront(); + assert(range.front == Date(2010, 9, 2)); + + range.popFront(); + assert(range.front == Date(2010, 9, 4)); + + range.popFront(); + assert(range.front == Date(2010, 9, 6)); + + range.popFront(); + assert(range.front == Date(2010, 9, 8)); + + range.popFront(); + assert(range.empty); + } + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + assert(!cInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); + assert(!iInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); +} + +// Test Interval's bwdRange. +@system unittest +{ + { + auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)); + + static void testInterval1(Interval!Date interval) + { + interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); + } + + assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); + + static void testInterval2(Interval!Date interval) + { + interval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront(); + } + + assertThrown!DateTimeException(testInterval2(interval)); + + assert(!interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty); + assert(interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).empty); + + assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange( + everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front == Date(2010, 10, 1)); + + assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange( + everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 24)); + } + + // Verify Examples. + { + auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); + auto func = delegate (in Date date) + { + if ((date.day & 1) == 0) + return date - dur!"days"(2); + return date - dur!"days"(1); + }; + auto range = interval.bwdRange(func); + + // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). + assert(range.front == Date(2010, 9, 9)); + + range.popFront(); + assert(range.front == Date(2010, 9, 8)); + + range.popFront(); + assert(range.front == Date(2010, 9, 6)); + + range.popFront(); + assert(range.front == Date(2010, 9, 4)); + + range.popFront(); + assert(range.front == Date(2010, 9, 2)); + + range.popFront(); + assert(range.empty); + } + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + assert(!cInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); + assert(!iInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); +} + +// Test Interval's toString(). +@safe unittest +{ + assert(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).toString() == "[2010-Jul-04 - 2012-Jan-07)"); + + const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); + assert(cInterval.toString()); + assert(iInterval.toString()); +} diff --git a/std/datetime/package.d b/std/datetime/package.d index 371bc12ed..c1d3213fe 100644 --- a/std/datetime/package.d +++ b/std/datetime/package.d @@ -172,56 +172,6 @@ else version(Posix) // Section with public enums and constants. //============================================================================== -/++ - Indicates a direction in time. One example of its use is $(LREF2 .Interval, Interval)'s - $(LREF expand, expand) function which uses it to indicate whether the interval should - be expanded backwards (into the past), forwards (into the future), or both. - +/ -enum Direction -{ - /// Backward. - bwd, - - /// Forward. - fwd, - - /// Both backward and forward. - both -} - -/++ - Used to indicate whether $(D popFront) should be called immediately upon - creating a range. The idea is that for some functions used to generate a - range for an interval, $(D front) is not necessarily a time point which - would ever be generated by the range. To get the first time point - in the range to match what the function generates, then use - $(D PopFirst.yes) to indicate that the range should have $(D popFront) - called on it before the range is returned so that $(D front) is a time point - which the function would generate. - - For instance, if the function used to generate a range of time points - generated successive Easters (i.e. you're iterating over all of the Easters - within the interval), the initial date probably isn't an Easter. Using - $(D PopFirst.yes) would tell the function which returned the - range that $(D popFront) was to be called so that front would then be - an Easter - the next one generated by the function (which when - iterating forward would be the Easter following the original $(D front), - while when iterating backward, it would be the Easter prior to the - original $(D front)). If $(D PopFirst.no) were used, then $(D front) would - remain the original time point and it would not necessarily be a time point - which would be generated by the range-generating function (which in many - cases is exactly what is desired - - e.g. if iterating over every day starting at the beginning - of the interval). - - If set to $(D PopFirst.no), then popFront is not called before returning - the range. - - Otherwise, if set to $(D PopFirst.yes), then popFront is called before - returning the range. - +/ -alias PopFirst = Flag!"popFirst"; - /++ Used by StopWatch to indicate whether it should start immediately upon construction. @@ -18269,3181 +18219,6 @@ private: // Section with intervals. //============================================================================== -/++ - Represents an interval of time. - - An $(D Interval) has a starting point and an end point. The interval of time - is therefore the time starting at the starting point up to, but not - including, the end point. e.g. - - $(BOOKTABLE, - $(TR $(TD [January 5th, 2010 - March 10th, 2010$(RPAREN))) - $(TR $(TD [05:00:30 - 12:00:00$(RPAREN))) - $(TR $(TD [1982-01-04T08:59:00 - 2010-07-04T12:00:00$(RPAREN))) - ) - - A range can be obtained from an $(D Interval), allowing iteration over - that interval, with the exact time points which are iterated over depending - on the function which generates the range. - +/ -struct Interval(TP) -{ -public: - - /++ - Params: - begin = The time point which begins the interval. - end = The time point which ends (but is not included in) the - interval. - - Throws: - $(LREF DateTimeException) if $(D_PARAM end) is before $(D_PARAM begin). - - Example: --------------------- -Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); --------------------- - +/ - this(U)(in TP begin, in U end) pure - if (is(Unqual!TP == Unqual!U)) - { - if (!_valid(begin, end)) - throw new DateTimeException("Arguments would result in an invalid Interval."); - - _begin = cast(TP) begin; - _end = cast(TP) end; - } - - - /++ - Params: - begin = The time point which begins the interval. - duration = The duration from the starting point to the end point. - - Throws: - $(LREF DateTimeException) if the resulting $(D end) is before - $(D begin). - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), dur!"days"(3)) == - Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5))); --------------------- - +/ - this(D)(in TP begin, in D duration) pure - if (__traits(compiles, begin + duration)) - { - _begin = cast(TP) begin; - _end = begin + duration; - - if (!_valid(_begin, _end)) - throw new DateTimeException("Arguments would result in an invalid Interval."); - } - - - /++ - Params: - rhs = The $(LREF2 .Interval, Interval) to assign to this one. - +/ - ref Interval opAssign(const ref Interval rhs) pure nothrow - { - _begin = cast(TP) rhs._begin; - _end = cast(TP) rhs._end; - return this; - } - - - /++ - Params: - rhs = The $(LREF2 .Interval, Interval) to assign to this one. - +/ - ref Interval opAssign(Interval rhs) pure nothrow - { - _begin = cast(TP) rhs._begin; - _end = cast(TP) rhs._end; - return this; - } - - - /++ - The starting point of the interval. It is included in the interval. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == - Date(1996, 1, 2)); --------------------- - +/ - @property TP begin() const pure nothrow - { - return cast(TP)_begin; - } - - - /++ - The starting point of the interval. It is included in the interval. - - Params: - timePoint = The time point to set $(D begin) to. - - Throws: - $(LREF DateTimeException) if the resulting interval would be invalid. - +/ - @property void begin(TP timePoint) pure - { - if (!_valid(timePoint, _end)) - throw new DateTimeException("Arguments would result in an invalid Interval."); - - _begin = timePoint; - } - - - /++ - The end point of the interval. It is excluded from the interval. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == - Date(2012, 3, 1)); --------------------- - +/ - @property TP end() const pure nothrow - { - return cast(TP)_end; - } - - - /++ - The end point of the interval. It is excluded from the interval. - - Params: - timePoint = The time point to set end to. - - Throws: - $(LREF DateTimeException) if the resulting interval would be invalid. - +/ - @property void end(TP timePoint) pure - { - if (!_valid(_begin, timePoint)) - throw new DateTimeException("Arguments would result in an invalid Interval."); - - _end = timePoint; - } - - - /++ - Returns the duration between $(D begin) and $(D end). - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == - dur!"days"(5903)); --------------------- - +/ - @property auto length() const pure nothrow - { - return _end - _begin; - } - - - /++ - Whether the interval's length is 0, that is, whether $(D begin == end). - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty); -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty); --------------------- - +/ - @property bool empty() const pure nothrow - { - return _begin == _end; - } - - - /++ - Whether the given time point is within this interval. - - Params: - timePoint = The time point to check for inclusion in this interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( - Date(1994, 12, 24))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( - Date(2000, 1, 5))); -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( - Date(2012, 3, 1))); --------------------- - +/ - bool contains(in TP timePoint) const pure - { - _enforceNotEmpty(); - - return timePoint >= _begin && timePoint < _end; - } - - - /++ - Whether the given interval is completely within this interval. - - Params: - interval = The interval to check for inclusion in this interval. - - Throws: - $(LREF DateTimeException) if either interval is empty. - - Example: --------------------- -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( - Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( - Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); - -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( - Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); --------------------- - +/ - bool contains(in Interval interval) const pure - { - _enforceNotEmpty(); - interval._enforceNotEmpty(); - - return interval._begin >= _begin && - interval._begin < _end && - interval._end <= _end; - } - - - /++ - Whether the given interval is completely within this interval. - - Always returns false (unless this interval is empty), because an - interval going to positive infinity can never be contained in a finite - interval. - - Params: - interval = The interval to check for inclusion in this interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( - PosInfInterval!Date(Date(1999, 5, 4)))); --------------------- - +/ - bool contains(in PosInfInterval!TP interval) const pure - { - _enforceNotEmpty(); - - return false; - } - - - /++ - Whether the given interval is completely within this interval. - - Always returns false (unless this interval is empty), because an - interval beginning at negative infinity can never be contained in a - finite interval. - - Params: - interval = The interval to check for inclusion in this interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( - NegInfInterval!Date(Date(1996, 5, 4)))); --------------------- - +/ - bool contains(in NegInfInterval!TP interval) const pure - { - _enforceNotEmpty(); - - return false; - } - - - /++ - Whether this interval is before the given time point. - - Params: - timePoint = The time point to check whether this interval is before - it. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( - Date(1994, 12, 24))); - -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( - Date(2000, 1, 5))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( - Date(2012, 3, 1))); --------------------- - +/ - bool isBefore(in TP timePoint) const pure - { - _enforceNotEmpty(); - - return _end <= timePoint; - } - - - /++ - Whether this interval is before the given interval and does not - intersect with it. - - Params: - interval = The interval to check for against this interval. - - Throws: - $(LREF DateTimeException) if either interval is empty. - - Example: --------------------- -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( - Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); - -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( - Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( - Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1)))); --------------------- - +/ - bool isBefore(in Interval interval) const pure - { - _enforceNotEmpty(); - interval._enforceNotEmpty(); - - return _end <= interval._begin; - } - - - /++ - Whether this interval is before the given interval and does not - intersect with it. - - Params: - interval = The interval to check for against this interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( - PosInfInterval!Date(Date(1999, 5, 4)))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( - PosInfInterval!Date(Date(2013, 3, 7)))); --------------------- - +/ - bool isBefore(in PosInfInterval!TP interval) const pure - { - _enforceNotEmpty(); - - return _end <= interval._begin; - } - - - /++ - Whether this interval is before the given interval and does not - intersect with it. - - Always returns false (unless this interval is empty) because a finite - interval can never be before an interval beginning at negative infinity. - - Params: - interval = The interval to check for against this interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( - NegInfInterval!Date(Date(1996, 5, 4)))); --------------------- - +/ - bool isBefore(in NegInfInterval!TP interval) const pure - { - _enforceNotEmpty(); - - return false; - } - - - /++ - Whether this interval is after the given time point. - - Params: - timePoint = The time point to check whether this interval is after - it. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( - Date(1994, 12, 24))); - -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( - Date(2000, 1, 5))); - -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( - Date(2012, 3, 1))); --------------------- - +/ - bool isAfter(in TP timePoint) const pure - { - _enforceNotEmpty(); - - return timePoint < _begin; - } - - - /++ - Whether this interval is after the given interval and does not intersect - it. - - Params: - interval = The interval to check against this interval. - - Throws: - $(LREF DateTimeException) if either interval is empty. - - Example: --------------------- -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( - Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); - -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( - Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( - Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); --------------------- - +/ - bool isAfter(in Interval interval) const pure - { - _enforceNotEmpty(); - interval._enforceNotEmpty(); - - return _begin >= interval._end; - } - - - /++ - Whether this interval is after the given interval and does not intersect - it. - - Always returns false (unless this interval is empty) because a finite - interval can never be after an interval going to positive infinity. - - Params: - interval = The interval to check against this interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( - PosInfInterval!Date(Date(1999, 5, 4)))); --------------------- - +/ - bool isAfter(in PosInfInterval!TP interval) const pure - { - _enforceNotEmpty(); - - return false; - } - - - /++ - Whether this interval is after the given interval and does not intersect - it. - - Params: - interval = The interval to check against this interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( - NegInfInterval!Date(Date(1996, 1, 2)))); --------------------- - +/ - bool isAfter(in NegInfInterval!TP interval) const pure - { - _enforceNotEmpty(); - - return _begin >= interval._end; - } - - - /++ - Whether the given interval overlaps this interval. - - Params: - interval = The interval to check for intersection with this interval. - - Throws: - $(LREF DateTimeException) if either interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( - Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( - Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); - -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( - Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); --------------------- - +/ - bool intersects(in Interval interval) const pure - { - _enforceNotEmpty(); - interval._enforceNotEmpty(); - - return interval._begin < _end && interval._end > _begin; - } - - - /++ - Whether the given interval overlaps this interval. - - Params: - interval = The interval to check for intersection with this interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( - PosInfInterval!Date(Date(1999, 5, 4)))); - -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( - PosInfInterval!Date(Date(2012, 3, 1)))); --------------------- - +/ - bool intersects(in PosInfInterval!TP interval) const pure - { - _enforceNotEmpty(); - - return _end > interval._begin; - } - - - /++ - Whether the given interval overlaps this interval. - - Params: - interval = The interval to check for intersection with this interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( - NegInfInterval!Date(Date(1996, 1, 2)))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( - NegInfInterval!Date(Date(2000, 1, 2)))); --------------------- - +/ - bool intersects(in NegInfInterval!TP interval) const pure - { - _enforceNotEmpty(); - - return _begin < interval._end; - } - - - /++ - Returns the intersection of two intervals - - Params: - interval = The interval to intersect with this interval. - - Throws: - $(LREF DateTimeException) if the two intervals do not intersect or if - either interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( - Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == - Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( - Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == - Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); --------------------- - +/ - Interval intersection(in Interval interval) const - { - import std.format : format; - - enforce( - this.intersects(interval), - new DateTimeException(format("%s and %s do not intersect.", this, interval)) - ); - - auto begin = _begin > interval._begin ? _begin : interval._begin; - auto end = _end < interval._end ? _end : interval._end; - - return Interval(begin, end); - } - - - /++ - Returns the intersection of two intervals - - Params: - interval = The interval to intersect with this interval. - - Throws: - $(LREF DateTimeException) if the two intervals do not intersect or if - this interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( - PosInfInterval!Date(Date(1990, 7, 6))) == - Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( - PosInfInterval!Date(Date(1999, 1, 12))) == - Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); --------------------- - +/ - Interval intersection(in PosInfInterval!TP interval) const - { - import std.format : format; - - enforce( - this.intersects(interval), - new DateTimeException(format("%s and %s do not intersect.", this, interval)) - ); - - return Interval(_begin > interval._begin ? _begin : interval._begin, _end); - } - - - /++ - Returns the intersection of two intervals - - Params: - interval = The interval to intersect with this interval. - - Throws: - $(LREF DateTimeException) if the two intervals do not intersect or if - this interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( - NegInfInterval!Date(Date(1999, 7, 6))) == - Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( - NegInfInterval!Date(Date(2013, 1, 12))) == - Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); --------------------- - +/ - Interval intersection(in NegInfInterval!TP interval) const - { - import std.format : format; - - enforce( - this.intersects(interval), - new DateTimeException(format("%s and %s do not intersect.", this, interval)) - ); - - return Interval(_begin, _end < interval._end ? _end : interval._end); - } - - - /++ - Whether the given interval is adjacent to this interval. - - Params: - interval = The interval to check whether its adjecent to this - interval. - - Throws: - $(LREF DateTimeException) if either interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( - Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2)))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( - Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17)))); - -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( - Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1)))); --------------------- - +/ - bool isAdjacent(in Interval interval) const pure - { - _enforceNotEmpty(); - interval._enforceNotEmpty(); - - return _begin == interval._end || _end == interval._begin; - } - - - /++ - Whether the given interval is adjacent to this interval. - - Params: - interval = The interval to check whether its adjecent to this - interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( - PosInfInterval!Date(Date(1999, 5, 4)))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( - PosInfInterval!Date(Date(2012, 3, 1)))); --------------------- - +/ - bool isAdjacent(in PosInfInterval!TP interval) const pure - { - _enforceNotEmpty(); - - return _end == interval._begin; - } - - - /++ - Whether the given interval is adjacent to this interval. - - Params: - interval = The interval to check whether its adjecent to this - interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( - NegInfInterval!Date(Date(1996, 1, 2)))); - -assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( - NegInfInterval!Date(Date(2000, 1, 2)))); --------------------- - +/ - bool isAdjacent(in NegInfInterval!TP interval) const pure - { - _enforceNotEmpty(); - - return _begin == interval._end; - } - - - /++ - Returns the union of two intervals - - Params: - interval = The interval to merge with this interval. - - Throws: - $(LREF DateTimeException) if the two intervals do not intersect and are - not adjacent or if either interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( - Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == - Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( - Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == - Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); --------------------- - +/ - Interval merge(in Interval interval) const - { - import std.format : format; - - enforce(this.isAdjacent(interval) || this.intersects(interval), - new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); - - auto begin = _begin < interval._begin ? _begin : interval._begin; - auto end = _end > interval._end ? _end : interval._end; - - return Interval(begin, end); - } - - - /++ - Returns the union of two intervals - - Params: - interval = The interval to merge with this interval. - - Throws: - $(LREF DateTimeException) if the two intervals do not intersect and are - not adjacent or if this interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( - PosInfInterval!Date(Date(1990, 7, 6))) == - PosInfInterval!Date(Date(1990, 7 , 6))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( - PosInfInterval!Date(Date(2012, 3, 1))) == - PosInfInterval!Date(Date(1996, 1 , 2))); --------------------- - +/ - PosInfInterval!TP merge(in PosInfInterval!TP interval) const - { - import std.format : format; - - enforce(this.isAdjacent(interval) || this.intersects(interval), - new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); - - return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin); - } - - - /++ - Returns the union of two intervals - - Params: - interval = The interval to merge with this interval. - - Throws: - $(LREF DateTimeException) if the two intervals do not intersect and are not - adjacent or if this interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( - NegInfInterval!Date(Date(1996, 1, 2))) == - NegInfInterval!Date(Date(2012, 3 , 1))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( - NegInfInterval!Date(Date(2013, 1, 12))) == - NegInfInterval!Date(Date(2013, 1 , 12))); --------------------- - +/ - NegInfInterval!TP merge(in NegInfInterval!TP interval) const - { - import std.format : format; - - enforce(this.isAdjacent(interval) || this.intersects(interval), - new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); - - return NegInfInterval!TP(_end > interval._end ? _end : interval._end); - } - - - /++ - Returns an interval that covers from the earliest time point of two - intervals up to (but not including) the latest time point of two - intervals. - - Params: - interval = The interval to create a span together with this interval. - - Throws: - $(LREF DateTimeException) if either interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( - Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) == - Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( - Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == - Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); --------------------- - +/ - Interval span(in Interval interval) const pure - { - _enforceNotEmpty(); - interval._enforceNotEmpty(); - - auto begin = _begin < interval._begin ? _begin : interval._begin; - auto end = _end > interval._end ? _end : interval._end; - - return Interval(begin, end); - } - - - /++ - Returns an interval that covers from the earliest time point of two - intervals up to (but not including) the latest time point of two - intervals. - - Params: - interval = The interval to create a span together with this interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( - PosInfInterval!Date(Date(1990, 7, 6))) == - PosInfInterval!Date(Date(1990, 7 , 6))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( - PosInfInterval!Date(Date(2050, 1, 1))) == - PosInfInterval!Date(Date(1996, 1 , 2))); --------------------- - +/ - PosInfInterval!TP span(in PosInfInterval!TP interval) const pure - { - _enforceNotEmpty(); - - return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin); - } - - - /++ - Returns an interval that covers from the earliest time point of two - intervals up to (but not including) the latest time point of two - intervals. - - Params: - interval = The interval to create a span together with this interval. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Example: --------------------- -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( - NegInfInterval!Date(Date(1602, 5, 21))) == - NegInfInterval!Date(Date(2012, 3 , 1))); - -assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( - NegInfInterval!Date(Date(2013, 1, 12))) == - NegInfInterval!Date(Date(2013, 1 , 12))); --------------------- - +/ - NegInfInterval!TP span(in NegInfInterval!TP interval) const pure - { - _enforceNotEmpty(); - - return NegInfInterval!TP(_end > interval._end ? _end : interval._end); - } - - - /++ - Shifts the interval forward or backwards in time by the given duration - (a positive duration shifts the interval forward; a negative duration - shifts it backward). Effectively, it does $(D begin += duration) and - $(D end += duration). - - Params: - duration = The duration to shift the interval by. - - Throws: - $(LREF DateTimeException) this interval is empty or if the resulting - interval would be invalid. - - Example: --------------------- -auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); -auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); - -interval1.shift(dur!"days"(50)); -assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25))); - -interval2.shift(dur!"days"(-50)); -assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15))); --------------------- - +/ - void shift(D)(D duration) pure - if (__traits(compiles, begin + duration)) - { - _enforceNotEmpty(); - - auto begin = _begin + duration; - auto end = _end + duration; - - if (!_valid(begin, end)) - throw new DateTimeException("Argument would result in an invalid Interval."); - - _begin = begin; - _end = end; - } - - - static if (__traits(compiles, begin.add!"months"(1)) && - __traits(compiles, begin.add!"years"(1))) - { - /++ - Shifts the interval forward or backwards in time by the given number - of years and/or months (a positive number of years and months shifts - the interval forward; a negative number shifts it backward). - It adds the years the given years and months to both begin and end. - It effectively calls $(D add!"years"()) and then $(D add!"months"()) - on begin and end with the given number of years and months. - - Params: - years = The number of years to shift the interval by. - months = The number of months to shift the interval by. - allowOverflow = Whether the days should be allowed to overflow - on $(D begin) and $(D end), causing their month - to increment. - - Throws: - $(LREF DateTimeException) if this interval is empty or if the - resulting interval would be invalid. - - Example: --------------------- -auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); -auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); - -interval1.shift(2); -assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1))); - -interval2.shift(-2); -assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1))); --------------------- - +/ - void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = Yes.allowDayOverflow) - if (isIntegral!T) - { - _enforceNotEmpty(); - - auto begin = _begin; - auto end = _end; - - begin.add!"years"(years, allowOverflow); - begin.add!"months"(months, allowOverflow); - end.add!"years"(years, allowOverflow); - end.add!"months"(months, allowOverflow); - - enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval.")); - - _begin = begin; - _end = end; - } - } - - - /++ - Expands the interval forwards and/or backwards in time. Effectively, - it does $(D begin -= duration) and/or $(D end += duration). Whether - it expands forwards and/or backwards in time is determined by - $(D_PARAM dir). - - Params: - duration = The duration to expand the interval by. - dir = The direction in time to expand the interval. - - Throws: - $(LREF DateTimeException) this interval is empty or if the resulting - interval would be invalid. - - Example: --------------------- -auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); -auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); - -interval1.expand(2); -assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); - -interval2.expand(-2); -assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); --------------------- - +/ - void expand(D)(D duration, Direction dir = Direction.both) pure - if (__traits(compiles, begin + duration)) - { - _enforceNotEmpty(); - - switch (dir) - { - case Direction.both: - { - auto begin = _begin - duration; - auto end = _end + duration; - - if (!_valid(begin, end)) - throw new DateTimeException("Argument would result in an invalid Interval."); - - _begin = begin; - _end = end; - - return; - } - case Direction.fwd: - { - auto end = _end + duration; - - if (!_valid(_begin, end)) - throw new DateTimeException("Argument would result in an invalid Interval."); - _end = end; - - return; - } - case Direction.bwd: - { - auto begin = _begin - duration; - - if (!_valid(begin, _end)) - throw new DateTimeException("Argument would result in an invalid Interval."); - _begin = begin; - - return; - } - default: - assert(0, "Invalid Direction."); - } - } - - static if (__traits(compiles, begin.add!"months"(1)) && - __traits(compiles, begin.add!"years"(1))) - { - /++ - Expands the interval forwards and/or backwards in time. Effectively, - it subtracts the given number of months/years from $(D begin) and - adds them to $(D end). Whether it expands forwards and/or backwards - in time is determined by $(D_PARAM dir). - - Params: - years = The number of years to expand the interval by. - months = The number of months to expand the interval by. - allowOverflow = Whether the days should be allowed to overflow - on $(D begin) and $(D end), causing their month - to increment. - dir = The direction in time to expand the interval. - - Throws: - $(LREF DateTimeException) if this interval is empty or if the - resulting interval would be invalid. - - Example: --------------------- -auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); -auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); - -interval1.expand(2); -assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); - -interval2.expand(-2); -assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); --------------------- - +/ - void expand(T)( - T years, T months = 0, AllowDayOverflow allowOverflow = Yes.allowDayOverflow, - Direction dir = Direction.both) if (isIntegral!T) - { - _enforceNotEmpty(); - - switch (dir) - { - case Direction.both: - { - auto begin = _begin; - auto end = _end; - - begin.add!"years"(-years, allowOverflow); - begin.add!"months"(-months, allowOverflow); - end.add!"years"(years, allowOverflow); - end.add!"months"(months, allowOverflow); - - enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval.")); - _begin = begin; - _end = end; - - return; - } - case Direction.fwd: - { - auto end = _end; - - end.add!"years"(years, allowOverflow); - end.add!"months"(months, allowOverflow); - - enforce( - _valid(_begin, end), - new DateTimeException("Argument would result in an invalid Interval.") - ); - _end = end; - - return; - } - case Direction.bwd: - { - auto begin = _begin; - - begin.add!"years"(-years, allowOverflow); - begin.add!"months"(-months, allowOverflow); - - enforce( - _valid(begin, _end), - new DateTimeException("Argument would result in an invalid Interval.") - ); - _begin = begin; - - return; - } - default: - assert(0, "Invalid Direction."); - } - } - } - - - /++ - Returns a range which iterates forward over the interval, starting - at $(D begin), using $(D_PARAM func) to generate each successive time - point. - - The range's $(D front) is the interval's $(D begin). $(D_PARAM func) is - used to generate the next $(D front) when $(D popFront) is called. If - $(D_PARAM popFirst) is $(D Yes.popFirst), then $(D popFront) is called - before the range is returned (so that $(D front) is a time point which - $(D_PARAM func) would generate). - - If $(D_PARAM func) ever generates a time point less than or equal to the - current $(D front) of the range, then a $(LREF DateTimeException) will be - thrown. The range will be empty and iteration complete when - $(D_PARAM func) generates a time point equal to or beyond the $(D end) - of the interval. - - There are helper functions in this module which generate common - delegates to pass to $(D fwdRange). Their documentation starts with - "Range-generating function," making them easily searchable. - - Params: - func = The function used to generate the time points of the - range over the interval. - popFirst = Whether $(D popFront) should be called on the range - before returning it. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Warning: - $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) - would be a function pointer to a pure function, but forcing - $(D_PARAM func) to be pure is far too restrictive to be useful, and - in order to have the ease of use of having functions which generate - functions to pass to $(D fwdRange), $(D_PARAM func) must be a - delegate. - - If $(D_PARAM func) retains state which changes as it is called, then - some algorithms will not work correctly, because the range's - $(D save) will have failed to have really saved the range's state. - To avoid such bugs, don't pass a delegate which is - not logically pure to $(D fwdRange). If $(D_PARAM func) is given the - same time point with two different calls, it must return the same - result both times. - - Of course, none of the functions in this module have this problem, - so it's only relevant if when creating a custom delegate. - - Example: --------------------- -auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); -auto func = delegate (in Date date) //For iterating over even-numbered days. - { - if ((date.day & 1) == 0) - return date + dur!"days"(2); - - return date + dur!"days"(1); - }; -auto range = interval.fwdRange(func); - - //An odd day. Using Yes.popFirst would have made this Date(2010, 9, 2). -assert(range.front == Date(2010, 9, 1)); - -range.popFront(); -assert(range.front == Date(2010, 9, 2)); - -range.popFront(); -assert(range.front == Date(2010, 9, 4)); - -range.popFront(); -assert(range.front == Date(2010, 9, 6)); - -range.popFront(); -assert(range.front == Date(2010, 9, 8)); - -range.popFront(); -assert(range.empty); --------------------- - +/ - IntervalRange!(TP, Direction.fwd) fwdRange(TP delegate(in TP) func, PopFirst popFirst = No.popFirst) const - { - _enforceNotEmpty(); - - auto range = IntervalRange!(TP, Direction.fwd)(this, func); - - if (popFirst == Yes.popFirst) - range.popFront(); - - return range; - } - - - /++ - Returns a range which iterates backwards over the interval, starting - at $(D end), using $(D_PARAM func) to generate each successive time - point. - - The range's $(D front) is the interval's $(D end). $(D_PARAM func) is - used to generate the next $(D front) when $(D popFront) is called. If - $(D_PARAM popFirst) is $(D Yes.popFirst), then $(D popFront) is called - before the range is returned (so that $(D front) is a time point which - $(D_PARAM func) would generate). - - If $(D_PARAM func) ever generates a time point greater than or equal to - the current $(D front) of the range, then a $(LREF DateTimeException) will - be thrown. The range will be empty and iteration complete when - $(D_PARAM func) generates a time point equal to or less than the - $(D begin) of the interval. - - There are helper functions in this module which generate common - delegates to pass to $(D bwdRange). Their documentation starts with - "Range-generating function," making them easily searchable. - - Params: - func = The function used to generate the time points of the - range over the interval. - popFirst = Whether $(D popFront) should be called on the range - before returning it. - - Throws: - $(LREF DateTimeException) if this interval is empty. - - Warning: - $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) - would be a function pointer to a pure function, but forcing - $(D_PARAM func) to be pure is far too restrictive to be useful, and - in order to have the ease of use of having functions which generate - functions to pass to $(D fwdRange), $(D_PARAM func) must be a - delegate. - - If $(D_PARAM func) retains state which changes as it is called, then - some algorithms will not work correctly, because the range's - $(D save) will have failed to have really saved the range's state. - To avoid such bugs, don't pass a delegate which is - not logically pure to $(D fwdRange). If $(D_PARAM func) is given the - same time point with two different calls, it must return the same - result both times. - - Of course, none of the functions in this module have this problem, - so it's only relevant for custom delegates. - - Example: --------------------- -auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); -auto func = delegate (in Date date) //For iterating over even-numbered days. - { - if ((date.day & 1) == 0) - return date - dur!"days"(2); - - return date - dur!"days"(1); - }; -auto range = interval.bwdRange(func); - -//An odd day. Using Yes.popFirst would have made this Date(2010, 9, 8). -assert(range.front == Date(2010, 9, 9)); - -range.popFront(); -assert(range.front == Date(2010, 9, 8)); - -range.popFront(); -assert(range.front == Date(2010, 9, 6)); - -range.popFront(); -assert(range.front == Date(2010, 9, 4)); - -range.popFront(); -assert(range.front == Date(2010, 9, 2)); - -range.popFront(); -assert(range.empty); --------------------- - +/ - IntervalRange!(TP, Direction.bwd) bwdRange(TP delegate(in TP) func, PopFirst popFirst = No.popFirst) const - { - _enforceNotEmpty(); - - auto range = IntervalRange!(TP, Direction.bwd)(this, func); - - if (popFirst == Yes.popFirst) - range.popFront(); - - return range; - } - - - /+ - Converts this interval to a string. - +/ - //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't - //have versions of toString() with extra modifiers, so we define one version - //with modifiers and one without. - string toString() - { - return _toStringImpl(); - } - - - /++ - Converts this interval to a string. - +/ - //Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't - //have versions of toString() with extra modifiers, so we define one version - //with modifiers and one without. - string toString() const nothrow - { - return _toStringImpl(); - } - - -private: - - /+ - Since we have two versions of toString, we have _toStringImpl - so that they can share implementations. - +/ - string _toStringImpl() const nothrow - { - import std.format : format; - try - return format("[%s - %s)", _begin, _end); - catch (Exception e) - assert(0, "format() threw."); - } - - - /+ - Throws: - $(LREF DateTimeException) if this interval is empty. - +/ - void _enforceNotEmpty(size_t line = __LINE__) const pure - { - if (empty) - throw new DateTimeException("Invalid operation for an empty Interval.", __FILE__, line); - } - - - /+ - Whether the given values form a valid time interval. - - Params: - begin = The starting point of the interval. - end = The end point of the interval. - +/ - static bool _valid(in TP begin, in TP end) pure nothrow - { - return begin <= end; - } - - - pure invariant() - { - assert(_valid(_begin, _end), "Invariant Failure: begin is not before or equal to end."); - } - - - TP _begin; - TP _end; -} - -//Test Interval's constructors. -@safe unittest -{ - assertThrown!DateTimeException(Interval!Date(Date(2010, 1, 1), Date(1, 1, 1))); - - Interval!Date(Date.init, Date.init); - Interval!TimeOfDay(TimeOfDay.init, TimeOfDay.init); - Interval!DateTime(DateTime.init, DateTime.init); - Interval!SysTime(SysTime(0), SysTime(0)); - - Interval!DateTime(DateTime.init, dur!"days"(7)); - - //Verify Examples. - Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); - assert( - Interval!Date(Date(1996, 1, 2), dur!"weeks"(3)) == Interval!Date( - Date(1996, 1, 2), Date(1996, 1, 23)) - ); - assert( - Interval!Date(Date(1996, 1, 2), dur!"days"(3)) == Interval!Date( - Date(1996, 1, 2), Date(1996, 1, 5)) - ); - assert( - Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"hours"(3)) == Interval!DateTime( - DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 15, 0, 0)) - ); - assert( - Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"minutes"(3)) == Interval!DateTime( - DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 3, 0)) - ); - assert( - Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"seconds"(3)) == Interval!DateTime( - DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3)) - ); - assert( - Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"msecs"(3000)) == Interval!DateTime( - DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3)) - ); -} - -//Test Interval's begin. -@safe unittest -{ - assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).begin == Date(1, 1, 1)); - assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).begin == Date(2010, 1, 1)); - assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).begin == Date(1997, 12, 31)); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - assert(cInterval.begin == Date(2010, 7, 4)); - assert(iInterval.begin == Date(2010, 7, 4)); - - //Verify Examples. - assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == Date(1996, 1, 2)); -} - -//Test Interval's end. -@safe unittest -{ - assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1)); - assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1)); - assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).end == Date(1998, 1, 1)); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - assert(cInterval.end == Date(2012, 1, 7)); - assert(iInterval.end == Date(2012, 1, 7)); - - //Verify Examples. - assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == Date(2012, 3, 1)); -} - -//Test Interval's length. -@safe unittest -{ - assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).length == dur!"days"(0)); - assert(Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).length == dur!"days"(90)); - assert(Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).length == dur!"seconds"(42_727)); - assert(Interval!DateTime( - DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).length == dur!"seconds"(129_127)); - assert(Interval!SysTime( - SysTime(DateTime(2010, 1, 1, 0, 30, 0)), - SysTime(DateTime(2010, 1, 2, 12, 22, 7)) - ).length == dur!"seconds"(129_127)); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - assert(cInterval.length != Duration.zero); - assert(iInterval.length != Duration.zero); - - //Verify Examples. - assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == dur!"days"(5903)); -} - -//Test Interval's empty. -@safe unittest -{ - assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).empty); - assert(!Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).empty); - assert(!Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).empty); - assert(!Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).empty); - assert(!Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)), SysTime(DateTime(2010, 1, 2, 12, 22, 7))).empty); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - assert(!cInterval.empty); - assert(!iInterval.empty); - - //Verify Examples. - assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty); - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty); -} - -//Test Interval's contains(time point). -@safe unittest -{ - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(Date(2010, 7, 4))); - - assert(!interval.contains(Date(2009, 7, 4))); - assert(!interval.contains(Date(2010, 7, 3))); - assert(interval.contains(Date(2010, 7, 4))); - assert(interval.contains(Date(2010, 7, 5))); - assert(interval.contains(Date(2011, 7, 1))); - assert(interval.contains(Date(2012, 1, 6))); - assert(!interval.contains(Date(2012, 1, 7))); - assert(!interval.contains(Date(2012, 1, 8))); - assert(!interval.contains(Date(2013, 1, 7))); - - const cdate = Date(2010, 7, 6); - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - assert(interval.contains(cdate)); - assert(cInterval.contains(cdate)); - assert(iInterval.contains(cdate)); - - //Verify Examples. - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(1994, 12, 24))); - assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2000, 1, 5))); - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2012, 3, 1))); -} - -//Test Interval's contains(Interval). -@safe unittest -{ - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - assertThrown!DateTimeException(interval.contains(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(interval)); - assertThrown!DateTimeException(Interval!Date( - Date(2010, 7, 4), - dur!"days"(0) - ).contains(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - - assert(interval.contains(interval)); - assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); - assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); - assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); - assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); - assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); - assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); - assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); - assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); - assert(interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); - assert(!interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); - assert(!interval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); - assert(!interval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); - - assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).contains(interval)); - assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).contains(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).contains(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).contains(interval)); - assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).contains(interval)); - assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).contains(interval)); - assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).contains(interval)); - assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).contains(interval)); - assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).contains(interval)); - assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).contains(interval)); - assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).contains(interval)); - assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).contains(interval)); - - assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 3)))); - assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 4)))); - assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 5)))); - assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 6)))); - assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 7)))); - assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 8)))); - - assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 3)))); - assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 4)))); - assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 5)))); - assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 6)))); - assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 7)))); - assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 8)))); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - assert(interval.contains(interval)); - assert(interval.contains(cInterval)); - assert(interval.contains(iInterval)); - assert(!interval.contains(posInfInterval)); - assert(!interval.contains(cPosInfInterval)); - assert(!interval.contains(iPosInfInterval)); - assert(!interval.contains(negInfInterval)); - assert(!interval.contains(cNegInfInterval)); - assert(!interval.contains(iNegInfInterval)); - assert(cInterval.contains(interval)); - assert(cInterval.contains(cInterval)); - assert(cInterval.contains(iInterval)); - assert(!cInterval.contains(posInfInterval)); - assert(!cInterval.contains(cPosInfInterval)); - assert(!cInterval.contains(iPosInfInterval)); - assert(!cInterval.contains(negInfInterval)); - assert(!cInterval.contains(cNegInfInterval)); - assert(!cInterval.contains(iNegInfInterval)); - assert(iInterval.contains(interval)); - assert(iInterval.contains(cInterval)); - assert(iInterval.contains(iInterval)); - assert(!iInterval.contains(posInfInterval)); - assert(!iInterval.contains(cPosInfInterval)); - assert(!iInterval.contains(iPosInfInterval)); - assert(!iInterval.contains(negInfInterval)); - assert(!iInterval.contains(cNegInfInterval)); - assert(!iInterval.contains(iNegInfInterval)); - - //Verify Examples. - assert(!Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); - assert(!Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); - - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4)))); - - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4)))); -} - -//Test Interval's isBefore(time point). -@safe unittest -{ - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(Date(2010, 7, 4))); - - assert(!interval.isBefore(Date(2009, 7, 3))); - assert(!interval.isBefore(Date(2010, 7, 3))); - assert(!interval.isBefore(Date(2010, 7, 4))); - assert(!interval.isBefore(Date(2010, 7, 5))); - assert(!interval.isBefore(Date(2011, 7, 1))); - assert(!interval.isBefore(Date(2012, 1, 6))); - assert(interval.isBefore(Date(2012, 1, 7))); - assert(interval.isBefore(Date(2012, 1, 8))); - assert(interval.isBefore(Date(2013, 1, 7))); - - const cdate = Date(2010, 7, 6); - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - assert(!interval.isBefore(cdate)); - assert(!cInterval.isBefore(cdate)); - assert(!iInterval.isBefore(cdate)); - - //Verify Examples. - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(1994, 12, 24))); - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2000, 1, 5))); - assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2012, 3, 1))); -} - -//Test Interval's isBefore(Interval). -@safe unittest -{ - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - assertThrown!DateTimeException(interval.isBefore(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(interval)); - assertThrown!DateTimeException(Interval!Date( - Date(2010, 7, 4), - dur!"days"(0) - ).isBefore(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - - assert(!interval.isBefore(interval)); - assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); - assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); - assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); - assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); - assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); - assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); - assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); - assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); - assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); - assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); - assert(interval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); - assert(interval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); - - assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isBefore(interval)); - assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isBefore(interval)); - assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isBefore(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isBefore(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isBefore(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isBefore(interval)); - assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isBefore(interval)); - assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isBefore(interval)); - assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isBefore(interval)); - assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isBefore(interval)); - assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isBefore(interval)); - assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isBefore(interval)); - - assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 3)))); - assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 4)))); - assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 5)))); - assert(!interval.isBefore(PosInfInterval!Date(Date(2012, 1, 6)))); - assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 7)))); - assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 8)))); - - assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 3)))); - assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 4)))); - assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 5)))); - assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 6)))); - assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 7)))); - assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 8)))); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - assert(!interval.isBefore(interval)); - assert(!interval.isBefore(cInterval)); - assert(!interval.isBefore(iInterval)); - assert(!interval.isBefore(posInfInterval)); - assert(!interval.isBefore(cPosInfInterval)); - assert(!interval.isBefore(iPosInfInterval)); - assert(!interval.isBefore(negInfInterval)); - assert(!interval.isBefore(cNegInfInterval)); - assert(!interval.isBefore(iNegInfInterval)); - assert(!cInterval.isBefore(interval)); - assert(!cInterval.isBefore(cInterval)); - assert(!cInterval.isBefore(iInterval)); - assert(!cInterval.isBefore(posInfInterval)); - assert(!cInterval.isBefore(cPosInfInterval)); - assert(!cInterval.isBefore(iPosInfInterval)); - assert(!cInterval.isBefore(negInfInterval)); - assert(!cInterval.isBefore(cNegInfInterval)); - assert(!cInterval.isBefore(iNegInfInterval)); - assert(!iInterval.isBefore(interval)); - assert(!iInterval.isBefore(cInterval)); - assert(!iInterval.isBefore(iInterval)); - assert(!iInterval.isBefore(posInfInterval)); - assert(!iInterval.isBefore(cPosInfInterval)); - assert(!iInterval.isBefore(iPosInfInterval)); - assert(!iInterval.isBefore(negInfInterval)); - assert(!iInterval.isBefore(cNegInfInterval)); - assert(!iInterval.isBefore(iNegInfInterval)); - - //Verify Examples. - assert(!Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); - assert(!Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isBefore(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1)))); - - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4)))); - assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2013, 3, 7)))); - - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4)))); -} - -//Test Interval's isAfter(time point). -@safe unittest -{ - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(Date(2010, 7, 4))); - - assert(interval.isAfter(Date(2009, 7, 4))); - assert(interval.isAfter(Date(2010, 7, 3))); - assert(!interval.isAfter(Date(2010, 7, 4))); - assert(!interval.isAfter(Date(2010, 7, 5))); - assert(!interval.isAfter(Date(2011, 7, 1))); - assert(!interval.isAfter(Date(2012, 1, 6))); - assert(!interval.isAfter(Date(2012, 1, 7))); - assert(!interval.isAfter(Date(2012, 1, 8))); - assert(!interval.isAfter(Date(2013, 1, 7))); - - const cdate = Date(2010, 7, 6); - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - assert(!interval.isAfter(cdate)); - assert(!cInterval.isAfter(cdate)); - assert(!iInterval.isAfter(cdate)); - - //Verify Examples. - assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(1994, 12, 24))); - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2000, 1, 5))); - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2012, 3, 1))); -} - -//Test Interval's isAfter(Interval). -@safe unittest -{ - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - assertThrown!DateTimeException(interval.isAfter(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(interval)); - assertThrown!DateTimeException(Interval!Date( - Date(2010, 7, 4), - dur!"days"(0) - ).isAfter(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - - assert(!interval.isAfter(interval)); - assert(interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); - assert(!interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); - assert(interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); - assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); - assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); - assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); - assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); - assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); - assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); - assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); - assert(!interval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); - assert(!interval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); - - assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAfter(interval)); - assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAfter(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAfter(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAfter(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAfter(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAfter(interval)); - assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAfter(interval)); - assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAfter(interval)); - assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAfter(interval)); - assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAfter(interval)); - assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAfter(interval)); - assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAfter(interval)); - - assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 3)))); - assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 4)))); - assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 5)))); - assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 6)))); - assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 7)))); - assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 8)))); - - assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 3)))); - assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 4)))); - assert(!interval.isAfter(NegInfInterval!Date(Date(2010, 7, 5)))); - assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 6)))); - assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 7)))); - assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 8)))); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - assert(!interval.isAfter(interval)); - assert(!interval.isAfter(cInterval)); - assert(!interval.isAfter(iInterval)); - assert(!interval.isAfter(posInfInterval)); - assert(!interval.isAfter(cPosInfInterval)); - assert(!interval.isAfter(iPosInfInterval)); - assert(!interval.isAfter(negInfInterval)); - assert(!interval.isAfter(cNegInfInterval)); - assert(!interval.isAfter(iNegInfInterval)); - assert(!cInterval.isAfter(interval)); - assert(!cInterval.isAfter(cInterval)); - assert(!cInterval.isAfter(iInterval)); - assert(!cInterval.isAfter(posInfInterval)); - assert(!cInterval.isAfter(cPosInfInterval)); - assert(!cInterval.isAfter(iPosInfInterval)); - assert(!cInterval.isAfter(negInfInterval)); - assert(!cInterval.isAfter(cNegInfInterval)); - assert(!cInterval.isAfter(iNegInfInterval)); - assert(!iInterval.isAfter(interval)); - assert(!iInterval.isAfter(cInterval)); - assert(!iInterval.isAfter(iInterval)); - assert(!iInterval.isAfter(posInfInterval)); - assert(!iInterval.isAfter(cPosInfInterval)); - assert(!iInterval.isAfter(iPosInfInterval)); - assert(!iInterval.isAfter(negInfInterval)); - assert(!iInterval.isAfter(cNegInfInterval)); - assert(!iInterval.isAfter(iNegInfInterval)); - - //Verify Examples. - assert(!Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); - assert(!Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isAfter(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); - - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4)))); - - assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 1, 2)))); -} - -//Test Interval's intersects(). -@safe unittest -{ - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - assertThrown!DateTimeException(interval.intersects(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects(interval)); - assertThrown!DateTimeException(Interval!Date( - Date(2010, 7, 4), - dur!"days"(0) - ).intersects(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - - assert(interval.intersects(interval)); - assert(!interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); - assert(interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); - assert(!interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); - assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); - assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); - assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); - assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); - assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); - assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); - assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); - assert(!interval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); - assert(!interval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); - - assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersects(interval)); - assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersects(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersects(interval)); - assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersects(interval)); - assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersects(interval)); - assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersects(interval)); - assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersects(interval)); - assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersects(interval)); - assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersects(interval)); - assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersects(interval)); - assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersects(interval)); - assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersects(interval)); - - assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 3)))); - assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 4)))); - assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 5)))); - assert(interval.intersects(PosInfInterval!Date(Date(2012, 1, 6)))); - assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 7)))); - assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 8)))); - - assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 3)))); - assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 4)))); - assert(interval.intersects(NegInfInterval!Date(Date(2010, 7, 5)))); - assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 6)))); - assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 7)))); - assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 8)))); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - assert(interval.intersects(interval)); - assert(interval.intersects(cInterval)); - assert(interval.intersects(iInterval)); - assert(interval.intersects(posInfInterval)); - assert(interval.intersects(cPosInfInterval)); - assert(interval.intersects(iPosInfInterval)); - assert(interval.intersects(negInfInterval)); - assert(interval.intersects(cNegInfInterval)); - assert(interval.intersects(iNegInfInterval)); - assert(cInterval.intersects(interval)); - assert(cInterval.intersects(cInterval)); - assert(cInterval.intersects(iInterval)); - assert(cInterval.intersects(posInfInterval)); - assert(cInterval.intersects(cPosInfInterval)); - assert(cInterval.intersects(iPosInfInterval)); - assert(cInterval.intersects(negInfInterval)); - assert(cInterval.intersects(cNegInfInterval)); - assert(cInterval.intersects(iNegInfInterval)); - assert(iInterval.intersects(interval)); - assert(iInterval.intersects(cInterval)); - assert(iInterval.intersects(iInterval)); - assert(iInterval.intersects(posInfInterval)); - assert(iInterval.intersects(cPosInfInterval)); - assert(iInterval.intersects(iPosInfInterval)); - assert(iInterval.intersects(negInfInterval)); - assert(iInterval.intersects(cNegInfInterval)); - assert(iInterval.intersects(iNegInfInterval)); - - //Verify Examples. - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); - assert(!Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).intersects(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); - - assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4)))); - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1)))); - - assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 1, 2)))); - assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2000, 1, 2)))); -} - -//Test Interval's intersection(). -@safe unittest -{ - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection(interval)); - assertThrown!DateTimeException(Interval!Date( - Date(2010, 7, 4), - dur!"days"(0) - ).intersection(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - - assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); - assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); - assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); - assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); - - assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersection(interval)); - assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersection(interval)); - assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersection(interval)); - assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersection(interval)); - - assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 7)))); - assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 8)))); - - assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 3)))); - assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 4)))); - - assert(interval.intersection(interval) == interval); - assert(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == - Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); - assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == - Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); - assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == - Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); - assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == - Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); - assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == - Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); - - assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersection(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersection(interval) == - Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); - assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersection(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersection(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersection(interval) == - Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); - assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersection(interval) == - Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); - assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersection(interval) == - Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); - assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersection(interval) == - Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); - - assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == - Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); - assert(interval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == - Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); - - assert(interval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == - Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); - assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6))); - assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - assert(!interval.intersection(interval).empty); - assert(!interval.intersection(cInterval).empty); - assert(!interval.intersection(iInterval).empty); - assert(!interval.intersection(posInfInterval).empty); - assert(!interval.intersection(cPosInfInterval).empty); - assert(!interval.intersection(iPosInfInterval).empty); - assert(!interval.intersection(negInfInterval).empty); - assert(!interval.intersection(cNegInfInterval).empty); - assert(!interval.intersection(iNegInfInterval).empty); - assert(!cInterval.intersection(interval).empty); - assert(!cInterval.intersection(cInterval).empty); - assert(!cInterval.intersection(iInterval).empty); - assert(!cInterval.intersection(posInfInterval).empty); - assert(!cInterval.intersection(cPosInfInterval).empty); - assert(!cInterval.intersection(iPosInfInterval).empty); - assert(!cInterval.intersection(negInfInterval).empty); - assert(!cInterval.intersection(cNegInfInterval).empty); - assert(!cInterval.intersection(iNegInfInterval).empty); - assert(!iInterval.intersection(interval).empty); - assert(!iInterval.intersection(cInterval).empty); - assert(!iInterval.intersection(iInterval).empty); - assert(!iInterval.intersection(posInfInterval).empty); - assert(!iInterval.intersection(cPosInfInterval).empty); - assert(!iInterval.intersection(iPosInfInterval).empty); - assert(!iInterval.intersection(negInfInterval).empty); - assert(!iInterval.intersection(cNegInfInterval).empty); - assert(!iInterval.intersection(iNegInfInterval).empty); - - //Verify Examples. - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).intersection(Interval!Date( - Date(1990, 7, 6), - Date(2000, 8, 2)) - ) == Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).intersection(Interval!Date( - Date(1999, 1, 12), - Date(2011, 9, 17)) - ) == Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); - - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).intersection(PosInfInterval!Date(Date(1990, 7, 6))) == Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).intersection(PosInfInterval!Date(Date(1999, 1, 12))) == Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); - - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).intersection(NegInfInterval!Date(Date(1999, 7, 6))) == Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).intersection(NegInfInterval!Date(Date(2013, 1, 12))) == Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); -} - -//Test Interval's isAdjacent(). -@safe unittest -{ - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - static void testInterval(in Interval!Date interval1, in Interval!Date interval2) - { - interval1.isAdjacent(interval2); - } - - assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval)); - assertThrown!DateTimeException(testInterval(Interval!Date( - Date(2010, 7, 4), - dur!"days"(0) - ), Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - - assert(!interval.isAdjacent(interval)); - assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); - assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); - assert(interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); - assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); - assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); - assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); - assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); - assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); - assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); - assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); - assert(interval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); - assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); - - assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAdjacent(interval)); - assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAdjacent(interval)); - assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAdjacent(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAdjacent(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAdjacent(interval)); - assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAdjacent(interval)); - assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAdjacent(interval)); - assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAdjacent(interval)); - assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAdjacent(interval)); - assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAdjacent(interval)); - assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAdjacent(interval)); - assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAdjacent(interval)); - - assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3)))); - assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4)))); - assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5)))); - assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6)))); - assert(interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7)))); - assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8)))); - - assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3)))); - assert(interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4)))); - assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5)))); - assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6)))); - assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7)))); - assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8)))); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - assert(!interval.isAdjacent(interval)); - assert(!interval.isAdjacent(cInterval)); - assert(!interval.isAdjacent(iInterval)); - assert(!interval.isAdjacent(posInfInterval)); - assert(!interval.isAdjacent(cPosInfInterval)); - assert(!interval.isAdjacent(iPosInfInterval)); - assert(!interval.isAdjacent(negInfInterval)); - assert(!interval.isAdjacent(cNegInfInterval)); - assert(!interval.isAdjacent(iNegInfInterval)); - assert(!cInterval.isAdjacent(interval)); - assert(!cInterval.isAdjacent(cInterval)); - assert(!cInterval.isAdjacent(iInterval)); - assert(!cInterval.isAdjacent(posInfInterval)); - assert(!cInterval.isAdjacent(cPosInfInterval)); - assert(!cInterval.isAdjacent(iPosInfInterval)); - assert(!cInterval.isAdjacent(negInfInterval)); - assert(!cInterval.isAdjacent(cNegInfInterval)); - assert(!cInterval.isAdjacent(iNegInfInterval)); - assert(!iInterval.isAdjacent(interval)); - assert(!iInterval.isAdjacent(cInterval)); - assert(!iInterval.isAdjacent(iInterval)); - assert(!iInterval.isAdjacent(posInfInterval)); - assert(!iInterval.isAdjacent(cPosInfInterval)); - assert(!iInterval.isAdjacent(iPosInfInterval)); - assert(!iInterval.isAdjacent(negInfInterval)); - assert(!iInterval.isAdjacent(cNegInfInterval)); - assert(!iInterval.isAdjacent(iNegInfInterval)); - - //Verify Examples. - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isAdjacent(Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2)))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isAdjacent(Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17)))); - assert(!Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isAdjacent(Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1)))); - - assert(!Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4)))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1)))); - - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2)))); - assert(!Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).isAdjacent(NegInfInterval!Date(Date(2000, 1, 2)))); -} - -//Test Interval's merge(). -@safe unittest -{ - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - static void testInterval(I)(in Interval!Date interval1, in I interval2) - { - interval1.merge(interval2); - } - - assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval)); - assertThrown!DateTimeException(testInterval(Interval!Date( - Date(2010, 7, 4), - dur!"days"(0) - ), Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - - assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); - assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); - - assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)), interval)); - assertThrown!DateTimeException(testInterval(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)), interval)); - - assertThrown!DateTimeException(testInterval(interval, PosInfInterval!Date(Date(2012, 1, 8)))); - - assertThrown!DateTimeException(testInterval(interval, NegInfInterval!Date(Date(2010, 7, 3)))); - - assert(interval.merge(interval) == interval); - assert(interval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == - Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); - assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); - assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); - assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); - assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); - assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); - assert(interval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); - - assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).merge(interval) == - Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); - assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).merge(interval) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); - assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).merge(interval) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); - assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).merge(interval) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); - assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).merge(interval) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); - assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).merge(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).merge(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).merge(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).merge(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); - assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).merge(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); - - assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 3))) == - PosInfInterval!Date(Date(2010, 7, 3))); - assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 4))) == - PosInfInterval!Date(Date(2010, 7, 4))); - assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 5))) == - PosInfInterval!Date(Date(2010, 7, 4))); - assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 6))) == - PosInfInterval!Date(Date(2010, 7, 4))); - assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 7))) == - PosInfInterval!Date(Date(2010, 7, 4))); - - assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 4))) == - NegInfInterval!Date(Date(2012, 1, 7))); - assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 5))) == - NegInfInterval!Date(Date(2012, 1, 7))); - assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 6))) == - NegInfInterval!Date(Date(2012, 1, 7))); - assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 7))) == - NegInfInterval!Date(Date(2012, 1, 7))); - assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 8))) == - NegInfInterval!Date(Date(2012, 1, 8))); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - assert(!interval.merge(interval).empty); - assert(!interval.merge(cInterval).empty); - assert(!interval.merge(iInterval).empty); - assert(!interval.merge(posInfInterval).empty); - assert(!interval.merge(cPosInfInterval).empty); - assert(!interval.merge(iPosInfInterval).empty); - assert(!interval.merge(negInfInterval).empty); - assert(!interval.merge(cNegInfInterval).empty); - assert(!interval.merge(iNegInfInterval).empty); - assert(!cInterval.merge(interval).empty); - assert(!cInterval.merge(cInterval).empty); - assert(!cInterval.merge(iInterval).empty); - assert(!cInterval.merge(posInfInterval).empty); - assert(!cInterval.merge(cPosInfInterval).empty); - assert(!cInterval.merge(iPosInfInterval).empty); - assert(!cInterval.merge(negInfInterval).empty); - assert(!cInterval.merge(cNegInfInterval).empty); - assert(!cInterval.merge(iNegInfInterval).empty); - assert(!iInterval.merge(interval).empty); - assert(!iInterval.merge(cInterval).empty); - assert(!iInterval.merge(iInterval).empty); - assert(!iInterval.merge(posInfInterval).empty); - assert(!iInterval.merge(cPosInfInterval).empty); - assert(!iInterval.merge(iPosInfInterval).empty); - assert(!iInterval.merge(negInfInterval).empty); - assert(!iInterval.merge(cNegInfInterval).empty); - assert(!iInterval.merge(iNegInfInterval).empty); - - //Verify Examples. - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).merge(Interval!Date( - Date(1990, 7, 6), - Date(2000, 8, 2)) - ) == Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).merge(Interval!Date( - Date(2012, 3, 1), - Date(2013, 5, 7)) - ) == Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); - - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).merge(PosInfInterval!Date( - Date(1990, 7, 6)) - ) == PosInfInterval!Date(Date(1990, 7 , 6))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).merge(PosInfInterval!Date( - Date(2012, 3, 1)) - ) == PosInfInterval!Date(Date(1996, 1 , 2))); - - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).merge(NegInfInterval!Date( - Date(1996, 1, 2)) - ) == NegInfInterval!Date(Date(2012, 3 , 1))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).merge(NegInfInterval!Date( - Date(2013, 1, 12)) - ) == NegInfInterval!Date(Date(2013, 1 , 12))); -} - -//Test Interval's span(). -@safe unittest -{ - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - static void testInterval(in Interval!Date interval1, in Interval!Date interval2) - { - interval1.span(interval2); - } - - assertThrown!DateTimeException(testInterval(interval, Interval!Date( - Date(2010, 7, 4), - dur!"days"(0)) - )); - assertThrown!DateTimeException(testInterval(Interval!Date( - Date(2010, 7, 4), - dur!"days"(0) - ),interval)); - assertThrown!DateTimeException(testInterval(Interval!Date( - Date(2010, 7, 4), - dur!"days"(0) - ), Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - - assert(interval.span(interval) == interval); - assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == - Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); - assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == - Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); - assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); - assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); - assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); - assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); - assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); - assert(interval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); - assert(interval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9))); - - assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).span(interval) == - Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); - assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).span(interval) == - Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); - assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).span(interval) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); - assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).span(interval) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); - assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).span(interval) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); - assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).span(interval) == - Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); - assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).span(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).span(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).span(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); - assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).span(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); - assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).span(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); - assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).span(interval) == - Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9))); - - assert(interval.span(PosInfInterval!Date(Date(2010, 7, 3))) == - PosInfInterval!Date(Date(2010, 7, 3))); - assert(interval.span(PosInfInterval!Date(Date(2010, 7, 4))) == - PosInfInterval!Date(Date(2010, 7, 4))); - assert(interval.span(PosInfInterval!Date(Date(2010, 7, 5))) == - PosInfInterval!Date(Date(2010, 7, 4))); - assert(interval.span(PosInfInterval!Date(Date(2012, 1, 6))) == - PosInfInterval!Date(Date(2010, 7, 4))); - assert(interval.span(PosInfInterval!Date(Date(2012, 1, 7))) == - PosInfInterval!Date(Date(2010, 7, 4))); - assert(interval.span(PosInfInterval!Date(Date(2012, 1, 8))) == - PosInfInterval!Date(Date(2010, 7, 4))); - - assert(interval.span(NegInfInterval!Date(Date(2010, 7, 3))) == - NegInfInterval!Date(Date(2012, 1, 7))); - assert(interval.span(NegInfInterval!Date(Date(2010, 7, 4))) == - NegInfInterval!Date(Date(2012, 1, 7))); - assert(interval.span(NegInfInterval!Date(Date(2010, 7, 5))) == - NegInfInterval!Date(Date(2012, 1, 7))); - assert(interval.span(NegInfInterval!Date(Date(2012, 1, 6))) == - NegInfInterval!Date(Date(2012, 1, 7))); - assert(interval.span(NegInfInterval!Date(Date(2012, 1, 7))) == - NegInfInterval!Date(Date(2012, 1, 7))); - assert(interval.span(NegInfInterval!Date(Date(2012, 1, 8))) == - NegInfInterval!Date(Date(2012, 1, 8))); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); - auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); - assert(!interval.span(interval).empty); - assert(!interval.span(cInterval).empty); - assert(!interval.span(iInterval).empty); - assert(!interval.span(posInfInterval).empty); - assert(!interval.span(cPosInfInterval).empty); - assert(!interval.span(iPosInfInterval).empty); - assert(!interval.span(negInfInterval).empty); - assert(!interval.span(cNegInfInterval).empty); - assert(!interval.span(iNegInfInterval).empty); - assert(!cInterval.span(interval).empty); - assert(!cInterval.span(cInterval).empty); - assert(!cInterval.span(iInterval).empty); - assert(!cInterval.span(posInfInterval).empty); - assert(!cInterval.span(cPosInfInterval).empty); - assert(!cInterval.span(iPosInfInterval).empty); - assert(!cInterval.span(negInfInterval).empty); - assert(!cInterval.span(cNegInfInterval).empty); - assert(!cInterval.span(iNegInfInterval).empty); - assert(!iInterval.span(interval).empty); - assert(!iInterval.span(cInterval).empty); - assert(!iInterval.span(iInterval).empty); - assert(!iInterval.span(posInfInterval).empty); - assert(!iInterval.span(cPosInfInterval).empty); - assert(!iInterval.span(iPosInfInterval).empty); - assert(!iInterval.span(negInfInterval).empty); - assert(!iInterval.span(cNegInfInterval).empty); - assert(!iInterval.span(iNegInfInterval).empty); - - //Verify Examples. - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).span(Interval!Date( - Date(1990, 7, 6), - Date(1991, 1, 8)) - ) == Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).span(Interval!Date( - Date(2012, 3, 1), - Date(2013, 5, 7)) - ) == Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); - - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).span(PosInfInterval!Date( - Date(1990, 7, 6)) - ) == PosInfInterval!Date(Date(1990, 7 , 6))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).span(PosInfInterval!Date( - Date(2050, 1, 1)) - ) == PosInfInterval!Date(Date(1996, 1 , 2))); - - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).span(NegInfInterval!Date( - Date(1602, 5, 21)) - ) == NegInfInterval!Date(Date(2012, 3 , 1))); - assert(Interval!Date( - Date(1996, 1, 2), - Date(2012, 3, 1) - ).span(NegInfInterval!Date( - Date(2013, 1, 12)) - ) == NegInfInterval!Date(Date(2013, 1 , 12))); -} - -//Test Interval's shift(duration). -@safe unittest -{ - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - static void testIntervalFail(Interval!Date interval, in Duration duration) - { - interval.shift(duration); - } - - assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1))); - - static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__) - { - interval.shift(duration); - assert(interval == expected); - } - - testInterval(interval, dur!"days"(22), Interval!Date(Date(2010, 7, 26), Date(2012, 1, 29))); - testInterval(interval, dur!"days"(-22), Interval!Date(Date(2010, 6, 12), Date(2011, 12, 16))); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - static assert(!__traits(compiles, cInterval.shift(dur!"days"(5)))); - static assert(!__traits(compiles, iInterval.shift(dur!"days"(5)))); - - //Verify Examples. - auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); - auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); - - interval1.shift(dur!"days"(50)); - assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25))); - - interval2.shift(dur!"days"(-50)); - assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15))); -} - -//Test Interval's shift(int, int, AllowDayOverflow). -@safe unittest -{ - { - auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - - static void testIntervalFail(Interval!Date interval, int years, int months) - { - interval.shift(years, months); - } - - assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0)); - - static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, - in I expected, size_t line = __LINE__) - { - interval.shift(years, months, allow); - assert(interval == expected); - } - - testInterval(interval, 5, 0, Yes.allowDayOverflow, Interval!Date(Date(2015, 7, 4), Date(2017, 1, 7))); - testInterval(interval, -5, 0, Yes.allowDayOverflow, Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7))); - - auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31)); - - testInterval(interval2, 1, 1, Yes.allowDayOverflow, Interval!Date(Date(2001, 3, 1), Date(2011, 7, 1))); - testInterval(interval2, 1, -1, Yes.allowDayOverflow, Interval!Date(Date(2000, 12, 29), Date(2011, 5, 1))); - testInterval(interval2, -1, -1, Yes.allowDayOverflow, Interval!Date(Date(1998, 12, 29), Date(2009, 5, 1))); - testInterval(interval2, -1, 1, Yes.allowDayOverflow, Interval!Date(Date(1999, 3, 1), Date(2009, 7, 1))); - - testInterval(interval2, 1, 1, No.allowDayOverflow, Interval!Date(Date(2001, 2, 28), Date(2011, 6, 30))); - testInterval(interval2, 1, -1, No.allowDayOverflow, Interval!Date(Date(2000, 12, 29), Date(2011, 4, 30))); - testInterval(interval2, -1, -1, No.allowDayOverflow, Interval!Date(Date(1998, 12, 29), Date(2009, 4, 30))); - testInterval(interval2, -1, 1, No.allowDayOverflow, Interval!Date(Date(1999, 2, 28), Date(2009, 6, 30))); - } - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - static assert(!__traits(compiles, cInterval.shift(5))); - static assert(!__traits(compiles, iInterval.shift(5))); - - //Verify Examples. - auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); - auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); - - interval1.shift(2); - assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1))); - - interval2.shift(-2); - assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1))); -} - -//Test Interval's expand(Duration). -@safe unittest -{ - auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7)); - - static void testIntervalFail(I)(I interval, in Duration duration) - { - interval.expand(duration); - } - - assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1))); - assertThrown!DateTimeException(testIntervalFail(Interval!Date( - Date(2010, 7, 4), - Date(2010, 7, 5) - ), dur!"days"(-5))); - - static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__) - { - interval.expand(duration); - assert(interval == expected); - } - - testInterval(interval, dur!"days"(22), Interval!Date(Date(2000, 6, 12), Date(2012, 1, 29))); - testInterval(interval, dur!"days"(-22), Interval!Date(Date(2000, 7, 26), Date(2011, 12, 16))); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - static assert(!__traits(compiles, cInterval.expand(dur!"days"(5)))); - static assert(!__traits(compiles, iInterval.expand(dur!"days"(5)))); - - //Verify Examples. - auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); - auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); - - interval1.expand(dur!"days"(2)); - assert(interval1 == Interval!Date(Date(1995, 12, 31), Date(2012, 3, 3))); - - interval2.expand(dur!"days"(-2)); - assert(interval2 == Interval!Date(Date(1996, 1, 4), Date(2012, 2, 28))); -} - -//Test Interval's expand(int, int, AllowDayOverflow, Direction) -@safe unittest -{ - { - auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7)); - - static void testIntervalFail(Interval!Date interval, int years, int months) - { - interval.expand(years, months); - } - - assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0)); - assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)), -5, 0)); - - static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, - Direction dir, in I expected, size_t line = __LINE__) - { - interval.expand(years, months, allow, dir); - assert(interval == expected); - } - - testInterval(interval, 5, 0, Yes.allowDayOverflow, Direction.both, - Interval!Date(Date(1995, 7, 4), Date(2017, 1, 7))); - testInterval(interval, -5, 0, Yes.allowDayOverflow, Direction.both, - Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7))); - - testInterval(interval, 5, 0, Yes.allowDayOverflow, Direction.fwd, - Interval!Date(Date(2000, 7, 4), Date(2017, 1, 7))); - testInterval(interval, -5, 0, Yes.allowDayOverflow, Direction.fwd, - Interval!Date(Date(2000, 7, 4), Date(2007, 1, 7))); - - testInterval(interval, 5, 0, Yes.allowDayOverflow, Direction.bwd, - Interval!Date(Date(1995, 7, 4), Date(2012, 1, 7))); - testInterval(interval, -5, 0, Yes.allowDayOverflow, Direction.bwd, - Interval!Date(Date(2005, 7, 4), Date(2012, 1, 7))); - - auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31)); - - testInterval(interval2, 1, 1, Yes.allowDayOverflow, Direction.both, - Interval!Date(Date(1998, 12, 29), Date(2011, 7, 1))); - testInterval(interval2, 1, -1, Yes.allowDayOverflow, Direction.both, - Interval!Date(Date(1999, 3, 1), Date(2011, 5, 1))); - testInterval(interval2, -1, -1, Yes.allowDayOverflow, Direction.both, - Interval!Date(Date(2001, 3, 1), Date(2009, 5, 1))); - testInterval(interval2, -1, 1, Yes.allowDayOverflow, Direction.both, - Interval!Date(Date(2000, 12, 29), Date(2009, 7, 1))); - - testInterval(interval2, 1, 1, No.allowDayOverflow, Direction.both, - Interval!Date(Date(1998, 12, 29), Date(2011, 6, 30))); - testInterval(interval2, 1, -1, No.allowDayOverflow, Direction.both, - Interval!Date(Date(1999, 2, 28), Date(2011, 4, 30))); - testInterval(interval2, -1, -1, No.allowDayOverflow, Direction.both, - Interval!Date(Date(2001, 2, 28), Date(2009, 4, 30))); - testInterval(interval2, -1, 1, No.allowDayOverflow, Direction.both, - Interval!Date(Date(2000, 12, 29), Date(2009, 6, 30))); - - testInterval(interval2, 1, 1, Yes.allowDayOverflow, Direction.fwd, - Interval!Date(Date(2000, 1, 29), Date(2011, 7, 1))); - testInterval(interval2, 1, -1, Yes.allowDayOverflow, Direction.fwd, - Interval!Date(Date(2000, 1, 29), Date(2011, 5, 1))); - testInterval(interval2, -1, -1, Yes.allowDayOverflow, Direction.fwd, - Interval!Date(Date(2000, 1, 29), Date(2009, 5, 1))); - testInterval(interval2, -1, 1, Yes.allowDayOverflow, Direction.fwd, - Interval!Date(Date(2000, 1, 29), Date(2009, 7, 1))); - - testInterval(interval2, 1, 1, No.allowDayOverflow, Direction.fwd, - Interval!Date(Date(2000, 1, 29), Date(2011, 6, 30))); - testInterval(interval2, 1, -1, No.allowDayOverflow, Direction.fwd, - Interval!Date(Date(2000, 1, 29), Date(2011, 4, 30))); - testInterval(interval2, -1, -1, No.allowDayOverflow, Direction.fwd, - Interval!Date(Date(2000, 1, 29), Date(2009, 4, 30))); - testInterval(interval2, -1, 1, No.allowDayOverflow, Direction.fwd, - Interval!Date(Date(2000, 1, 29), Date(2009, 6, 30))); - - testInterval(interval2, 1, 1, Yes.allowDayOverflow, Direction.bwd, - Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31))); - testInterval(interval2, 1, -1, Yes.allowDayOverflow, Direction.bwd, - Interval!Date(Date(1999, 3, 1), Date(2010, 5, 31))); - testInterval(interval2, -1, -1, Yes.allowDayOverflow, Direction.bwd, - Interval!Date(Date(2001, 3, 1), Date(2010, 5, 31))); - testInterval(interval2, -1, 1, Yes.allowDayOverflow, Direction.bwd, - Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31))); - - testInterval(interval2, 1, 1, No.allowDayOverflow, Direction.bwd, - Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31))); - testInterval(interval2, 1, -1, No.allowDayOverflow, Direction.bwd, - Interval!Date(Date(1999, 2, 28), Date(2010, 5, 31))); - testInterval(interval2, -1, -1, No.allowDayOverflow, Direction.bwd, - Interval!Date(Date(2001, 2, 28), Date(2010, 5, 31))); - testInterval(interval2, -1, 1, No.allowDayOverflow, Direction.bwd, - Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31))); - } - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - static assert(!__traits(compiles, cInterval.expand(5))); - static assert(!__traits(compiles, iInterval.expand(5))); - - //Verify Examples. - auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); - auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); - - interval1.expand(2); - assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); - - interval2.expand(-2); - assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); -} - -//Test Interval's fwdRange. -@system unittest -{ - { - auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)); - - static void testInterval1(Interval!Date interval) - { - interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); - } - - assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - - static void testInterval2(Interval!Date interval) - { - interval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront(); - } - - assertThrown!DateTimeException(testInterval2(interval)); - - assert(!interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); - assert(interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), Yes.popFirst).empty); - - assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front == - Date(2010, 9, 12)); - - assert( - Interval!Date( - Date(2010, 9, 12), - Date(2010, 10, 1) - ).fwdRange( - everyDayOfWeek!Date(DayOfWeek.fri), Yes.popFirst).front == Date(2010, 9, 17)); - } - - //Verify Examples. - { - auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); - auto func = delegate (in Date date) - { - if ((date.day & 1) == 0) - return date + dur!"days"(2); - - return date + dur!"days"(1); - }; - auto range = interval.fwdRange(func); - - assert(range.front == Date(2010, 9, 1)); //An odd day. Using Yes.popFirst would have made this Date(2010, 9, 2). - - range.popFront(); - assert(range.front == Date(2010, 9, 2)); - - range.popFront(); - assert(range.front == Date(2010, 9, 4)); - - range.popFront(); - assert(range.front == Date(2010, 9, 6)); - - range.popFront(); - assert(range.front == Date(2010, 9, 8)); - - range.popFront(); - assert(range.empty); - } - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - assert(!cInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); - assert(!iInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); -} - -//Test Interval's bwdRange. -@system unittest -{ - { - auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)); - - static void testInterval1(Interval!Date interval) - { - interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); - } - - assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); - - static void testInterval2(Interval!Date interval) - { - interval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront(); - } - - assertThrown!DateTimeException(testInterval2(interval)); - - assert(!interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty); - assert(interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), Yes.popFirst).empty); - - assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)) - .bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front == Date(2010, - 10, 1)); - - assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)) - .bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), Yes.popFirst).front == Date(2010, - 9, 24)); - } - - //Verify Examples. - { - auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); - auto func = delegate (in Date date) - { - if ((date.day & 1) == 0) - return date - dur!"days"(2); - - return date - dur!"days"(1); - }; - auto range = interval.bwdRange(func); - - assert(range.front == Date(2010, 9, 9)); //An odd day. Using Yes.popFirst would have made this Date(2010, 9, 8). - - range.popFront(); - assert(range.front == Date(2010, 9, 8)); - - range.popFront(); - assert(range.front == Date(2010, 9, 6)); - - range.popFront(); - assert(range.front == Date(2010, 9, 4)); - - range.popFront(); - assert(range.front == Date(2010, 9, 2)); - - range.popFront(); - assert(range.empty); - } - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - assert(!cInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); - assert(!iInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); -} - -//Test Interval's toString(). -@safe unittest -{ - assert(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).toString() == "[2010-Jul-04 - 2012-Jan-07)"); - - const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); - assert(cInterval.toString()); - assert(iInterval.toString()); -} - - /++ Represents an interval of time which has positive infinity as its end point. @@ -22454,6 +19229,7 @@ assert(!range.empty); } private: +package: // temporary /+ Since we have two versions of toString(), we have _toStringImpl() @@ -24683,6 +21459,7 @@ assert(!range.empty); } private: +package: // temporary /+ Since we have two versions of toString(), we have _toStringImpl() @@ -26531,6 +23308,7 @@ public: private: +package: // temporary /+ Params: