src/Utilities/Date.php
public static function getDateDifference($dateStart, $dateEnd, $differenceUnit = null)
    {
        $validDateStart = self::isValidDate($dateStart, true);
        $validDateEnd = self::isValidDate($dateEnd, true);

        /*
         * The start or end date is unknown?
         * or
         * The start or end date is not valid date?
         *
         * Nothing to do
         */
        if (empty($dateStart) || empty($dateEnd) || !$validDateStart || !$validDateEnd) {
            return null;
        }

        $start = self::getDateTime($dateStart, true);
        $end = self::getDateTime($dateEnd, true);

        $difference = [];
        $dateDiff = $end->getTimestamp() - $start->getTimestamp();

        $daysInSeconds = 0;
        $hoursInSeconds = 0;

        $hourSeconds = 60 * 60;
        $daySeconds = $hourSeconds * 24;

        /*
         * These units are related, because while calculating difference in the lowest unit, difference in the
         * highest unit is required, e.g. while calculating hours I have to know difference in days
         */
        $relatedUnits = [
            self::DATE_DIFFERENCE_UNIT_DAYS,
            self::DATE_DIFFERENCE_UNIT_HOURS,
            self::DATE_DIFFERENCE_UNIT_MINUTES,
        ];

        if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_YEARS === $differenceUnit) {
            $diff = $end->diff($start);

            // Difference between dates in years should be returned only?
            if (self::DATE_DIFFERENCE_UNIT_YEARS === $differenceUnit) {
                return $diff->y;
            }

            $difference[self::DATE_DIFFERENCE_UNIT_YEARS] = $diff->y;
        }

        if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MONTHS === $differenceUnit) {
            $diff = $end->diff($start);

            // Difference between dates in months should be returned only?
            if (self::DATE_DIFFERENCE_UNIT_MONTHS === $differenceUnit) {
                return $diff->m;
            }

            $difference[self::DATE_DIFFERENCE_UNIT_MONTHS] = $diff->m;
        }

        if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
            $days = (int)floor($dateDiff / $daySeconds);

            // Difference between dates in days should be returned only?
            if (self::DATE_DIFFERENCE_UNIT_DAYS === $differenceUnit) {
                return $days;
            }

            // All units should be returned?
            if (null === $differenceUnit) {
                $difference[self::DATE_DIFFERENCE_UNIT_DAYS] = $days;
            }

            // Calculation for later usage
            $daysInSeconds = $days * $daySeconds;
        }

        if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
            $hours = (int)floor(($dateDiff - $daysInSeconds) / $hourSeconds);

            // Difference between dates in hours should be returned only?
            if (self::DATE_DIFFERENCE_UNIT_HOURS === $differenceUnit) {
                return $hours;
            }

            // All units should be returned?
            if (null === $differenceUnit) {
                $difference[self::DATE_DIFFERENCE_UNIT_HOURS] = $hours;
            }

            // Calculation for later usage
            $hoursInSeconds = $hours * $hourSeconds;
        }

        if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MINUTES === $differenceUnit) {
            $minutes = (int)floor(($dateDiff - $daysInSeconds - $hoursInSeconds) / 60);

            // Difference between dates in minutes should be returned only?
            if (self::DATE_DIFFERENCE_UNIT_MINUTES === $differenceUnit) {
                return $minutes;
            }

            $difference[self::DATE_DIFFERENCE_UNIT_MINUTES] = $minutes;
        }

        return $difference;
    }
