Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
a local clone.

std.datetime.interval

Indicates a direction in time. One example of its use is Interval's
expand function which uses it to indicate whether the interval
should be expanded backwards (into the past), forwards (into the future), or
both.

bwd

Backward.

fwd

Forward.

both

Both backward and forward.

alias PopFirst = std.typecons.Flag!"popFirst".Flag;

Used to indicate whether popFront should be called immediately upon
creating a range. The idea is that for some functions used to generate a
range for an interval, 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 PopFirst.yes to indicate
that the range should have popFront called on it before the range is
returned so that front is a time point which the function would
generate. To let the first time point not match the generator function,
use 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
PopFirst.yes would tell the function which returned the range that
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 front, while when iterating backward,
it would be the Easter prior to the original front). If
PopFirst.no were used, then 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 PopFirst.no, then popFront is not called before returning
the range.

Otherwise, if set to PopFirst.yes, then popFront is called before
returning the range.

struct Interval(TP);

Represents an interval of time.

An 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.

[January 5th, 2010 - March 10th, 2010)

[05:00:30 - 12:00:00)

[1982-01-04T08:59:00 - 2010-07-04T12:00:00)

A range can be obtained from an Interval, allowing iteration over
that interval, with the exact time points which are iterated over depending
on the function which generates the range.

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 begin += duration and
end += duration.

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 add!"years"() and then add!"months"()
on begin and end with the given number of years and months.

Parameters:

T years

The number of years to shift the interval by.

T months

The number of months to shift the interval by.

AllowDayOverflow allowOverflow

Whether the days should be allowed to overflow
on begin and end, causing their month
to increment.

Expands the interval forwards and/or backwards in time. Effectively,
it subtracts the given number of months/years from begin and
adds them to end. Whether it expands forwards and/or backwards
in time is determined by dir.

Parameters:

T years

The number of years to expand the interval by.

T months

The number of months to expand the interval by.

AllowDayOverflow allowOverflow

Whether the days should be allowed to overflow
on begin and end, causing their month
to increment.

Returns a range which iterates forward over the interval, starting
at begin, using func to generate each successive time
point.

The range's front is the interval's begin. func is
used to generate the next front when popFront is called. If
popFirst is PopFirst.yes, then popFront is called
before the range is returned (so that front is a time point which
func would generate).

If func ever generates a time point less than or equal to the
current front of the range, then a
std.datetime.date.DateTimeException will be thrown. The range
will be empty and iteration complete when func generates a
time point equal to or beyond the end of the interval.

There are helper functions in this module which generate common
delegates to pass to fwdRange. Their documentation starts with
"Range-generating function," making them easily searchable.

Parameters:

TP delegate(in TP) func

The function used to generate the time points of the
range over the interval.

Warningfunc must be logically pure. Ideally, func
would be a function pointer to a pure function, but forcing
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 fwdRange, func must be a
delegate.

If func retains state which changes as it is called, then
some algorithms will not work correctly, because the range's
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 fwdRange. If 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.

Returns a range which iterates backwards over the interval, starting
at end, using func to generate each successive time
point.

The range's front is the interval's end. func is
used to generate the next front when popFront is called. If
popFirst is PopFirst.yes, then popFront is called
before the range is returned (so that front is a time point which
func would generate).

If func ever generates a time point greater than or equal to
the current front of the range, then a
std.datetime.date.DateTimeException will be thrown. The range
will be empty and iteration complete when func generates a
time point equal to or less than the begin of the interval.

There are helper functions in this module which generate common
delegates to pass to bwdRange. Their documentation starts with
"Range-generating function," making them easily searchable.

Parameters:

TP delegate(in TP) func

The function used to generate the time points of the
range over the interval.

Warningfunc must be logically pure. Ideally, func
would be a function pointer to a pure function, but forcing
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 fwdRange, func must be a
delegate.

If func retains state which changes as it is called, then
some algorithms will not work correctly, because the range's
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 fwdRange. If 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.

Represents an interval of time which has positive infinity as its end point.

Any ranges which iterate over a PosInfInterval are infinite. So, the
main purpose of using PosInfInterval is to create an infinite range
which starts at a fixed point in time and goes to positive infinity.

Shifts the 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
begin += duration.

Shifts the 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
begin. It effectively calls add!"years"() and then
add!"months"() on begin with the given number of years and
months.

Parameters:

T years

The number of years to shift the interval by.

T months

The number of months to shift the interval by.

AllowDayOverflow allowOverflow

Whether the days should be allowed to overflow
on begin, causing its month to increment.

Returns a range which iterates forward over the interval, starting
at begin, using func to generate each successive time
point.

The range's front is the interval's begin. func is
used to generate the next front when popFront is called. If
popFirst is PopFirst.yes, then popFront is called
before the range is returned (so that front is a time point which
func would generate).

