ForecastMapper mapt voortaan index 0 t/m 5 van Open-Meteo (was 1 t/m 5), zodat vandaag als eerste kolom in de verwachtingsstrook verschijnt naast de bestaande 5 dagen erna. Verwachtingskolommen gaan van 5 naar 6 breed (103px i.p.v. 124px), weericoon iets verkleind (58 -> 50px) om te passen. Spec bijgewerkt om de wijziging vast te leggen. Service-worker-versie naar v4 zodat het scherm dit zelf binnen enkele minuten oppikt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
46 lines
1.5 KiB
PHP
46 lines
1.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Weerscherm;
|
|
|
|
/** Zet het "daily"-blok van Open-Meteo om naar 6 dagen, inclusief vandaag (index 0). */
|
|
final class ForecastMapper
|
|
{
|
|
private const DAYS = 6;
|
|
|
|
/**
|
|
* @param array<string, mixed> $daily
|
|
* @return list<array{date: string, weather_code: ?int, temp_max: ?float, temp_min: ?float, precip_mm: ?float, precip_prob: ?int}>
|
|
*/
|
|
public static function map(array $daily): array
|
|
{
|
|
$dates = is_array($daily['time'] ?? null) ? $daily['time'] : [];
|
|
$out = [];
|
|
for ($i = 0; $i < self::DAYS && isset($dates[$i]); $i++) {
|
|
if (!is_string($dates[$i])) {
|
|
continue;
|
|
}
|
|
$out[] = [
|
|
'date' => $dates[$i],
|
|
'weather_code' => self::intOrNull($daily['weather_code'][$i] ?? null),
|
|
'temp_max' => self::floatOrNull($daily['temperature_2m_max'][$i] ?? null),
|
|
'temp_min' => self::floatOrNull($daily['temperature_2m_min'][$i] ?? null),
|
|
'precip_mm' => self::floatOrNull($daily['precipitation_sum'][$i] ?? null),
|
|
'precip_prob' => self::intOrNull($daily['precipitation_probability_max'][$i] ?? null),
|
|
];
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
private static function floatOrNull(mixed $v): ?float
|
|
{
|
|
return is_int($v) || is_float($v) ? (float) $v : null;
|
|
}
|
|
|
|
private static function intOrNull(mixed $v): ?int
|
|
{
|
|
return is_int($v) || is_float($v) ? (int) round($v) : null;
|
|
}
|
|
}
|