12 || $dayValue <= 0) { return null; } $day = (int) floor($dayValue); if ($day < 1 || $day > 31) { return null; } $fractionalDay = $dayValue - $day; $seconds = (int) round($fractionalDay * 86400); try { $date = new DateTimeImmutable(sprintf('%04d-%02d-%02d 00:00:00', $year, $month, $day), new DateTimeZone('UTC')); } catch (Throwable $e) { return null; } return $date->modify(sprintf('+%d seconds', $seconds)); } function classifyOrbitType(string $orbitType): string { return match (strtoupper(trim($orbitType))) { 'P' => 'Periodisch', 'C' => 'Nicht periodisch', 'I' => 'Interstellar', 'D' => 'Verschollen / zerfallen', 'A' => 'Asteroidal', default => trim($orbitType) !== '' ? trim($orbitType) : '-', }; } function estimatePerihelMagnitude(?float $absoluteMagnitudeH, ?float $perihelionDistanceAu): ?float { if ($absoluteMagnitudeH === null || !is_finite($absoluteMagnitudeH) || $perihelionDistanceAu === null || !is_finite($perihelionDistanceAu) || $perihelionDistanceAu <= 0.0) { return null; } $heliocentricDistance = max(0.05, $perihelionDistanceAu); $geocentricDistance = max(0.2, abs(1.0 - $perihelionDistanceAu)); return $absoluteMagnitudeH + (5.0 * log10($geocentricDistance)) + (10.0 * log10($heliocentricDistance)); } $config = require __DIR__ . '/../config/database.php'; $dsn = sprintf( 'mysql:host=%s;dbname=%s;charset=%s', $config['host'], $config['dbname'], $config['charset'] ?? 'utf8mb4' ); $pdo = new PDO( $dsn, $config['user'], $config['pass'], [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ] ); $userId = isset($_SESSION['user_id']) ? (int) $_SESSION['user_id'] : 0; $today = new DateTimeImmutable('today', new DateTimeZone('UTC')); $windowStart = $today->modify('-180 days'); $windowEnd = $today->modify('+365 days'); $queryYearMin = (int) $windowStart->format('Y') - 1; $queryYearMax = (int) $windowEnd->format('Y') + 1; $stmtComets = $pdo->prepare(" SELECT c.*, CASE WHEN auc.`comet_id` IS NULL THEN 0 ELSE 1 END AS `is_tracked`, CASE WHEN auc.`is_favorite` = 1 THEN 1 ELSE 0 END AS `is_favorite` FROM `comets_mpc` c LEFT JOIN `app_user_comets` auc ON auc.`comet_id` = c.`id` AND auc.`user_id` = :user_id WHERE c.`year_of_perihelion` BETWEEN :year_min AND :year_max OR auc.`comet_id` IS NOT NULL ORDER BY c.`year_of_perihelion` ASC, c.`month_of_perihelion` ASC, c.`day_of_perihelion` ASC, c.`designation_and_name` ASC "); $stmtComets->execute([ ':user_id' => $userId, ':year_min' => $queryYearMin, ':year_max' => $queryYearMax, ]); $allComets = []; $trackedComets = []; $interestingComets = []; foreach ($stmtComets as $row) { $perihelionDate = buildPerihelionDate($row); $daysFromToday = $perihelionDate ? (int) floor(($perihelionDate->getTimestamp() - $today->getTimestamp()) / 86400) : null; $row['perihelion_date_object'] = $perihelionDate; $row['perihelion_date_display'] = $perihelionDate ? $perihelionDate->setTimezone(new DateTimeZone('Europe/Berlin'))->format('d.m.Y H:i') . ' UTC' : '-'; $row['days_from_today'] = $daysFromToday; $row['orbit_type_label'] = classifyOrbitType((string) ($row['orbit_type'] ?? '')); $row['absolute_magnitude_display'] = isset($row['absolute_magnitude_h']) && $row['absolute_magnitude_h'] !== null ? formatDecimalGerman((float) $row['absolute_magnitude_h'], 1) : '-'; $row['slope_parameter_display'] = isset($row['slope_parameter_g']) && $row['slope_parameter_g'] !== null ? formatDecimalGerman((float) $row['slope_parameter_g'], 1) : '-'; $row['perihelion_dist_display'] = formatDecimalGerman(isset($row['perihelion_dist_au']) ? (float) $row['perihelion_dist_au'] : null, 3); $row['eccentricity_display'] = formatDecimalGerman(isset($row['eccentricity']) ? (float) $row['eccentricity'] : null, 4); $row['inclination_display'] = formatDecimalGerman(isset($row['inclination_deg']) ? (float) $row['inclination_deg'] : null, 2); $estimatedPerihelMagnitude = estimatePerihelMagnitude( isset($row['absolute_magnitude_h']) && $row['absolute_magnitude_h'] !== null ? (float) $row['absolute_magnitude_h'] : null, isset($row['perihelion_dist_au']) && $row['perihelion_dist_au'] !== null ? (float) $row['perihelion_dist_au'] : null ); $row['estimated_perihel_magnitude'] = $estimatedPerihelMagnitude; $row['estimated_perihel_magnitude_display'] = $estimatedPerihelMagnitude !== null ? formatDecimalGerman($estimatedPerihelMagnitude, 1) : '-'; $allComets[] = $row; if ((int) ($row['is_tracked'] ?? 0) === 1) { $trackedComets[] = $row; } if ($perihelionDate !== null && $perihelionDate >= $windowStart && $perihelionDate <= $windowEnd) { $interestingComets[] = $row; } } usort($trackedComets, static function (array $left, array $right): int { $favoriteCompare = ((int) $right['is_favorite']) <=> ((int) $left['is_favorite']); if ($favoriteCompare !== 0) { return $favoriteCompare; } return ((int) ($left['days_from_today'] ?? PHP_INT_MAX)) <=> ((int) ($right['days_from_today'] ?? PHP_INT_MAX)); }); usort($interestingComets, static function (array $left, array $right): int { $leftDistance = abs((int) ($left['days_from_today'] ?? PHP_INT_MAX)); $rightDistance = abs((int) ($right['days_from_today'] ?? PHP_INT_MAX)); if ($leftDistance !== $rightDistance) { return $leftDistance <=> $rightDistance; } return strcmp((string) $left['designation_and_name'], (string) $right['designation_and_name']); }); $interestingComets = array_slice($interestingComets, 0, 24); $orbitTypeCounts = []; foreach ($allComets as $comet) { $orbitKey = (string) ($comet['orbit_type'] ?? '?'); $orbitTypeCounts[$orbitKey] = ($orbitTypeCounts[$orbitKey] ?? 0) + 1; } arsort($orbitTypeCounts); ?>
Diese erste Version liest die vorhandenen Kometen direkt aus comets_mpc und hebt Objekte hervor,
deren Perihel zwischen = h($windowStart->format('d.m.Y')) ?> und
= h($windowEnd->format('d.m.Y')) ?> liegt.
Nutzer-Favoriten aus app_user_comets werden zusaetzlich separat gezeigt.
Die Spalte m grob ist eine sehr einfache Helligkeitsschaetzung nahe dem Perihel
auf Basis von MPC-H und q. Sie ist nur als Orientierung gedacht.
Du hast aktuell noch keine Kometen in deinen Favoriten. In Favoriten kannst du welche markieren.
| Komet | Typ | Perihel | Abstand | m grob |
|---|---|---|---|---|
|
= h((string) $comet['designation_and_name']) ?>
|
= h((string) $comet['orbit_type_label']) ?> | = h((string) $comet['perihelion_date_display']) ?> | = h($daysLabel) ?> | = h((string) $comet['estimated_perihel_magnitude_display']) ?> |
Sortiert nach Naehe zum heutigen Datum bezogen auf den Periheldurchgang.
Im aktuellen Zeitfenster wurden keine Kometen gefunden.
| Komet | Typ | Perihel | Abstand | m grob | H | G |
|---|---|---|---|---|---|---|
|
= h((string) $comet['designation_and_name']) ?>
|
= h((string) $comet['orbit_type_label']) ?> | = h((string) $comet['perihelion_date_display']) ?> | = h($daysLabel) ?> | = h((string) $comet['estimated_perihel_magnitude_display']) ?> | = h((string) $comet['absolute_magnitude_display']) ?> | = h((string) $comet['slope_parameter_display']) ?> |