| // 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/_interval.d) |
| +/ |
| module std.datetime.interval; |
| |
| import core.time : Duration, dur; |
| import std.datetime.date : AllowDayOverflow, DateTimeException, daysToDayOfWeek, |
| DayOfWeek, isTimePoint, Month; |
| import std.exception : enforce; |
| import std.traits : isIntegral, Unqual; |
| import std.typecons : Flag; |
| |
| version (unittest) import std.exception : assertThrown; |
| |
| |
| /++ |
| Indicates a direction in time. One example of its use is $(LREF Interval)'s |
| $(LREF 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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 $(LREF 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 $(LREF 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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 |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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 |
| $(REF DateTimeException,std,datetime,date) 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: |
| $(REF DateTimeException,std,datetime,date) 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: |
| |
| /+ |
| 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: |
| $(REF DateTimeException,std,datetime,date) 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 |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| 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 |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| { |
| 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 |
| { |
| import std.datetime.date; |
| |
| 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 |
| { |
| import std.datetime.date; |
| |
| { |
| 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 |
| { |
| import std.datetime.date; |
| |
| { |
| 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 |
| { |
| import std.datetime.date; |
| |
| { |
| 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 |
| { |
| import std.datetime.date; |
| |
| assert(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).toString() == "[2010-Jul-04 - 2012-Jan-07)"); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(cInterval.toString()); |
| assert(iInterval.toString()); |
| } |
| |
| |
| /++ |
| Represents an interval of time which has positive infinity as its end point. |
| |
| Any ranges which iterate over a $(D PosInfInterval) are infinite. So, the |
| main purpose of using $(D PosInfInterval) is to create an infinite range |
| which starts at a fixed point in time and goes to positive infinity. |
| +/ |
| struct PosInfInterval(TP) |
| { |
| public: |
| |
| /++ |
| Params: |
| begin = The time point which begins the interval. |
| |
| Example: |
| -------------------- |
| auto interval = PosInfInterval!Date(Date(1996, 1, 2)); |
| -------------------- |
| +/ |
| this(in TP begin) pure nothrow |
| { |
| _begin = cast(TP) begin; |
| } |
| |
| |
| /++ |
| Params: |
| rhs = The $(D PosInfInterval) to assign to this one. |
| +/ |
| ref PosInfInterval opAssign(const ref PosInfInterval rhs) pure nothrow |
| { |
| _begin = cast(TP) rhs._begin; |
| return this; |
| } |
| |
| |
| /++ |
| Params: |
| rhs = The $(D PosInfInterval) to assign to this one. |
| +/ |
| ref PosInfInterval opAssign(PosInfInterval rhs) pure nothrow |
| { |
| _begin = cast(TP) rhs._begin; |
| return this; |
| } |
| |
| |
| /++ |
| The starting point of the interval. It is included in the interval. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).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. |
| +/ |
| @property void begin(TP timePoint) pure nothrow |
| { |
| _begin = timePoint; |
| } |
| |
| |
| /++ |
| Whether the interval's length is 0. Always returns false. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty); |
| -------------------- |
| +/ |
| enum bool empty = false; |
| |
| |
| /++ |
| Whether the given time point is within this interval. |
| |
| Params: |
| timePoint = The time point to check for inclusion in this interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5))); |
| -------------------- |
| +/ |
| bool contains(TP timePoint) const pure nothrow |
| { |
| return timePoint >= _begin; |
| } |
| |
| |
| /++ |
| Whether the given interval is completely within this interval. |
| |
| Params: |
| interval = The interval to check for inclusion in this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).contains( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).contains( |
| Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); |
| -------------------- |
| +/ |
| bool contains(in Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return interval._begin >= _begin; |
| } |
| |
| |
| /++ |
| Whether the given interval is completely within this interval. |
| |
| Params: |
| interval = The interval to check for inclusion in this interval. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).contains( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains( |
| PosInfInterval!Date(Date(1995, 7, 2)))); |
| -------------------- |
| +/ |
| bool contains(in PosInfInterval interval) const pure nothrow |
| { |
| return interval._begin >= _begin; |
| } |
| |
| |
| /++ |
| Whether the given interval is completely within this interval. |
| |
| Always returns false because an interval going to positive infinity |
| can never contain an interval beginning at negative infinity. |
| |
| Params: |
| interval = The interval to check for inclusion in this interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains( |
| NegInfInterval!Date(Date(1996, 5, 4)))); |
| -------------------- |
| +/ |
| bool contains(in NegInfInterval!TP interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given time point. |
| |
| Always returns false because an interval going to positive infinity |
| can never be before any time point. |
| |
| Params: |
| timePoint = The time point to check whether this interval is before |
| it. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5))); |
| -------------------- |
| +/ |
| bool isBefore(in TP timePoint) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given interval and does not |
| intersect it. |
| |
| Always returns false (unless the given interval is empty) because an |
| interval going to positive infinity can never be before any other |
| interval. |
| |
| Params: |
| interval = The interval to check for against this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| -------------------- |
| +/ |
| bool isBefore(in Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given interval and does not |
| intersect it. |
| |
| Always returns false because an interval going to positive infinity can |
| never be before any other interval. |
| |
| Params: |
| interval = The interval to check for against this interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( |
| PosInfInterval!Date(Date(1992, 5, 4)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( |
| PosInfInterval!Date(Date(2013, 3, 7)))); |
| -------------------- |
| +/ |
| bool isBefore(in PosInfInterval interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given interval and does not |
| intersect it. |
| |
| Always returns false because an interval going to positive infinity can |
| never be before any other interval. |
| |
| Params: |
| interval = The interval to check for against this interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( |
| NegInfInterval!Date(Date(1996, 5, 4)))); |
| -------------------- |
| +/ |
| bool isBefore(in NegInfInterval!TP interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given time point. |
| |
| Params: |
| timePoint = The time point to check whether this interval is after |
| it. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5))); |
| -------------------- |
| +/ |
| bool isAfter(in TP timePoint) const pure nothrow |
| { |
| 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: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| -------------------- |
| +/ |
| bool isAfter(in Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return _begin >= interval._end; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given interval and does not intersect |
| it. |
| |
| Always returns false because an interval going to positive infinity can |
| never be after another interval going to positive infinity. |
| |
| Params: |
| interval = The interval to check against this interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| PosInfInterval!Date(Date(1990, 1, 7)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| -------------------- |
| +/ |
| bool isAfter(in PosInfInterval interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given interval and does not intersect |
| it. |
| |
| Params: |
| interval = The interval to check against this interval. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| NegInfInterval!Date(Date(1996, 1, 2)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| NegInfInterval!Date(Date(2000, 7, 1)))); |
| -------------------- |
| +/ |
| bool isAfter(in NegInfInterval!TP interval) const pure nothrow |
| { |
| return _begin >= interval._end; |
| } |
| |
| |
| /++ |
| Whether the given interval overlaps this interval. |
| |
| Params: |
| interval = The interval to check for intersection with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| -------------------- |
| +/ |
| bool intersects(in Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return interval._end > _begin; |
| } |
| |
| |
| /++ |
| Whether the given interval overlaps this interval. |
| |
| Always returns true because two intervals going to positive infinity |
| always overlap. |
| |
| Params: |
| interval = The interval to check for intersection with this |
| interval. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| PosInfInterval!Date(Date(1990, 1, 7)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| -------------------- |
| +/ |
| bool intersects(in PosInfInterval interval) const pure nothrow |
| { |
| return true; |
| } |
| |
| |
| /++ |
| Whether the given interval overlaps this interval. |
| |
| Params: |
| interval = The interval to check for intersection with this |
| interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| NegInfInterval!Date(Date(1996, 1, 2)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| NegInfInterval!Date(Date(2000, 7, 1)))); |
| -------------------- |
| +/ |
| bool intersects(in NegInfInterval!TP interval) const pure nothrow |
| { |
| return _begin < interval._end; |
| } |
| |
| |
| /++ |
| Returns the intersection of two intervals |
| |
| Params: |
| interval = The interval to intersect with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect or if the given interval is empty. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == |
| Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); |
| -------------------- |
| +/ |
| Interval!TP intersection(in Interval!TP 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; |
| |
| return Interval!TP(begin, interval._end); |
| } |
| |
| |
| /++ |
| Returns the intersection of two intervals |
| |
| Params: |
| interval = The interval to intersect with this interval. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( |
| PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( |
| PosInfInterval!Date(Date(1999, 1, 12))) == |
| PosInfInterval!Date(Date(1999, 1 , 12))); |
| -------------------- |
| +/ |
| PosInfInterval intersection(in PosInfInterval interval) const pure nothrow |
| { |
| return PosInfInterval(_begin < interval._begin ? interval._begin : _begin); |
| } |
| |
| |
| /++ |
| Returns the intersection of two intervals |
| |
| Params: |
| interval = The interval to intersect with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( |
| NegInfInterval!Date(Date(1999, 7, 6))) == |
| Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( |
| NegInfInterval!Date(Date(2013, 1, 12))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2013, 1, 12))); |
| -------------------- |
| +/ |
| Interval!TP 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!TP(_begin, interval._end); |
| } |
| |
| |
| /++ |
| Whether the given interval is adjacent to this interval. |
| |
| Params: |
| interval = The interval to check whether its adjecent to this |
| interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( |
| Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| |
| assert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| -------------------- |
| +/ |
| bool isAdjacent(in Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return _begin == interval._end; |
| } |
| |
| |
| /++ |
| Whether the given interval is adjacent to this interval. |
| |
| Always returns false because two intervals going to positive infinity |
| can never be adjacent to one another. |
| |
| Params: |
| interval = The interval to check whether its adjecent to this |
| interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( |
| PosInfInterval!Date(Date(1990, 1, 7)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( |
| PosInfInterval!Date(Date(1996, 1, 2)))); |
| -------------------- |
| +/ |
| bool isAdjacent(in PosInfInterval interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether the given interval is adjacent to this interval. |
| |
| Params: |
| interval = The interval to check whether its adjecent to this |
| interval. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( |
| NegInfInterval!Date(Date(1996, 1, 2)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( |
| NegInfInterval!Date(Date(2000, 7, 1)))); |
| -------------------- |
| +/ |
| bool isAdjacent(in NegInfInterval!TP interval) const pure nothrow |
| { |
| return _begin == interval._end; |
| } |
| |
| |
| /++ |
| Returns the union of two intervals |
| |
| Params: |
| interval = The interval to merge with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect and are not adjacent or if the given interval is |
| empty. |
| |
| Note: |
| There is no overload for $(D merge) which takes a |
| $(D NegInfInterval), because an interval |
| going from negative infinity to positive infinity |
| is not possible. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| PosInfInterval!Date(Date(1990, 7 , 6))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| -------------------- |
| +/ |
| PosInfInterval merge(in Interval!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(_begin < interval._begin ? _begin : interval._begin); |
| } |
| |
| |
| /++ |
| Returns the union of two intervals |
| |
| Params: |
| interval = The interval to merge with this interval. |
| |
| Note: |
| There is no overload for $(D merge) which takes a |
| $(D NegInfInterval), because an interval |
| going from negative infinity to positive infinity |
| is not possible. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( |
| PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1990, 7 , 6))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( |
| PosInfInterval!Date(Date(1999, 1, 12))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| -------------------- |
| +/ |
| PosInfInterval merge(in PosInfInterval interval) const pure nothrow |
| { |
| return PosInfInterval(_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: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Note: |
| There is no overload for $(D span) which takes a |
| $(D NegInfInterval), because an interval |
| going from negative infinity to positive infinity |
| is not possible. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span( |
| Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) == |
| PosInfInterval!Date(Date(500, 8, 9))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| PosInfInterval!Date(Date(1990, 7 , 6))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| -------------------- |
| +/ |
| PosInfInterval span(in Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return PosInfInterval(_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. |
| |
| Note: |
| There is no overload for $(D span) which takes a |
| $(D NegInfInterval), because an interval |
| going from negative infinity to positive infinity |
| is not possible. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span( |
| PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1990, 7 , 6))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span( |
| PosInfInterval!Date(Date(1999, 1, 12))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| -------------------- |
| +/ |
| PosInfInterval span(in PosInfInterval interval) const pure nothrow |
| { |
| return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); |
| } |
| |
| |
| /++ |
| Shifts the $(D begin) of this 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). |
| |
| Params: |
| duration = The duration to shift the interval by. |
| |
| Example: |
| -------------------- |
| auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); |
| auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); |
| |
| interval1.shift(dur!"days"(50)); |
| assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21))); |
| |
| interval2.shift(dur!"days"(-50)); |
| assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13))); |
| -------------------- |
| +/ |
| void shift(D)(D duration) pure nothrow |
| if (__traits(compiles, begin + duration)) |
| { |
| _begin += duration; |
| } |
| |
| |
| static if (__traits(compiles, begin.add!"months"(1)) && |
| __traits(compiles, begin.add!"years"(1))) |
| { |
| /++ |
| Shifts the $(D begin) of this 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 |
| $(D begin). It effectively calls $(D add!"years"()) and then |
| $(D add!"months"()) on $(D begin) 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), causing its month to increment. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty or if the resulting interval would be invalid. |
| |
| Example: |
| -------------------- |
| auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); |
| auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); |
| |
| interval1.shift(dur!"days"(50)); |
| assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21))); |
| |
| interval2.shift(dur!"days"(-50)); |
| assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13))); |
| -------------------- |
| +/ |
| void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) |
| if (isIntegral!T) |
| { |
| auto begin = _begin; |
| |
| begin.add!"years"(years, allowOverflow); |
| begin.add!"months"(months, allowOverflow); |
| |
| _begin = begin; |
| } |
| } |
| |
| |
| /++ |
| Expands the interval backwards in time. Effectively, it does |
| $(D begin -= duration). |
| |
| Params: |
| duration = The duration to expand the interval by. |
| |
| Example: |
| -------------------- |
| auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); |
| auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); |
| |
| interval1.expand(dur!"days"(2)); |
| assert(interval1 == PosInfInterval!Date(Date(1995, 12, 31))); |
| |
| interval2.expand(dur!"days"(-2)); |
| assert(interval2 == PosInfInterval!Date(Date(1996, 1, 4))); |
| -------------------- |
| +/ |
| void expand(D)(D duration) pure nothrow |
| if (__traits(compiles, begin + duration)) |
| { |
| _begin -= duration; |
| } |
| |
| |
| 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). |
| |
| 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), causing its month to increment. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty or if the resulting interval would be invalid. |
| |
| Example: |
| -------------------- |
| auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); |
| auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); |
| |
| interval1.expand(2); |
| assert(interval1 == PosInfInterval!Date(Date(1994, 1, 2))); |
| |
| interval2.expand(-2); |
| assert(interval2 == PosInfInterval!Date(Date(1998, 1, 2))); |
| -------------------- |
| +/ |
| void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) |
| if (isIntegral!T) |
| { |
| auto begin = _begin; |
| |
| begin.add!"years"(-years, allowOverflow); |
| begin.add!"months"(-months, allowOverflow); |
| |
| _begin = begin; |
| } |
| } |
| |
| |
| /++ |
| 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 |
| $(REF DateTimeException,std,datetime,date) will be thrown. |
| |
| There are helper functions in this module which generate common |
| delegates to pass to $(D fwdRange). Their documentation starts with |
| "Range-generating function," to make 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: |
| $(REF DateTimeException,std,datetime,date) 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 = PosInfInterval!Date(Date(2010, 9, 1)); |
| 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); |
| -------------------- |
| +/ |
| PosInfIntervalRange!(TP) fwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const |
| { |
| auto range = PosInfIntervalRange!(TP)(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: |
| |
| /+ |
| 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 - ∞)", _begin); |
| catch (Exception e) |
| assert(0, "format() threw."); |
| } |
| |
| |
| TP _begin; |
| } |
| |
| //Test PosInfInterval's constructor. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| PosInfInterval!Date(Date.init); |
| PosInfInterval!TimeOfDay(TimeOfDay.init); |
| PosInfInterval!DateTime(DateTime.init); |
| PosInfInterval!SysTime(SysTime(0)); |
| |
| //Verify Examples. |
| auto interval = PosInfInterval!Date(Date(1996, 1, 2)); |
| } |
| |
| //Test PosInfInterval's begin. |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| assert(PosInfInterval!Date(Date(1, 1, 1)).begin == Date(1, 1, 1)); |
| assert(PosInfInterval!Date(Date(2010, 1, 1)).begin == Date(2010, 1, 1)); |
| assert(PosInfInterval!Date(Date(1997, 12, 31)).begin == Date(1997, 12, 31)); |
| |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| assert(cPosInfInterval.begin != Date.init); |
| assert(iPosInfInterval.begin != Date.init); |
| |
| //Verify Examples. |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2)); |
| } |
| |
| //Test PosInfInterval's empty. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| assert(!PosInfInterval!Date(Date(2010, 1, 1)).empty); |
| assert(!PosInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty); |
| assert(!PosInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty); |
| assert(!PosInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty); |
| |
| const cPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(!cPosInfInterval.empty); |
| assert(!iPosInfInterval.empty); |
| |
| //Verify Examples. |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty); |
| } |
| |
| //Test PosInfInterval's contains(time point). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| assert(!posInfInterval.contains(Date(2009, 7, 4))); |
| assert(!posInfInterval.contains(Date(2010, 7, 3))); |
| assert(posInfInterval.contains(Date(2010, 7, 4))); |
| assert(posInfInterval.contains(Date(2010, 7, 5))); |
| assert(posInfInterval.contains(Date(2011, 7, 1))); |
| |