isEqualTo($startWorkday)) { throw new \InvalidArgumentException("Start and end workday must be different"); } $workDuration = $duration; $endDuration = Duration::zero(); $workDaySeconds = $endWorkday->toSecondOfDay() - $startWorkday->toSecondOfDay(); // handle first day $startDateTime = \DateTimeImmutable::createFromInterface($startTime)->setTime($startWorkday->getHour(), $startWorkday->getMinute()); $availSecondsFirstDay = $workDaySeconds - ($startTime->getTimestamp() - $startDateTime->getTimestamp()); if ($availSecondsFirstDay >= $workDuration->toSeconds()) { // first day is enough time $endDuration->plusSeconds($workDaySeconds - $availSecondsFirstDay); return new DurationConvertorResult( false, $endDuration->plusSeconds($workDuration->toSeconds()) ); } else { $workDuration = $workDuration->minusSeconds($availSecondsFirstDay); $endDuration = $endDuration->plus(Duration::ofDays(1)); } while ($workDuration->toSeconds() > $workDaySeconds) { $endDuration = $endDuration->plus(Duration::ofDays(1)); $workDuration = $workDuration->minusSeconds($workDaySeconds); } return new DurationConvertorResult( true, $endDuration->plus($workDuration) ); } }