*/ public static function leistungsangebot( int $nennleistung, int $istleistung, bool $verfuegbar, bool $aenderungMoeglich, bool $mindestlaufzeitErzwungen, bool $peakbetrieb, bool $peakSperreBeiMindestlaufzeitAnbieten = true ): array { if ($nennleistung <= 0) { throw new InvalidArgumentException('Die Nennleistung muss groesser als 0 sein.'); } if (!in_array($istleistung, [0, $nennleistung], true)) { throw new InvalidArgumentException('Die Istleistung muss 0 oder der Nennleistung entsprechen.'); } if (!$verfuegbar || !$aenderungMoeglich) { return [$istleistung]; } if ($mindestlaufzeitErzwungen) { return $peakbetrieb && $peakSperreBeiMindestlaufzeitAnbieten ? [0, $nennleistung] : [$nennleistung]; } if ($peakbetrieb) { return [0]; } return [0, $nennleistung]; } public static function freigabezeitpunkt( bool $eingeschaltet, int $bestaetigtSeit, int $mindesteinschaltdauer, int $mindestausschaltdauer ): int { if ($bestaetigtSeit < 0 || $mindesteinschaltdauer < 0 || $mindestausschaltdauer < 0) { throw new InvalidArgumentException('Zeitwerte duerfen nicht negativ sein.'); } return $bestaetigtSeit + ($eingeschaltet ? $mindesteinschaltdauer : $mindestausschaltdauer); } public static function restMindestzeit(int $freigabezeitpunkt, int $jetzt): int { if ($freigabezeitpunkt < 0 || $jetzt < 0) { throw new InvalidArgumentException('Zeitwerte duerfen nicht negativ sein.'); } return max(0, $freigabezeitpunkt - $jetzt); } public static function mussMindestlaufzeitErzwingen( int $tageslaufzeit, int $mindestlaufzeit, int $sekundenBisTagesende ): bool { self::pruefeLaufzeiten($tageslaufzeit, $mindestlaufzeit, $sekundenBisTagesende); $restlaufzeit = max(0, $mindestlaufzeit - $tageslaufzeit); return $restlaufzeit > 0 && $sekundenBisTagesende <= $restlaufzeit; } public static function sekundenBisNaechsteTagespruefung( int $tageslaufzeit, int $mindestlaufzeit, int $sekundenBisTagesende, bool $eingeschaltet ): int { self::pruefeLaufzeiten($tageslaufzeit, $mindestlaufzeit, $sekundenBisTagesende); $restlaufzeit = max(0, $mindestlaufzeit - $tageslaufzeit); if ($restlaufzeit === 0) { return max(1, $sekundenBisTagesende); } if ($eingeschaltet) { return max(1, min($restlaufzeit, $sekundenBisTagesende)); } return max(1, $sekundenBisTagesende - $restlaufzeit); } /** * @return array{Tag: string, Sekunden: int, StandZeit: int} */ public static function aktualisiereTageslaufzeit( string $gespeicherterTag, int $gespeicherteSekunden, int $standZeit, int $jetzt, bool $warEingeschaltet, DateTimeZone $zeitzone ): array { if ($gespeicherteSekunden < 0 || $standZeit < 0 || $jetzt < 0) { throw new InvalidArgumentException('Zeitwerte duerfen nicht negativ sein.'); } $jetztDatum = self::datum($jetzt, $zeitzone); $aktuellerTag = $jetztDatum->format('Y-m-d'); if ($standZeit <= 0 || $standZeit > $jetzt) { return [ 'Tag' => $aktuellerTag, 'Sekunden' => $gespeicherterTag === $aktuellerTag ? $gespeicherteSekunden : 0, 'StandZeit' => $jetzt, ]; } $standDatum = self::datum($standZeit, $zeitzone); $sekunden = $gespeicherteSekunden; if ($gespeicherterTag !== $aktuellerTag || $standDatum->format('Y-m-d') !== $aktuellerTag) { $sekunden = 0; if ($warEingeschaltet) { $tagesbeginn = $jetztDatum->setTime(0, 0)->getTimestamp(); $sekunden = max(0, $jetzt - max($standZeit, $tagesbeginn)); } } elseif ($warEingeschaltet) { $sekunden += $jetzt - $standZeit; } $tagesbeginn = $jetztDatum->setTime(0, 0); $tagesdauer = $tagesbeginn->modify('+1 day')->getTimestamp() - $tagesbeginn->getTimestamp(); return [ 'Tag' => $aktuellerTag, 'Sekunden' => min($sekunden, $tagesdauer), 'StandZeit' => $jetzt, ]; } public static function sekundenBisTagesende(int $jetzt, DateTimeZone $zeitzone): int { if ($jetzt < 0) { throw new InvalidArgumentException('Der Zeitpunkt darf nicht negativ sein.'); } $datum = self::datum($jetzt, $zeitzone); $tagesende = $datum->setTime(0, 0)->modify('+1 day'); return max(1, $tagesende->getTimestamp() - $jetzt); } private static function pruefeLaufzeiten( int $tageslaufzeit, int $mindestlaufzeit, int $sekundenBisTagesende ): void { if ($tageslaufzeit < 0 || $mindestlaufzeit < 0 || $mindestlaufzeit > 86400) { throw new InvalidArgumentException('Laufzeiten sind ausserhalb des gueltigen Bereichs.'); } if ($sekundenBisTagesende <= 0) { throw new InvalidArgumentException('Sekunden bis Tagesende muss groesser als 0 sein.'); } } private static function datum(int $zeitpunkt, DateTimeZone $zeitzone): DateTimeImmutable { return (new DateTimeImmutable('@' . $zeitpunkt))->setTimezone($zeitzone); } }