PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]); $locationStmt = $pdo->prepare( "SELECT id, name, latitude, longitude, elevation, timezone, is_default FROM app_user_locations WHERE user_id = ? ORDER BY is_default DESC, name ASC, id ASC" ); $locationStmt->execute([(int) $_SESSION['user_id']]); while ($row = $locationStmt->fetch()) { if ($row['latitude'] === null || $row['longitude'] === null) { continue; } $availableLocations[] = [ 'id' => $row['id'] !== null ? (int) $row['id'] : null, 'name' => trim((string) ($row['name'] ?? 'Standort')), 'latitude' => (float) $row['latitude'], 'longitude' => (float) $row['longitude'], 'elevation' => $row['elevation'] !== null ? (float) $row['elevation'] : 0.0, 'timezone' => trim((string) ($row['timezone'] ?? 'Europe/Berlin')), 'is_default' => !empty($row['is_default']), ]; } } catch (Throwable $e) { $availableLocations = []; $pdo = null; } } if ($_SERVER['REQUEST_METHOD'] === 'POST' && (string) ($_POST['ajax'] ?? '') === '1') { header('Content-Type: application/json; charset=utf-8'); $pythonResult = runPythonApiWithJsonPayloadFile('twilight_chart', [ 'latitude' => (float) ($_POST['latitude'] ?? 0), 'longitude' => (float) ($_POST['longitude'] ?? 0), 'timeZone' => trim((string) ($_POST['timeZone'] ?? '')), 'startDate' => trim((string) ($_POST['startDate'] ?? '')), 'endDate' => trim((string) ($_POST['endDate'] ?? '')), ]); if (!$pythonResult['ok']) { echo json_encode([ 'ok' => false, 'error' => (string) ($pythonResult['error'] ?? 'Python-Fehler'), ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } echo json_encode($pythonResult['data'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } require __DIR__ . '/header.php'; $initialLocation = [ 'id' => isset($currentLocation['id']) ? (int) $currentLocation['id'] : null, 'name' => $currentLocation['name'] ?? 'Sternwarte Sonneberg', 'latitude' => isset($currentLocation['latitude']) ? (float) $currentLocation['latitude'] : 50.3597, 'longitude' => isset($currentLocation['longitude']) ? (float) $currentLocation['longitude'] : 11.1907, 'timezone' => $currentLocation['timezone'] ?? 'Europe/Berlin', ]; if (!$availableLocations) { $availableLocations[] = [ 'id' => $initialLocation['id'], 'name' => $initialLocation['name'], 'latitude' => $initialLocation['latitude'], 'longitude' => $initialLocation['longitude'], 'elevation' => isset($currentLocation['elevation']) && $currentLocation['elevation'] !== null ? (float) $currentLocation['elevation'] : 0.0, 'timezone' => $initialLocation['timezone'], 'is_default' => true, ]; } $defaultStartDate = date('Y-01-01'); $defaultEndDate = date('Y-12-31'); ?>
Die Grafik zeigt jeden Tag des gewählten Zeitraums als senkrechte Spur. Von oben nach unten läuft die lokale Uhrzeit des Standorts, farblich getrennt nach Nacht, astronomischer, nautischer und bürgerlicher Dämmerung sowie Tag.
Die Dämmerungsgrenzen werden serverseitig mit Skyfield und lokalen JPL-Ephemeriden berechnet, damit besonders die Übergänge an der astronomischen Dämmerung möglichst präzise bleiben.