thephpleague / period

PHP's time range API

Home Page:https://period.thephpleague.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add helper itterators

adamnicholson opened this issue · comments

It would be really handy if this lib could do things like:

foreach ($period->weeks() as $period)
    // ....

This'd work for days(), weeks(), months(), years().

Or perhaps just a $period->each(\DateInterval $interval) which would give us scope to add anything?

I'm more than happy to write the code for this, but wanted to put feelers out and see if it was something you'd consider (or have already considered) before investing the time.

Hi,
Thanks for your interest in the package... there's already a Period::getRange which will become a Period::getDatePeriod in version 2.5 which does what you are proposing unless I did not get your intent ?

Sort of.

The problem with that method is that it returns a \DatePeriod object, which when iterating will simply return \DateTime's.

What seems like a better and more powerful option would be if getRange (or a new similar method) actually returned an instance of Period for each iteration.

Essentially a method that would return the same as this basic example if you wanted to iterate by month:

$months = [];
for ($i=1; $i<=12; $i++) {
    $months[] = Period::createFromMonth(2015, $i);
}
return $months;

Which would return 12 Period objects, representing each month.

Okay so what you would like to have is something like this:

function getInnerPeriods(Period $period, DateInterval $interval)
{
    $data = [];
    foreach ($period->getRange($interval) as $startDate) {
        $data[] = Period::createFromDuration($startDate, $interval);
    }

    return $data;
}

I don't see the inner benefits of this being included in the package as we are dealing with a Value Object which only tries to cover basic usage. Try to sell it to me with better argument because this function is really easy to do userland wise.
Again I may be wrong but you can still go ahead and make a PR around this I'll re-evaluate it with the PR in front of me.

Yes that's the sort of thing. Although you'd not need to pass in $period as you'd just reference $this.

The way I see it is that this is simply a more powerful version of getDatePeriod(). In fact, this is how I initially expected getRange()/getDatePeriod() to work (maybe naively as I hadn't used \DatePeriod before).

It can do everything getDatePeriod() can do, as well as giving you the power of the Period object. So the question in my mind is why do you think getDatePeriod() is worthwhile including but something like getInnerPeriods() isn't?

I don't think I agree with the 'this is easy to do in userland' argument. Everything this package does is easy to do in userland, Period just makes it even easier and removes the need to write boilerplate every time you want to perform a common task. I believe this is one of those common tasks that this package could cover.

Good point,

Let's assume we add the Period::getInnerPeriods method there are some egde cases like the following:

$period = Period::createFromYear(2015);
$res = $period->getInnerPeriods('5 MONTHS'); //$res is an array
  • how many period objects are in $res ? 2 or 3 ?
  • If the answer is 3. What is the interval of the last period ? 5 months or 2 months ?

I would say in that case $res should contain 3 Period objects.

Personally I would expect the third element to contain 2 months from your example, because the method name implies we're only interested in inner periods, but I can see where it might cause confusion.

Perhaps this would be better with an optional $overflow argument?

public function getInnerPeriods($interval, $overflow = false)

If $overflow is true, it would return 5 months, if false it would return 2 months.

I prefer having a opinionated choice that a relax one. Having a method with boolean variable is always a mess. That one reason I'm deprecating Period::getDuration. On usage, I always had to go back to documentation to know what true/false meant. In version 2.5 there will be getDateInterval and getTimestampInterval to replace it but they will be more accurate. Your expectation is the one I would expect too. So we will document it and the method name implies is too.
TL;DR:

  • $res returns 3 Period objects
  • the last Period object has an interval of 2 months

I've renamed the method to split which is self explanatory 👍

So now only HHVM failed tests is restraining the release of 2.5