🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano
CalendarPeriod — calendar period iteration
⚠️ Entwurfsübersetzung: massgeblich ist die russische Version; der Inhalt unten ist vorerst auf Englisch.
Purpose
A lazy date period with a step (TimeSpan, DateInterval or a string such as 1 month): a generator yields CalendarDate one at a time without materialising the whole range. Parity with CarbonPeriod.
What for and how to use
Calendars, payment schedules, daily/weekly/monthly reports: CalendarPeriod::between($from, $to, '1 week'), bounds via excludingStart()/excludingEnd(), membership via contains().
Example
$period = CalendarPeriod::between(
new DateTimeImmutable('2026-01-01'),
new DateTimeImmutable('2026-03-01'),
'1 month',
)->excludingEnd();
foreach ($period as $date) {
echo $date->format('Y-m-d'); // 2026-01-01, 2026-02-01
}
count($period); // 2
Anti-patterns
A step that does not move the date forward (zero or negative) is rejected with a typed exception — an infinite loop is impossible. For millions of points prefer foreach over toArray().
Lifecycle
stateDiagram-v2
[*] --> Configured: between(start, end, step)
Configured --> Configured: excludingStart() / excludingEnd()
Configured --> Iterating: foreach / count / toArray
Iterating --> Iterating: yield CalendarDate, advance(step)
Iterating --> Failed: step does not progress
Iterating --> [*]: date passes end
Feature comparison with competitors
| Aspect | 🏆 CloudCastle | symfony | carbon | lcobucci | beste | ergebnis |
|---|---|---|---|---|---|---|
| Lazy generator iteration | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| TimeSpan / DateInterval / string step | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Bound inclusion control | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Protection from a non-progressing step | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Immutable period configuration | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Total | 🏆 5 | 0 | 4 | 0 | 0 | 0 |
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano