phobos/std/datetime/interval.d
2017-05-04 10:00:29 +02:00

3069 lines
130 KiB
D

// Written in the D programming language
/++
License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
Authors: Jonathan M Davis
Source: $(PHOBOSSRC std/_datetime.d)
Macros:
LREF2=<a href="#$1">$(D $2)</a>
+/
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());
}