This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Belevo\EnelixEMS;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
use InvalidArgumentException;
|
||||
|
||||
final class EinStufigRegler
|
||||
{
|
||||
/**
|
||||
* @return list<int>
|
||||
*/
|
||||
public static function leistungsangebot(
|
||||
int $nennleistung,
|
||||
int $istleistung,
|
||||
bool $verfuegbar,
|
||||
bool $aenderungMoeglich,
|
||||
bool $mindestlaufzeitErzwungen
|
||||
): 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 || $mindestlaufzeitErzwungen) {
|
||||
return [$istleistung];
|
||||
}
|
||||
|
||||
return [0, $nennleistung];
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user