3
\$\begingroup\$

I've written a function to get the smallest date from an date[ ] and check for null. If null == infinity

    /**
     * @param DateTimeInterface|null ...$dates
     * @return DateTime|null
     */
    public static function minDateTime(?DateTimeInterface ...$dates)
    {
        $dateList = [];
        $dates = array_filter($dates);
        if (empty($dates)) {
            // all values where null
            return null;
        }

        foreach ($dates as $date) {
            $dateList[] = $date->getTimestamp();
        }

        return (new DateTime())->setTimeStamp(min($dateList));
    }

Its working but could this be written smaller or with more comments, so that external coworkers can read this?

\$\endgroup\$
1
  • \$\begingroup\$ The $dateList = []; at the start of the function isn't needed. \$\endgroup\$ – Dave May 14 '20 at 17:01
1
\$\begingroup\$

Things to be aware of:

  • array_filter() does a full loop of the array.
  • foreach(), of course, does a full loop of the array.
  • min() does a full loop of the array.
  • empty() does a couple of things: it checks if a variable is not set AND if it is "falsey". Because the $dates variable will be unconditionally set, there is no need to check this -- just use !$dates if you want to check if the array is empty.
  • array_filter(), like empty() is a "greedy" seeker of "falsey" values. I assume that this is a non-issue for your task because there should be no 0 or false (etc.) values -- only datetime values or nulls.
  • datetime objects can be compared.
  • you don't need to make iterated calls to getTimestamp(), nor do you need to declare a new datetime object and set its time manually -- just use the one you found.

I suppose I'll recommend that you loop the data just one time. No array generation, no function calls, very direct and concise. Your custom method name is descriptive. Go with this:

Code: (Demo)

public static function minDateTime(?DateTimeInterface ...$dates)
{
    $minDate = null;
    foreach ($dates as $date) {
        if ($date && (!$minDate || $date < $minDate)) {
            $minDate = $date;
        }
    }
    return $minDate;
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ This was really helpfull. Didn't know until now that null == false. That did not cross my mind for years. Thanks for additional information on the different loops, too! \$\endgroup\$ – DasBen May 15 '20 at 6:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.