public static function getDateDifference($dateStart, $dateEnd, $differenceUnit = null)
    {
        $validDateStart = self::isValidDate($dateStart, true);
        $validDateEnd = self::isValidDate($dateEnd, true);

        /*
         * The start or end date is unknown?
         * or
         * The start or end date is not valid date?
         *
         * Nothing to do
         */
        if (empty($dateStart) || empty($dateEnd) || !$validDateStart || !$validDateEnd) {
            return null;
        }

        $start = self::getDateTime($dateStart, true);
        $end = self::getDateTime($dateEnd, true);

        $difference = [];
        $dateDiff = $end->getTimestamp() - $start->getTimestamp();

        $daysInSeconds = 0;
        $hoursInSeconds = 0;

        $hourSeconds = 60 * 60;
        $daySeconds = $hourSeconds * 24;

        /*
         * These units are related, because while calculating difference in the lowest unit, difference in the
         * highest unit is required, e.g. while calculating hours I have to know difference in days
         */
        $relatedUnits = [
            self::DATE_DIFFERENCE_UNIT_DAYS,
            self::DATE_DIFFERENCE_UNIT_HOURS,
            self::DATE_DIFFERENCE_UNIT_MINUTES,
        ];

        if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_YEARS === $differenceUnit) {
            $diff = $end->diff($start);

            // Difference between dates in years should be returned only?
            if (self::DATE_DIFFERENCE_UNIT_YEARS === $differenceUnit) {
                return $diff->y;
            }

            $difference[self::DATE_DIFFERENCE_UNIT_YEARS] = $diff->y;
        }

        if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MONTHS === $differenceUnit) {
            $diff = $end->diff($start);

            // Difference between dates in months should be returned only?
            if (self::DATE_DIFFERENCE_UNIT_MONTHS === $differenceUnit) {
                return $diff->m;
            }

            $difference[self::DATE_DIFFERENCE_UNIT_MONTHS] = $diff->m;
        }

        if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
            $days = (int)floor($dateDiff / $daySeconds);

            // Difference between dates in days should be returned only?
            if (self::DATE_DIFFERENCE_UNIT_DAYS === $differenceUnit) {
                return $days;
            }

            // All units should be returned?
            if (null === $differenceUnit) {
                $difference[self::DATE_DIFFERENCE_UNIT_DAYS] = $days;
            }

            // Calculation for later usage
            $daysInSeconds = $days * $daySeconds;
        }

        if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
            $hours = (int)floor(($dateDiff - $daysInSeconds) / $hourSeconds);

            // Difference between dates in hours should be returned only?
            if (self::DATE_DIFFERENCE_UNIT_HOURS === $differenceUnit) {
                return $hours;
            }

            // All units should be returned?
            if (null === $differenceUnit) {
                $difference[self::DATE_DIFFERENCE_UNIT_HOURS] = $hours;
            }

            // Calculation for later usage
            $hoursInSeconds = $hours * $hourSeconds;
        }

        if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MINUTES === $differenceUnit) {
            $minutes = (int)floor(($dateDiff - $daysInSeconds - $hoursInSeconds) / 60);

            // Difference between dates in minutes should be returned only?
            if (self::DATE_DIFFERENCE_UNIT_MINUTES === $differenceUnit) {
                return $minutes;
            }

            $difference[self::DATE_DIFFERENCE_UNIT_MINUTES] = $minutes;
        }

        return $difference;
    }
