splitIn method
Split the period in multiple periods. The times
is the number of periods
to split the period in.
The periodBetween
is the duration between each period.
The periodBetween
must be greater than or equals to zero and less than
the duration of the period.
The sum of the period between the periods must be less than the duration
of the period.
If the periodBetween
is zero, the periods will be contiguous.
If the periodBetween
is greater than zero, the periods will be
separated by the given duration.
The times
must be greater than zero.
If the times
is one, the period will be returned.
If the times
is greater than one, the period will be split in multiple
periods.
Example:
final period = Period(
start: DateTime(2020, 1, 1),
end: DateTime(2020, 1, 31),
);
final periods = period.splitIn(
3,
periodBetween: Duration(days: 1),
);
// periods = [
// Period(
// start: DateTime(2020, 1, 1),
// end: DateTime(2020, 1, 10, 8),
// ),
// Period(
// start: DateTime(2020, 1, 11, 8),
// end: DateTime(2020, 1, 20, 16),
// ),
// Period(
// start: DateTime(2020, 1, 21, 16),
// end: DateTime(2020, 1, 31),
// ),
// ]
Implementation
List<Period> splitIn(
int times, {
Duration periodBetween = Duration.zero,
}) {
if (times <= 0) {
throw ArgumentError.value(
times,
'times',
'Times must be greater than zero.',
);
}
if ((periodBetween < Duration.zero) || (duration <= periodBetween)) {
throw ArgumentError.value(
periodBetween,
'periodBetween',
'Period between must be greater than or equals to zero and less than '
'the duration of the period.',
);
}
if ((periodBetween * times) > duration) {
throw ArgumentError.value(
times,
'times',
'The sum of the period between dates is greater than the duration of '
'the period.',
);
}
final periods = <Period>[];
final finalBetween = periodBetween * (times - 1);
var fullPeriodDuration = duration - finalBetween;
var rest = fullPeriodDuration.inMicroseconds % times;
while (rest != 0) {
fullPeriodDuration -= const Duration(microseconds: 1);
rest = fullPeriodDuration.inMicroseconds % times;
}
final periodDuration = fullPeriodDuration ~/ times;
for (var i = 0; i < times; i++) {
final start = this.start.add(
(periodDuration * i) + periodBetween * i,
);
var end = this.start.add(
periodDuration * (i + 1) + periodBetween * i,
);
if (i == (times - 1)) end = this.end;
periods.add(Period(start: start, end: end));
}
return periods;
}