feat: RainCalculator with timezone-aware day mapping and month total

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-11 14:37:06 +02:00
co-authored by Claude Fable 5.1
parent 12f5f97a53
commit d657fd069f
6 changed files with 252 additions and 1 deletions
+65
View File
@@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace Weerscherm;
/**
* Berekent regen vandaag, de 3 vorige dagen en het maandtotaal uit een Netatmo getmeasure-body
* (scale=1day, type=sum_rain, optimize=false): een map van unix-timestamp naar [mm].
*
* Elke timestamp wordt gekoppeld aan een lokale datum in de tijdzone van $now. Bij real_time=false
* liggen de timestamps van dagwaarden niet op middernacht, dus daar wordt niet van uitgegaan.
*/
final class RainCalculator
{
private const PREVIOUS_DAYS = 3;
/** 00:00 lokale tijd van min(1e van de maand, vandaag − 3 dagen). */
public static function dateBegin(\DateTimeImmutable $now): \DateTimeImmutable
{
$midnight = $now->setTime(0, 0, 0);
$firstOfMonth = $midnight->setDate((int) $now->format('Y'), (int) $now->format('n'), 1);
$threeDaysAgo = $midnight->modify('-' . self::PREVIOUS_DAYS . ' days');
return $firstOfMonth < $threeDaysAgo ? $firstOfMonth : $threeDaysAgo;
}
/**
* @param array<string|int, mixed> $body
* @return array{today: ?float, previous_days: list<array{date: string, mm: ?float}>, month_total: ?float}
*/
public static function compute(array $body, \DateTimeImmutable $now, ?float $sumRain24): array
{
$tz = $now->getTimezone();
$perDate = [];
foreach ($body as $timestamp => $values) {
if (!is_numeric($timestamp) || !is_array($values) || !isset($values[0]) || !is_numeric($values[0])) {
continue;
}
$date = (new \DateTimeImmutable('@' . (int) $timestamp))->setTimezone($tz)->format('Y-m-d');
$perDate[$date] = ($perDate[$date] ?? 0.0) + (float) $values[0];
}
$today = $now->format('Y-m-d');
$previous = [];
for ($i = self::PREVIOUS_DAYS; $i >= 1; $i--) {
$date = $now->modify("-$i days")->format('Y-m-d');
$previous[] = ['date' => $date, 'mm' => $perDate[$date] ?? null];
}
$monthPrefix = $now->format('Y-m') . '-';
$monthTotal = null;
foreach ($perDate as $date => $mm) {
if (str_starts_with($date, $monthPrefix) && $date <= $today) {
$monthTotal = ($monthTotal ?? 0.0) + $mm;
}
}
return [
'today' => $perDate[$today] ?? $sumRain24,
'previous_days' => $previous,
'month_total' => $monthTotal,
];
}
}