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\$ Commented May 14, 2020 at 17:01

1 Answer 1

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\$ Commented May 15, 2020 at 6:45

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.