Date range iteration

Jonathan M Davis newsgroup.d at jmdavisprog.com
Mon Mar 12 02:49:34 UTC 2018


On Monday, March 12, 2018 02:11:49 Jordan Wilson via Digitalmars-d-learn 
wrote:
> I wanted to iterate through a date range, so I initially tried:
> iota(Date(2016,1,1),Date(2018,1,1),dur!"days"(1));
>
> That wouldn't compile, which is fair enough I guess.

Maybe iota should be made to work, but as present, it basically wants all
three of the types it's given to be the same or implicitly convertible to
a single type. It can't handle the step being a completely different type.

> So I tried a for loop:
> for (auto i = Date(2016,1,1); i < Date(2018,1,1);
> i+=dur!"days"(1)){}
>
> That seemed to work fine, but I remember reading "for loops are
> bad" somewhere.

for loops are just fine - especially if you're just going to loop through
all the values and do something to them - but if you have a range, it's a
lot more flexible.

> So I looked for a range type mechanism, and I
> think it's this:
> foreach (i; Interval!Date
> (Date(2016,1,1),Date(2018,1,1)).fwdRange ( (a) { return
> a+dur!"days"(1); })){}
>
> My question is if the third way is the proper way of stepping
> through a period of time? It just seems quite complicated to me.

Well, honestly, the range support in std.datetime isn't very good. The core
problem that overcomplicates it is that the Interval needs to know which
direction you want to iterate in, and then the helper functions tend to need
to know it too in order to work properly. Also, the time point type being
used also tends to get duplicated a fair bit. So, you end up with annoyingly
repetitive code. The helper function intended for this use case is

https://dlang.org/phobos/std_datetime_interval.html#everyDuration

So, you'd get something more like

auto interval = Interval!Date(Date(2016, 1, 1), Date(2018, 1, 1));
auto range = interval.fwdRange(everyDuration!Date(days(1)));

But if you're just going to use the range in a foreach loop, then you might
as well just use a for loop. All of this extra machinery only really starts
being valuable when you start feeding the ranges into range-based functions.
For a simple loop, it's overkill.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list