Warningfunc must be logically pure. Ideally, func
would be a function pointer to a pure function, but forcing
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 fwdRange, func must be a
delegate.

If func retains state which changes as it is called, then
some algorithms will not work correctly, because the range's
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 fwdRange. If 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.

Represents an interval of time which has negative infinity as its starting
point.

Any ranges which iterate over a NegInfInterval are infinite. So, the
main purpose of using NegInfInterval is to create an infinite range
which starts at negative infinity and goes to a fixed end point.
Iterate over it in reverse.

Shifts the end 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
end += duration.

Shifts the end 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 end. It
effectively calls add!"years"() and then add!"months"()
on end with the given number of years and months.

Parameters:

T years

The number of years to shift the interval by.

T months

The number of months to shift the interval by.

AllowDayOverflow allowOverflow

Whether the days should be allowed to overflow
on end, causing its month to increment.

Returns a range which iterates backwards over the interval, starting
at end, using func to generate each successive time
point.

The range's front is the interval's end. func is
used to generate the next front when popFront is called. If
popFirst is PopFirst.yes, then popFront is called
before the range is returned (so that front is a time point which
func would generate).

Warningfunc must be logically pure. Ideally, func
would be a function pointer to a pure function, but forcing
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 fwdRange, func must be a
delegate.

If func retains state which changes as it is called, then
some algorithms will not work correctly, because the range's
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 fwdRange. If 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.

Returns a delegate which returns the next time point with the given
DayOfWeek in a range.

Using this delegate allows iteration over successive time points which
are all the same day of the week. e.g. passing DayOfWeek.mon to
everyDayOfWeek would result in a delegate which could be used to
iterate over all of the Mondays in a range.

Parameters:

dir

The direction to iterate in. If passing the return value to
fwdRange, use Direction.fwd. If passing it to
bwdRange, use Direction.bwd.

Returns a delegate which returns the next time point with the given month
which would be reached by adding months to the given time point.

So, using this delegate allows iteration over successive time points
which are in the same month but different years. For example,
iterate over each successive December 25th in an interval by starting with a
date which had the 25th as its day and passed Month.dec to
everyMonth to create the delegate.

Since it wouldn't really make sense to be iterating over a specific month
and end up with some of the time points in the succeeding month or two years
after the previous time point, AllowDayOverflow.no is always used when
calculating the next time point.

Parameters:

dir

The direction to iterate in. If passing the return value to
fwdRange, use Direction.fwd. If passing it to
bwdRange, use Direction.bwd.

int month

The month that each time point in the range will be in
(January is 1).

Returns a delegate which returns the next time point which is the given
duration later.

Using this delegate allows iteration over successive time points which
are apart by the given duration e.g. passing dur!"days"(3) to
everyDuration would result in a delegate which could be used to iterate
over a range of days which are each 3 days apart.

Parameters:

dir

The direction to iterate in. If passing the return value to
fwdRange, use Direction.fwd. If passing it to
bwdRange, use Direction.bwd.

Returns a delegate which returns the next time point which is the given
number of years, month, and duration later.

The difference between this version of everyDuration and the version
which just takes a core.time.Duration is that this one also takes
the number of years and months (along with an AllowDayOverflow to
indicate whether adding years and months should allow the days to overflow).

Note that if iterating forward, add!"years"() is called on the given
time point, then add!"months"(), and finally the duration is added
to it. However, if iterating backwards, the duration is added first, then
add!"months"() is called, and finally add!"years"() is called.
That way, going backwards generates close to the same time points that
iterating forward does, but since adding years and months is not entirely
reversible (due to possible day overflow, regardless of whether
AllowDayOverflow.yes or AllowDayOverflow.no is used), it can't be
guaranteed that iterating backwards will give the same time points as
iterating forward would have (even assuming that the end of the range is a
time point which would be returned by the delegate when iterating forward
from begin).

Parameters:

dir

The direction to iterate in. If passing the return
value to fwdRange, use Direction.fwd. If
passing it to bwdRange, use Direction.bwd.

int years

The number of years to add to the time point passed to
the delegate.

int months

The number of months to add to the time point passed to
the delegate.

AllowDayOverflow allowOverflow

Whether the days should be allowed to overflow on
begin and end, causing their month to
increment.

IntervalRange is only ever constructed by Interval. However, when
it is constructed, it is given a function, func, which is used to
generate the time points which are iterated over. func takes a time
point and returns a time point of the same type. For instance,
to iterate over all of the days in
the interval Interval!Date, pass a function to Interval's
fwdRange where that function took a std.datetime.date.Date and
returned a std.datetime.date.Date which was one day later. That
function would then be used by IntervalRange's popFront to iterate
over the std.datetime.date.Dates in the interval.