public static function getDateDifference ( $ dateStart , $ dateEnd , $ differenceUnit = null ) { $ validDateStart = self :: isValidDate ( $ dateStart , true ) ; $ validDateEnd = self :: isValidDate ( $ dateEnd , true ) ; /*
         * The start or end date is unknown?
         * or
         * The start or end date is not valid date?
         *
         * Nothing to do
         */ if ( empty ( $ dateStart ) || empty ( $ dateEnd ) || ! $ validDateStart || ! $ validDateEnd ) { return null ; } $ start = self :: getDateTime ( $ dateStart , true ) ; $ end = self :: getDateTime ( $ dateEnd , true ) ; $ difference = [ ] ; $ dateDiff = $ end -> getTimestamp ( ) - $ start -> getTimestamp ( ) ; $ daysInSeconds = 0 ; $ hoursInSeconds = 0 ; $ hourSeconds = 60 * 60 ; $ daySeconds = $ hourSeconds * 24 ; /*
         * These units are related, because while calculating difference in the lowest unit, difference in the
         * highest unit is required, e.g. while calculating hours I have to know difference in days
         */ $ relatedUnits = [ self :: DATE_DIFFERENCE_UNIT_DAYS , self :: DATE_DIFFERENCE_UNIT_HOURS , self :: DATE_DIFFERENCE_UNIT_MINUTES , ] ; if ( null === $ differenceUnit || self :: DATE_DIFFERENCE_UNIT_YEARS === $ differenceUnit ) { $ diff = $ end -> diff ( $ start ) ; // Difference between dates in years should be returned only? if ( self :: DATE_DIFFERENCE_UNIT_YEARS === $ differenceUnit ) { return $ diff -> y ; } $ difference [ self :: DATE_DIFFERENCE_UNIT_YEARS ] = $ diff -> y ; } if ( null === $ differenceUnit || self :: DATE_DIFFERENCE_UNIT_MONTHS === $ differenceUnit ) { $ diff = $ end -> diff ( $ start ) ; // Difference between dates in months should be returned only? if ( self :: DATE_DIFFERENCE_UNIT_MONTHS === $ differenceUnit ) { return $ diff -> m ; } $ difference [ self :: DATE_DIFFERENCE_UNIT_MONTHS ] = $ diff -> m ; } if ( null === $ differenceUnit || in_array ( $ differenceUnit , $ relatedUnits , true ) ) { $ days = ( int ) floor ( $ dateDiff / $ daySeconds ) ; // Difference between dates in days should be returned only? if ( self :: DATE_DIFFERENCE_UNIT_DAYS === $ differenceUnit ) { return $ days ; } // All units should be returned? if ( null === $ differenceUnit ) { $ difference [ self :: DATE_DIFFERENCE_UNIT_DAYS ] = $ days ; } // Calculation for later usage $ daysInSeconds = $ days * $ daySeconds ; } if ( null === $ differenceUnit || in_array ( $ differenceUnit , $ relatedUnits , true ) ) { $ hours = ( int ) floor ( ( $ dateDiff - $ daysInSeconds ) / $ hourSeconds ) ; // Difference between dates in hours should be returned only? if ( self :: DATE_DIFFERENCE_UNIT_HOURS === $ differenceUnit ) { return $ hours ; } // All units should be returned? if ( null === $ differenceUnit ) { $ difference [ self :: DATE_DIFFERENCE_UNIT_HOURS ] = $ hours ; } // Calculation for later usage $ hoursInSeconds = $ hours * $ hourSeconds ; } if ( null === $ differenceUnit || self :: DATE_DIFFERENCE_UNIT_MINUTES === $ differenceUnit ) { $ minutes = ( int ) floor ( ( $ dateDiff - $ daysInSeconds - $ hoursInSeconds ) / 60 ) ; // Difference between dates in minutes should be returned only? if ( self :: DATE_DIFFERENCE_UNIT_MINUTES === $ differenceUnit ) { return $ minutes ; } $ difference [ self :: DATE_DIFFERENCE_UNIT_MINUTES ] = $ minutes ; } return $ difference ; }
Returns difference between given dates.

The difference is calculated in units based on the 3rd argument or all available unit of date difference
(defined as DATE_DIFFERENCE_UNIT_* constants of this class).

The difference is also whole / complete value for given unit instead of relative value as may be received by
DateTime::diff() method, e.g.:
- 2 days, 50 hours
instead of
- 2 days, 2 hours

If the unit of date difference is null, all units are returned in array (units are keys of the array).
Otherwise - one, integer value is returned.

@param DateTime|string $dateStart      The start date
@param DateTime|string $dateEnd        The end date
@param string          $differenceUnit (optional) Unit of date difference. One of this class
DATE_DIFFERENCE_UNIT_* constants. If is set to null all units are
returned in the array.
@return array|int
Returns difference between given dates .