MonthRange.within constructor

MonthRange.within(
  1. CalendarMonth? min,
  2. CalendarMonth? max,
  3. int length, {
  4. CalendarMonth? tryToStartAt,
})

Create a MonthRange with desired length and (ideally) start, constrained by min and max.

The created range will never start before min or end after max. The length will match length as closely as possible, subject to that constraint. If possible, the range will start at or close to tryToStartAt, but this has the lowest priority.

Throws ArgumentError if length is less than 1, min/max are null, or max is before min.

  • length: int -- Must be at least 1.

Implementation

factory MonthRange.within(CalendarMonth? min, CalendarMonth? max, int length,
    {final CalendarMonth? tryToStartAt}) {
  if (length < 1) {
    throw ArgumentError.value(length, 'length', 'must be at least 1');
  }
  if (min == null) {
    throw ArgumentError.notNull('min');
  }
  if (max == null) {
    throw ArgumentError.notNull('max');
  }

  int months = min.deltaMonths(max) + 1;
  if (months < 1) {
    throw ArgumentError('max must not be before min');
  }

  var start = tryToStartAt?.start ?? min.start;

  // Clamp to maximum possible length
  if (length > months) length = months;

  // Enforce minimum
  if (start < min.start) {
    start = min.start;
  }

  // Enforce maximum (the end cannot go past max)
  var end = start.add(months: length - 1);
  if (end > max.start) {
    start = max.start.add(months: -(length - 1));
  }

  return MonthRange(start, length);
}