'Sternwarte Sonneberg', 'latitude' => 50.3547, 'longitude' => 11.1900, 'elevation' => 640.0, 'timezone' => 'Europe/Berlin', ]; $meteorRows = []; $pageError = null; function normalizeMeteorDegree(float $value): float { $normalized = fmod($value, 360.0); if ($normalized < 0.0) { $normalized += 360.0; } return $normalized; } function meteorSolarLongitude(DateTimeImmutable $dateTime): float { $julianDay = ((float) $dateTime->format('U')) / 86400.0 + 2440587.5; $daysSinceJ2000 = $julianDay - 2451545.0; $meanLongitude = normalizeMeteorDegree(280.46 + 0.9856474 * $daysSinceJ2000); $meanAnomalyRad = deg2rad(normalizeMeteorDegree(357.528 + 0.9856003 * $daysSinceJ2000)); return normalizeMeteorDegree( $meanLongitude + 1.915 * sin($meanAnomalyRad) + 0.020 * sin(2.0 * $meanAnomalyRad) ); } function meteorForwardDegreeDistance(float $from, float $to): float { return normalizeMeteorDegree($to - $from); } function meteorRadiantIsVisible(float $latitudeDeg, ?float $declinationDeg): bool { if ($declinationDeg === null) { return false; } return abs($latitudeDeg - $declinationDeg) < 90.0; } function findMeteorSolarLongitudeCrossing( DateTimeImmutable $rangeStartLocal, DateTimeImmutable $rangeEndLocal, float $targetLongitude, DateTimeZone $displayTimezone ): ?DateTimeImmutable { $utc = new DateTimeZone('UTC'); $rangeStartUtc = $rangeStartLocal->setTimezone($utc); $rangeEndUtc = $rangeEndLocal->setTimezone($utc); $startLongitude = meteorSolarLongitude($rangeStartUtc); $endLongitude = meteorSolarLongitude($rangeEndUtc); $targetDelta = meteorForwardDegreeDistance($startLongitude, $targetLongitude); $rangeDelta = meteorForwardDegreeDistance($startLongitude, $endLongitude); if ($targetDelta > $rangeDelta + 0.0001) { return null; } $low = (int) $rangeStartUtc->format('U'); $high = (int) $rangeEndUtc->format('U'); for ($i = 0; $i < 40; $i++) { $mid = (int) floor(($low + $high) / 2); $midLongitude = meteorSolarLongitude(new DateTimeImmutable('@' . $mid)); $midDelta = meteorForwardDegreeDistance($startLongitude, $midLongitude); if ($midDelta < $targetDelta) { $low = $mid; } else { $high = $mid; } } return (new DateTimeImmutable('@' . $high))->setTimezone($displayTimezone); } try { $dbConfig = require __DIR__ . '/../config/database.php'; $dsn = sprintf( 'mysql:host=%s;dbname=%s;charset=%s', $dbConfig['host'], $dbConfig['dbname'], $dbConfig['charset'] ?? 'utf8mb4' ); $pdo = new PDO( $dsn, $dbConfig['user'], $dbConfig['pass'], [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ] ); if ($loggedIn && isset($_SESSION['user_id'])) { $stmtLocation = $pdo->prepare( 'SELECT id, name, latitude, longitude, elevation, timezone FROM app_user_locations WHERE user_id = ? AND is_default = 1 LIMIT 1' ); $stmtLocation->execute([(int) $_SESSION['user_id']]); $userLocation = $stmtLocation->fetch(); if (is_array($userLocation)) { $defaultLocation = $userLocation; $locationIsGlobal = false; } } $stmt = $pdo->query( "SELECT designation, shower_code, radiant_delta_deg, peak_sol, zhr, zhr_variable FROM meteorshowers WHERE peak_sol IS NOT NULL ORDER BY peak_sol ASC, designation ASC" ); $meteorRows = $stmt->fetchAll(); } catch (Throwable $e) { $pageError = $e->getMessage(); } require __DIR__ . '/header.php'; $displayTimezoneName = (string) (($currentLocation['timezone'] ?? null) ?: ($defaultLocation['timezone'] ?? 'Europe/Berlin')); $displayTimezone = new DateTimeZone($displayTimezoneName); $displayLocationName = (string) (($currentLocation['name'] ?? null) ?: ($defaultLocation['name'] ?? 'Sternwarte Sonneberg')); $displayLatitude = isset($currentLocation['latitude']) ? (float) $currentLocation['latitude'] : (float) $defaultLocation['latitude']; $currentYear = (int) (new DateTimeImmutable('now', $displayTimezone))->format('Y'); $yearStart = new DateTimeImmutable(sprintf('%04d-01-01 00:00:00', $currentYear), $displayTimezone); $yearEnd = $yearStart->modify('+1 year'); $meteorEvents = []; foreach ($meteorRows as $row) { if (!is_array($row) || !isset($row['peak_sol'])) { continue; } $peakDateTime = findMeteorSolarLongitudeCrossing( $yearStart, $yearEnd, (float) $row['peak_sol'], $displayTimezone ); if (!$peakDateTime instanceof DateTimeImmutable) { continue; } $visible = meteorRadiantIsVisible( $displayLatitude, $row['radiant_delta_deg'] !== null ? (float) $row['radiant_delta_deg'] : null ); $zhrText = '-'; if ($row['zhr'] !== null && (int) $row['zhr'] >= 0) { $zhrText = 'ca. ' . (int) $row['zhr']; } elseif (trim((string) ($row['zhr_variable'] ?? '')) !== '') { $zhrText = 'ca. ' . trim((string) $row['zhr_variable']); } $meteorEvents[] = [ 'designation' => trim((string) ($row['designation'] ?? '')), 'shower_code' => trim((string) ($row['shower_code'] ?? '')), 'peak' => $peakDateTime, 'visible' => $visible, 'visible_label' => $visible ? 'vom Standort sichtbar' : 'vom Standort nicht sichtbar', 'zhr_text' => $zhrText, ]; } usort( $meteorEvents, static fn (array $a, array $b): int => $a['peak'] <=> $b['peak'] ); ?>

Meteorstroeme

Einfache Jahresliste der Meteorstrom-Maxima fuer in .

Daten konnten nicht geladen werden:
Fuer das aktuelle Jahr wurden keine Meteorstrom-Daten gefunden.
Datum Uhrzeit Meteorstrom Code ZHR Sichtbarkeit
format('d.m.Y'), ENT_QUOTES, 'UTF-8') ?> format('H:i'), ENT_QUOTES, 'UTF-8') ?>