/** * Calculates the period between this date and another date. * * This calculates the period between the two dates in terms of years, months and days. * The result will be negative if the end is before the start. * The negative sign will be the same in each of year, month and day. * * The start date is included, but the end date is not. * The period is calculated by removing complete months, then calculating * the remaining number of days, adjusting to ensure that both have the same sign. * The number of months is then normalized into years and months based on a 12 month year. * A month is considered to be complete if the end day-of-month is greater * than or equal to the start day-of-month. * * For example, from `2010-01-15` to `2011-03-18` is 1 year, 2 months and 3 days. * * @param LocalDate $endDateExclusive * * @return Period */ public function until(LocalDate $endDateExclusive) { $totalMonths = $endDateExclusive->getProlepticMonth() - $this->getProlepticMonth(); $days = $endDateExclusive->day - $this->day; if ($totalMonths > 0 && $days < 0) { $totalMonths--; $calcDate = $this->plusMonths($totalMonths); $days = $endDateExclusive->toEpochDay() - $calcDate->toEpochDay(); } elseif ($totalMonths < 0 && $days > 0) { $totalMonths++; $days -= $endDateExclusive->getLengthOfMonth(); } $years = intdiv($totalMonths, 12); $months = $totalMonths % 12; return Period::of($years, $months, $days); }