periodical method

Iterable<DateTime> periodical(
  1. TimeUnit unit, {
  2. int step = 1,
})

Creates an infinitely long Iterable of periodic DateTime timestamps starting at this DateTime.

The step size is configured using a required TimeUnit unit, and an optional step size that defaults to 1.

To limit the iteration to a specific number of timestamps use Iterable.take; and to limit iteration to a specific end-timestamp use Iterable.takeWhile. For example:

// Enumerate 10 days after September 2, 2017.
DateTime(2017, DateTime.SEPTEMBER, 2).periodical().take(10)

// Enumerate the remaining days in the current year.
final today = DateTime.now();
final nextYear = DateTime(today.year + 1);
today.periodical(period: Period.daily)
    .takeWhile((timestamp) => timestamp.isBefore(nextYear));

Note: Due to leap seconds and daylight saving time, not all periods are of equal length. To produce an infinite sequence of timestamps that are equally spaced, simply use iterate and an offset instead. For example:

final offset = Duration(days: 1);
iterate(DateTime().now(), (prev) => prev.add(offset));

Implementation

Iterable<DateTime> periodical(TimeUnit unit, {int step = 1}) {
  if (step == 0) {
    throw ArgumentError.value(step, 'step', 'Expected non-zero step size');
  }
  switch (unit) {
    case TimeUnit.millennium:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year + 1000 * step,
                prev.month,
                prev.day,
                prev.hour,
                prev.minute,
                prev.second,
                prev.millisecond,
                prev.microsecond,
              ));
    case TimeUnit.century:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year + 100 * step,
                prev.month,
                prev.day,
                prev.hour,
                prev.minute,
                prev.second,
                prev.millisecond,
                prev.microsecond,
              ));
    case TimeUnit.decade:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year + 10 * step,
                prev.month,
                prev.day,
                prev.hour,
                prev.minute,
                prev.second,
                prev.millisecond,
                prev.microsecond,
              ));
    case TimeUnit.year:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year + step,
                prev.month,
                prev.day,
                prev.hour,
                prev.minute,
                prev.second,
                prev.millisecond,
                prev.microsecond,
              ));
    case TimeUnit.quarter:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year,
                prev.month + 3 * step,
                prev.day,
                prev.hour,
                prev.minute,
                prev.second,
                prev.millisecond,
                prev.microsecond,
              ));
    case TimeUnit.month:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year,
                prev.month + step,
                prev.day,
                prev.hour,
                prev.minute,
                prev.second,
                prev.millisecond,
                prev.microsecond,
              ));
    case TimeUnit.week:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year,
                prev.month,
                prev.day + 7 * step,
                prev.hour,
                prev.minute,
                prev.second,
                prev.millisecond,
                prev.microsecond,
              ));
    case TimeUnit.day:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year,
                prev.month,
                prev.day + step,
                prev.hour,
                prev.minute,
                prev.second,
                prev.millisecond,
                prev.microsecond,
              ));
    case TimeUnit.hour:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year,
                prev.month,
                prev.day,
                prev.hour + step,
                prev.minute,
                prev.second,
                prev.millisecond,
                prev.microsecond,
              ));
    case TimeUnit.minute:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year,
                prev.month,
                prev.day,
                prev.hour,
                prev.minute + step,
                prev.second,
                prev.millisecond,
                prev.microsecond,
              ));
    case TimeUnit.second:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year,
                prev.month,
                prev.day,
                prev.hour,
                prev.minute,
                prev.second + step,
                prev.millisecond,
                prev.microsecond,
              ));
    case TimeUnit.millisecond:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year,
                prev.month,
                prev.day,
                prev.hour,
                prev.minute,
                prev.second,
                prev.millisecond + step,
                prev.microsecond,
              ));
    case TimeUnit.microsecond:
      return iterate(
          this,
          (prev) => DateTime(
                prev.year,
                prev.month,
                prev.day,
                prev.hour,
                prev.minute,
                prev.second,
                prev.millisecond,
                prev.microsecond + step,
              ));
  }
}