If dir == Direction.fwd, then a range iterates forward in time, whereas
if dir == Direction.bwd, then it iterates backwards in time. So, if
dir == Direction.fwd then front == interval.begin, whereas if
dir == Direction.bwd then front == interval.end. func must
generate a time point going in the proper direction of iteration, or a
std.datetime.date.DateTimeException will be thrown. So, to iterate
forward in time, the time point that func generates must be later in
time than the one passed to it. If it's either identical or earlier in time,
then a std.datetime.date.DateTimeException will be thrown. To
iterate backwards, then the generated time point must be before the time
point which was passed in.

If the generated time point is ever passed the edge of the range in the
proper direction, then the edge of that range will be used instead. So, if
iterating forward, and the generated time point is past the interval's
end, then front becomes end. If iterating backwards, and the
generated time point is before begin, then front becomes
begin. In either case, the range would then be empty.

Also note that while normally the begin of an interval is included in
it and its end is excluded from it, if dir == Direction.bwd, then
begin is treated as excluded and end is treated as included. This
allows for the same behavior in both directions. This works because none of
Interval's functions which care about whether begin or end
is included or excluded are ever called by IntervalRange. interval
returns a normal interval, regardless of whether dir == Direction.fwd
or if dir == Direction.bwd, so any Interval functions which are
called on it which care about whether begin or end are included or
excluded will treat begin as included and end as excluded.

Pops front from the range, using func to generate the next
time point in the range. If the generated time point is beyond the edge
of the range, then front is set to that edge, and the range is then
empty. So, if iterating forwards, and the generated time point is
greater than the interval's end, then front is set to
end. If iterating backwards, and the generated time point is less
than the interval's begin, then front is set to begin.

Throws:

std.datetime.date.DateTimeException if the range is empty
or if the generated time point is in the wrong direction (i.e. if
iterating forward and the generated time point is before front,
or if iterating backwards and the generated time point is after
front).

pure nothrow @property IntervalRange save();

Returns a copy of this.

const pure nothrow @property Interval!TP interval();

The interval that this IntervalRange currently covers.

pure nothrow @property TP delegate(in TP) func();

The function used to generate the next time point in the range.

const pure nothrow @property Direction direction();

The Direction that this range iterates in.

struct PosInfIntervalRange(TP) if (isTimePoint!TP);

A range over a PosInfInterval. It is an infinite range.

PosInfIntervalRange is only ever constructed by PosInfInterval.
However, when it is constructed, it is given a function, func, which
is used to generate the time points which are iterated over. func
takes a time point and returns a time point of the same type. For
instance, to iterate
over all of the days in the interval PosInfInterval!Date, pass a
function to PosInfInterval's fwdRange where that function took a
std.datetime.date.Date and returned a std.datetime.date.Date
which was one day later. That function would then be used by
PosInfIntervalRange's popFront to iterate over the
std.datetime.date.Dates in the interval - though obviously, since the
range is infinite, use a function such as std.range.take with it rather
than iterating over all of the dates.

As the interval goes to positive infinity, the range is always iterated over
forwards, never backwards. func must generate a time point going in
the proper direction of iteration, or a
std.datetime.date.DateTimeException will be thrown. So, the time
points that func generates must be later in time than the one passed to
it. If it's either identical or earlier in time, then a
std.datetime.date.DateTimeException will be thrown.

NegInfIntervalRange is only ever constructed by NegInfInterval.
However, when it is constructed, it is given a function, func, which
is used to generate the time points which are iterated over. func
takes a time point and returns a time point of the same type. For
instance, to iterate over all of the days in the interval
NegInfInterval!Date, pass a function to NegInfInterval's
bwdRange where that function took a std.datetime.date.Date and
returned a std.datetime.date.Date which was one day earlier. That
function would then be used by NegInfIntervalRange's popFront to
iterate over the std.datetime.date.Dates in the interval - though
obviously, since the range is infinite, use a function such as
std.range.take with it rather than iterating over all of the dates.

As the interval goes to negative infinity, the range is always iterated over
backwards, never forwards. func must generate a time point going in
the proper direction of iteration, or a
std.datetime.date.DateTimeException will be thrown. So, the time
points that func generates must be earlier in time than the one passed
to it. If it's either identical or later in time, then a
std.datetime.date.DateTimeException will be thrown.

Also note that while normally the end of an interval is excluded from
it, NegInfIntervalRange treats it as if it were included. This allows
for the same behavior as with PosInfIntervalRange. This works
because none of NegInfInterval's functions which care about whether
end is included or excluded are ever called by
NegInfIntervalRange. interval returns a normal interval, so any
NegInfInterval functions which are called on it which care about
whether end is included or excluded will treat end as excluded.