简体   繁体   中英

CarbonPeriod checks whether period is finite or not

I wrote a class that collects some information from a certain period by iterating and I need to check if this period is finite. I do somethink like that:

foreach ($cabonPeriod as $date) {
    // #some action
}

By finite, I mean whether there is an end/beginning of this period and is other than the end/start of time, and whether the number of iterations is not infinite, but probably first of the conditions will satisfy the second, so that my loop won't last forever.

I couldn't find a suitable method, so I wrote my own and it works for me, but it probably doesn't solve all cases of more advanced periods, which I don't have.

Here is my method:

private static function checkPeriod(CarbonPeriod $period)
{
    $start = $period->getStartDate();
    if ($start->isStartOfTime() || $start->isEndOfTime()) {
        throw new LengthException('Period has no defined beginning');
    }
    $end = $period->calculateEnd();
    if (!$end || $end->isStartOfTime() || $end->isEndOfTime()) {
        throw new LengthException('Period has no defined end');
    }
}

This seems to me quite a trivial case, so I'm wondering if there is any built-in method that allows you to achieve the same effect, or similar to mine, with less / more computational effort.

It's enough to be sure your period is iterable and not loop indefinitely.

But you can have finite periods that are not satisfying this. If it has a number of recurrences, then it does not has an end, if you want to accept those:

$end = $period->calculateEnd();
if ($end && ($end->isStartOfTime() || $end->isEndOfTime())) {
    throw new LengthException('Period has no finite end');
}

if (!$end && ($period->getRecurrences() === null || $period->getRecurrences() === INF) {
    throw new LengthException('Period has no defined end');
}

Last you can have filters in a period, filters cannot transform a finite period into an infinite period so you're on the safe side, but then can make a period to be finite in practice while it has no end and no recurrences.

You might also want to limit period. In practice if it loops for too long, it's probably causing troubles too (such as 1 second interval from 1970 to 2060).

For those case you can estimate the number of cycles and decide a maximum:

$end = $period->calculateEnd();
if ($end && ($end->isStartOfTime() || $end->isEndOfTime())) {
    throw new LengthException('Period has no finite end');
}

$recurrences = $period->getRecurrences();
if (!$end && ($recurrences === null || $recurrences === INF) {
    throw new LengthException('Period has no defined end');
}

$maxRecurrences = 2000;
if ($recurrences > $maxRecurrences) {
    throw new LengthException('Period is too long');
}

$seconds = $period->getDateInterval()->totalSeconds;
if ($end->diffInSeconds($start, true) / $seconds > $maxRecurrences) {
    throw new LengthException('Period is too long');
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM