periodUntil method

Period periodUntil(
  1. HasDate other
)

Finds the Period between this date and another.

It first finds the number of months by advancing the smaller date until it is within 1 month of the larger. Then it finds the number of days between them. The final result is normalized into years, months and days—all positive or all negative.

To count the total number of days between two dates use timespanUntil.

LocalDate(2000, 1, 1).periodUntil(LocalDate(2000, 3, 2)) ==
    Period(months: 2, days: 1);
LocalDate(2000, 3, 2).periodUntil(LocalDate(2000, 1, 1)) ==
    Period(months: -2, days: -1);
LocalDate(2000, 1, 2).periodUntil(LocalDate(2000, 3, 1)) ==
    Period(months: 1, days: 28);
LocalDate(2001, 1, 2).periodUntil(LocalDate(2001, 3, 1)) ==
    Period(months: 1, days: 27);
LocalDate(2000, 1, 1).periodUntil(LocalDate(2010, 2, 3)) ==
    Period(years: 10, months: 1, days: 2);

Implementation

Period periodUntil(HasDate other) {
  var otherDate = LocalDate(other.year, other.month, other.day);
  late int sign;
  late LocalDate d1;
  late LocalDate d2;
  if (otherDate._julianDay.inDays >= _julianDay.inDays) {
    sign = 1;
    d1 = this;
    d2 = otherDate;
  } else {
    sign = -1;
    d1 = otherDate;
    d2 = this;
  }
  var months = _absoluteMonth(d2) - _absoluteMonth(d1);
  if (d1.day <= d2.day) {
    return Period(months: sign * months, days: sign * (d2.day - d1.day))
        .normalize();
  } else {
    --months;
    var advanced = d1.plusPeriod(Period(months: months));
    return Period(
            months: sign * months,
            days: sign *
                (daysInMonth(advanced.year, advanced.month) -
                    advanced.day +
                    d2.day))
        .normalize();
  }
}