Add sun constellation changes page
This commit is contained in:
@@ -44,6 +44,10 @@
|
|||||||
"label": "Planetensichtbarkeit",
|
"label": "Planetensichtbarkeit",
|
||||||
"menu_group": "Himmel & Planeten"
|
"menu_group": "Himmel & Planeten"
|
||||||
},
|
},
|
||||||
|
"sonnensternbilder.php": {
|
||||||
|
"label": "Sonne in Sternbildern",
|
||||||
|
"menu_group": "Himmel & Planeten"
|
||||||
|
},
|
||||||
"ephemeriden.php": {
|
"ephemeriden.php": {
|
||||||
"label": "Ephemeriden",
|
"label": "Ephemeriden",
|
||||||
"menu_group": "Himmel & Planeten"
|
"menu_group": "Himmel & Planeten"
|
||||||
@@ -132,6 +136,7 @@
|
|||||||
"links": [
|
"links": [
|
||||||
"moonphase.php",
|
"moonphase.php",
|
||||||
"planetensichtbarkeit.php",
|
"planetensichtbarkeit.php",
|
||||||
|
"sonnensternbilder.php",
|
||||||
"ephemeriden.php",
|
"ephemeriden.php",
|
||||||
"comets.php",
|
"comets.php",
|
||||||
"astronomical_conversions.php",
|
"astronomical_conversions.php",
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ function manageablePublicPages(): array
|
|||||||
'my_favorites.php' => 'Favoriten',
|
'my_favorites.php' => 'Favoriten',
|
||||||
'moonphase.php' => 'Mondphase',
|
'moonphase.php' => 'Mondphase',
|
||||||
'planetensichtbarkeit.php' => 'Planetensichtbarkeit',
|
'planetensichtbarkeit.php' => 'Planetensichtbarkeit',
|
||||||
|
'sonnensternbilder.php' => 'Sonne in Sternbildern',
|
||||||
'ephemeriden.php' => 'Ephemeriden',
|
'ephemeriden.php' => 'Ephemeriden',
|
||||||
'comets.php' => 'Kometen',
|
'comets.php' => 'Kometen',
|
||||||
'astronomical_conversions.php' => 'Astronomical Conversions',
|
'astronomical_conversions.php' => 'Astronomical Conversions',
|
||||||
|
|||||||
@@ -872,6 +872,55 @@ footer a:hover { color: var(--gold); }
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- Sonne in Sternbildern -------------------------------- */
|
||||||
|
|
||||||
|
.sun-constellations-tool {
|
||||||
|
max-width: 1100px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sun-constellations-form {
|
||||||
|
display: flex;
|
||||||
|
align-items: end;
|
||||||
|
gap: 0.75rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sun-constellations-form label {
|
||||||
|
color: var(--text-dim);
|
||||||
|
font-size: 0.82rem;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sun-constellations-form input {
|
||||||
|
width: 7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sun-constellations-table-wrap {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sun-constellations-table td:nth-child(2),
|
||||||
|
.sun-constellations-table td:nth-child(3),
|
||||||
|
.sun-constellations-table td:nth-child(4),
|
||||||
|
.sun-constellations-table td:nth-child(5),
|
||||||
|
.sun-constellations-table td:nth-child(6),
|
||||||
|
.sun-constellations-table td:nth-child(7) {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 560px) {
|
||||||
|
.sun-constellations-form {
|
||||||
|
align-items: stretch;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sun-constellations-form label {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.msg-error pre {
|
.msg-error pre {
|
||||||
margin-top: 0.75rem;
|
margin-top: 0.75rem;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ $menuGroups = [
|
|||||||
'title' => 'Planeten & Sonnensystem',
|
'title' => 'Planeten & Sonnensystem',
|
||||||
'links' => [
|
'links' => [
|
||||||
['href' => 'planetensichtbarkeit.php', 'label' => 'Planetensichtbarkeit'],
|
['href' => 'planetensichtbarkeit.php', 'label' => 'Planetensichtbarkeit'],
|
||||||
|
['href' => 'sonnensternbilder.php', 'label' => 'Sonne in Sternbildern'],
|
||||||
['href' => 'ephemeriden.php', 'label' => 'Ephemeriden'],
|
['href' => 'ephemeriden.php', 'label' => 'Ephemeriden'],
|
||||||
['href' => 'solarsystem.php', 'label' => 'Sonnensystem'],
|
['href' => 'solarsystem.php', 'label' => 'Sonnensystem'],
|
||||||
['href' => 'barycenter.php', 'label' => 'Baryzentrum'],
|
['href' => 'barycenter.php', 'label' => 'Baryzentrum'],
|
||||||
|
|||||||
+139
-2
@@ -2174,6 +2174,138 @@ def action_planet_constellation_changes_for_month(args: list[str]) -> dict:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def action_sun_constellation_changes_for_year(args: list[str]) -> dict:
|
||||||
|
if len(args) != 2:
|
||||||
|
fail(
|
||||||
|
"Aktion sun_constellation_changes_for_year erwartet 2 Argumente: year timezone",
|
||||||
|
extra={"argv": args},
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
year = int(args[0])
|
||||||
|
except ValueError as exc:
|
||||||
|
fail("Jahr ist ungueltig.", extra={"details": str(exc), "argv": args})
|
||||||
|
|
||||||
|
if year < 1600 or year > 2200:
|
||||||
|
fail("Jahr muss zwischen 1600 und 2200 liegen.", extra={"year": year})
|
||||||
|
|
||||||
|
timezone_name = args[1]
|
||||||
|
try:
|
||||||
|
tz = ZoneInfo(timezone_name)
|
||||||
|
except Exception as exc:
|
||||||
|
fail("Zeitzone ist ungueltig oder auf dem Server nicht verfuegbar.", extra={"details": str(exc)})
|
||||||
|
|
||||||
|
local_start = datetime(year, 1, 1, 0, 0, 0, tzinfo=tz)
|
||||||
|
local_end = datetime(year + 1, 1, 1, 0, 0, 0, tzinfo=tz)
|
||||||
|
utc_start = local_start.astimezone(timezone.utc)
|
||||||
|
utc_end = local_end.astimezone(timezone.utc)
|
||||||
|
|
||||||
|
constellation_names = {
|
||||||
|
"Aries": "Widder",
|
||||||
|
"Taurus": "Stier",
|
||||||
|
"Gemini": "Zwillinge",
|
||||||
|
"Cancer": "Krebs",
|
||||||
|
"Leo": "Löwe",
|
||||||
|
"Virgo": "Jungfrau",
|
||||||
|
"Libra": "Waage",
|
||||||
|
"Scorpius": "Skorpion",
|
||||||
|
"Sagittarius": "Schütze",
|
||||||
|
"Capricornus": "Steinbock",
|
||||||
|
"Aquarius": "Wassermann",
|
||||||
|
"Pisces": "Fische",
|
||||||
|
"Ophiuchus": "Schlangenträger",
|
||||||
|
"Cetus": "Walfisch",
|
||||||
|
}
|
||||||
|
|
||||||
|
def display_constellation_name(info: astronomy.ConstellationInfo) -> str:
|
||||||
|
return constellation_names.get(info.name, info.name)
|
||||||
|
|
||||||
|
def refine_change_time(left_utc: datetime, right_utc: datetime, left_symbol: str) -> datetime:
|
||||||
|
left = left_utc
|
||||||
|
right = right_utc
|
||||||
|
for _ in range(40):
|
||||||
|
mid = left + (right - left) / 2
|
||||||
|
if body_constellation_info(astronomy.Body.Sun, mid).symbol == left_symbol:
|
||||||
|
left = mid
|
||||||
|
else:
|
||||||
|
right = mid
|
||||||
|
return right
|
||||||
|
|
||||||
|
events: list[dict] = []
|
||||||
|
intervals: list[dict] = []
|
||||||
|
interval_start_utc = utc_start
|
||||||
|
left_utc = utc_start
|
||||||
|
left_info = body_constellation_info(astronomy.Body.Sun, left_utc)
|
||||||
|
scan_step = timedelta(hours=12)
|
||||||
|
|
||||||
|
while left_utc < utc_end:
|
||||||
|
current_utc = min(utc_end, left_utc + scan_step)
|
||||||
|
current_info = body_constellation_info(astronomy.Body.Sun, current_utc)
|
||||||
|
if current_info.symbol == left_info.symbol:
|
||||||
|
left_utc = current_utc
|
||||||
|
left_info = current_info
|
||||||
|
continue
|
||||||
|
|
||||||
|
change_utc = refine_change_time(left_utc, current_utc, left_info.symbol)
|
||||||
|
before_info = body_constellation_info(astronomy.Body.Sun, change_utc - timedelta(seconds=1))
|
||||||
|
after_info = body_constellation_info(astronomy.Body.Sun, change_utc)
|
||||||
|
change_local = change_utc.astimezone(tz)
|
||||||
|
interval_start_local = interval_start_utc.astimezone(tz)
|
||||||
|
|
||||||
|
intervals.append({
|
||||||
|
"constellation_symbol": before_info.symbol,
|
||||||
|
"constellation_name": display_constellation_name(before_info),
|
||||||
|
"start_local_iso": interval_start_local.isoformat(),
|
||||||
|
"start_local_date": interval_start_local.strftime("%d.%m.%Y"),
|
||||||
|
"start_local_time": interval_start_local.strftime("%H:%M"),
|
||||||
|
"end_local_iso": change_local.isoformat(),
|
||||||
|
"end_local_date": change_local.strftime("%d.%m.%Y"),
|
||||||
|
"end_local_time": change_local.strftime("%H:%M"),
|
||||||
|
"duration_days": round((change_utc - interval_start_utc).total_seconds() / 86400.0, 2),
|
||||||
|
})
|
||||||
|
events.append({
|
||||||
|
"from_constellation_symbol": before_info.symbol,
|
||||||
|
"from_constellation_name": display_constellation_name(before_info),
|
||||||
|
"to_constellation_symbol": after_info.symbol,
|
||||||
|
"to_constellation_name": display_constellation_name(after_info),
|
||||||
|
"utc_iso": change_utc.isoformat().replace("+00:00", "Z"),
|
||||||
|
"local_iso": change_local.isoformat(),
|
||||||
|
"local_date": change_local.strftime("%d.%m.%Y"),
|
||||||
|
"local_time": change_local.strftime("%H:%M"),
|
||||||
|
})
|
||||||
|
|
||||||
|
interval_start_utc = change_utc
|
||||||
|
left_utc = change_utc + timedelta(seconds=1)
|
||||||
|
left_info = body_constellation_info(astronomy.Body.Sun, left_utc)
|
||||||
|
|
||||||
|
interval_start_local = interval_start_utc.astimezone(tz)
|
||||||
|
end_info = body_constellation_info(astronomy.Body.Sun, utc_end - timedelta(seconds=1))
|
||||||
|
intervals.append({
|
||||||
|
"constellation_symbol": end_info.symbol,
|
||||||
|
"constellation_name": display_constellation_name(end_info),
|
||||||
|
"start_local_iso": interval_start_local.isoformat(),
|
||||||
|
"start_local_date": interval_start_local.strftime("%d.%m.%Y"),
|
||||||
|
"start_local_time": interval_start_local.strftime("%H:%M"),
|
||||||
|
"end_local_iso": local_end.isoformat(),
|
||||||
|
"end_local_date": local_end.strftime("%d.%m.%Y"),
|
||||||
|
"end_local_time": local_end.strftime("%H:%M"),
|
||||||
|
"duration_days": round((utc_end - interval_start_utc).total_seconds() / 86400.0, 2),
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
"ok": True,
|
||||||
|
"action": "sun_constellation_changes_for_year",
|
||||||
|
"selected": {
|
||||||
|
"year": year,
|
||||||
|
"timezone": timezone_name,
|
||||||
|
"local_start": local_start.isoformat(),
|
||||||
|
"local_end": local_end.isoformat(),
|
||||||
|
},
|
||||||
|
"events": events,
|
||||||
|
"intervals": intervals,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def action_month_sky_context(args: list[str]) -> dict:
|
def action_month_sky_context(args: list[str]) -> dict:
|
||||||
if len(args) != 8:
|
if len(args) != 8:
|
||||||
fail(
|
fail(
|
||||||
@@ -5925,7 +6057,7 @@ def action_barycenter(args: list[str]) -> dict:
|
|||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
fail("Es wurde keine Aktion uebergeben.", extra={"available_actions": ["sun_moon_rise_set", "solar_longitude_to_datetime", "current_solar_longitude", "astronomical_conversions", "comet_brightnesses", "favorite_comet_events_for_month", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "planet_ephemeris", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "moon_deep_sky_approaches_for_month", "planet_bright_star_approaches_for_month", "golden_gate_of_ecliptic_for_month", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "jupiter_moons_one_side_for_month", "mercury_good_visibility_for_month", "planet_parades_for_month", "planet_constellation_changes_for_month", "moon_star_occultations_for_month"]})
|
fail("Es wurde keine Aktion uebergeben.", extra={"available_actions": ["sun_moon_rise_set", "solar_longitude_to_datetime", "current_solar_longitude", "astronomical_conversions", "comet_brightnesses", "favorite_comet_events_for_month", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "planet_ephemeris", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "moon_deep_sky_approaches_for_month", "planet_bright_star_approaches_for_month", "golden_gate_of_ecliptic_for_month", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "jupiter_moons_one_side_for_month", "mercury_good_visibility_for_month", "planet_parades_for_month", "planet_constellation_changes_for_month", "sun_constellation_changes_for_year", "moon_star_occultations_for_month"]})
|
||||||
|
|
||||||
action = sys.argv[1]
|
action = sys.argv[1]
|
||||||
args = sys.argv[2:]
|
args = sys.argv[2:]
|
||||||
@@ -6100,6 +6232,11 @@ def main() -> None:
|
|||||||
print(json.dumps(result, ensure_ascii=True))
|
print(json.dumps(result, ensure_ascii=True))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if action == "sun_constellation_changes_for_year":
|
||||||
|
result = action_sun_constellation_changes_for_year(args)
|
||||||
|
print(json.dumps(result, ensure_ascii=True))
|
||||||
|
return
|
||||||
|
|
||||||
if action == "moon_star_occultations_for_month":
|
if action == "moon_star_occultations_for_month":
|
||||||
result = action_moon_star_occultations_for_month(args)
|
result = action_moon_star_occultations_for_month(args)
|
||||||
print(json.dumps(result, ensure_ascii=True))
|
print(json.dumps(result, ensure_ascii=True))
|
||||||
@@ -6115,7 +6252,7 @@ def main() -> None:
|
|||||||
print(json.dumps(result, ensure_ascii=True))
|
print(json.dumps(result, ensure_ascii=True))
|
||||||
return
|
return
|
||||||
|
|
||||||
fail("Unbekannte Aktion.", extra={"action": action, "available_actions": ["sun_moon_rise_set", "solar_longitude_to_datetime", "current_solar_longitude", "astronomical_conversions", "twilight_chart", "comet_brightnesses", "favorite_comet_events_for_month", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "planet_ephemeris", "planet_visibility_chart", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "moon_deep_sky_approaches_for_month", "planet_bright_star_approaches_for_month", "golden_gate_of_ecliptic_for_month", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "jupiter_moons_one_side_for_month", "mercury_good_visibility_for_month", "planet_parades_for_month", "planet_constellation_changes_for_month", "moon_star_occultations_for_month"]})
|
fail("Unbekannte Aktion.", extra={"action": action, "available_actions": ["sun_moon_rise_set", "solar_longitude_to_datetime", "current_solar_longitude", "astronomical_conversions", "twilight_chart", "comet_brightnesses", "favorite_comet_events_for_month", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "planet_ephemeris", "planet_visibility_chart", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "moon_deep_sky_approaches_for_month", "planet_bright_star_approaches_for_month", "golden_gate_of_ecliptic_for_month", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "jupiter_moons_one_side_for_month", "mercury_good_visibility_for_month", "planet_parades_for_month", "planet_constellation_changes_for_month", "sun_constellation_changes_for_year", "moon_star_occultations_for_month"]})
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
require_once __DIR__ . '/python_api.php';
|
||||||
|
|
||||||
|
$pageTitle = 'Sonne in Sternbildern - AstroTools';
|
||||||
|
$bodyClass = 'sun-constellations-page';
|
||||||
|
|
||||||
|
function h(string $value): string
|
||||||
|
{
|
||||||
|
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
|
||||||
|
}
|
||||||
|
|
||||||
|
$timezoneName = 'Europe/Berlin';
|
||||||
|
$currentYear = (int) (new DateTimeImmutable('now', new DateTimeZone($timezoneName)))->format('Y');
|
||||||
|
$selectedYear = filter_input(INPUT_GET, 'year', FILTER_VALIDATE_INT);
|
||||||
|
if ($selectedYear === false || $selectedYear === null || $selectedYear < 1600 || $selectedYear > 2200) {
|
||||||
|
$selectedYear = $currentYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
<?php require __DIR__ . '/header.php'; ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$pythonResult = runPythonApi('sun_constellation_changes_for_year', [(string) $selectedYear, $timezoneName]);
|
||||||
|
$result = $pythonResult['ok'] ? $pythonResult['data'] : null;
|
||||||
|
$intervals = is_array($result['intervals'] ?? null) ? $result['intervals'] : [];
|
||||||
|
$events = is_array($result['events'] ?? null) ? $result['events'] : [];
|
||||||
|
$displayTimezone = new DateTimeZone($timezoneName);
|
||||||
|
$intervalsByStart = [];
|
||||||
|
foreach ($intervals as $interval) {
|
||||||
|
$startIso = (string) ($interval['start_local_iso'] ?? '');
|
||||||
|
if ($startIso !== '') {
|
||||||
|
$intervalsByStart[$startIso] = $interval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$astrologicalStarts = [
|
||||||
|
'Steinbock' => [$selectedYear - 1, 12, 22],
|
||||||
|
'Wassermann' => [$selectedYear, 1, 20],
|
||||||
|
'Fische' => [$selectedYear, 2, 19],
|
||||||
|
'Widder' => [$selectedYear, 3, 21],
|
||||||
|
'Stier' => [$selectedYear, 4, 20],
|
||||||
|
'Zwillinge' => [$selectedYear, 5, 21],
|
||||||
|
'Krebs' => [$selectedYear, 6, 21],
|
||||||
|
'Löwe' => [$selectedYear, 7, 23],
|
||||||
|
'Jungfrau' => [$selectedYear, 8, 23],
|
||||||
|
'Waage' => [$selectedYear, 9, 23],
|
||||||
|
'Skorpion' => [$selectedYear, 10, 23],
|
||||||
|
'Schütze' => [$selectedYear, 11, 22],
|
||||||
|
];
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main class="sun-constellations-tool">
|
||||||
|
<section class="card sun-constellations-card">
|
||||||
|
<form class="sun-constellations-form" method="get">
|
||||||
|
<label for="year">Jahr</label>
|
||||||
|
<input id="year" name="year" type="number" min="1600" max="2200" value="<?= h((string) $selectedYear) ?>">
|
||||||
|
<button class="btn btn-primary" type="submit">Berechnen</button>
|
||||||
|
</form>
|
||||||
|
<p class="hint">
|
||||||
|
Berechnet werden die offiziellen IAU-Sternbildgrenzen aus geozentrischer Sicht.
|
||||||
|
Der Jahreszeitraum beginnt am 01.01.<?= h((string) $selectedYear) ?> um 00:00 Uhr in Europe/Berlin.
|
||||||
|
Deshalb erscheint auch der Schlangenträger; der klassische Tierkreis mit zwölf Zeichen ist nicht identisch mit den Sternbildern.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<?php if ($result === null): ?>
|
||||||
|
<section class="card msg-error">
|
||||||
|
<h2>Berechnung nicht möglich</h2>
|
||||||
|
<p><?= h((string) ($pythonResult['error'] ?? 'Unbekannter Python-Fehler.')) ?></p>
|
||||||
|
</section>
|
||||||
|
<?php else: ?>
|
||||||
|
<section class="card sun-constellations-card">
|
||||||
|
<h2>Astronomisch und astrologisch</h2>
|
||||||
|
<div class="sun-constellations-table-wrap">
|
||||||
|
<table class="data-table sun-constellations-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Sternbild</th>
|
||||||
|
<th>Wechsel</th>
|
||||||
|
<th>Astrologisch</th>
|
||||||
|
<th>Differenz</th>
|
||||||
|
<th>Von</th>
|
||||||
|
<th>Bis</th>
|
||||||
|
<th>Dauer</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($events as $event): ?>
|
||||||
|
<?php
|
||||||
|
$constellationName = (string) ($event['to_constellation_name'] ?? '');
|
||||||
|
$interval = $intervalsByStart[(string) ($event['local_iso'] ?? '')] ?? [];
|
||||||
|
$astrologicalStart = null;
|
||||||
|
if (isset($astrologicalStarts[$constellationName])) {
|
||||||
|
[$astrologicalYear, $astrologicalMonth, $astrologicalDay] = $astrologicalStarts[$constellationName];
|
||||||
|
$astrologicalStart = new DateTimeImmutable(
|
||||||
|
sprintf('%04d-%02d-%02d 00:00:00', $astrologicalYear, $astrologicalMonth, $astrologicalDay),
|
||||||
|
$displayTimezone
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$astronomicalChange = new DateTimeImmutable((string) ($event['local_iso'] ?? ''), $displayTimezone);
|
||||||
|
$differenceText = '-';
|
||||||
|
if ($astrologicalStart !== null) {
|
||||||
|
$differenceDays = ($astronomicalChange->getTimestamp() - $astrologicalStart->getTimestamp()) / 86400;
|
||||||
|
$differenceText = sprintf('%+.1f Tage', $differenceDays);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><strong><?= h($constellationName) ?></strong></td>
|
||||||
|
<td><?= h((string) ($event['local_date'] ?? '')) ?></td>
|
||||||
|
<td><?= $astrologicalStart === null ? '-' : h($astrologicalStart->format('d.m.Y')) ?></td>
|
||||||
|
<td><?= h($differenceText) ?></td>
|
||||||
|
<td><?= h((string) ($interval['start_local_date'] ?? '')) ?>, <?= h((string) ($interval['start_local_time'] ?? '')) ?> Uhr</td>
|
||||||
|
<td><?= h((string) ($interval['end_local_date'] ?? '')) ?>, <?= h((string) ($interval['end_local_time'] ?? '')) ?> Uhr</td>
|
||||||
|
<td><?= h(number_format((float) ($interval['duration_days'] ?? 0), 1, ',', '.')) ?> Tage</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<?php endif; ?>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<?php require __DIR__ . '/footer.php'; ?>
|
||||||
Reference in New Issue
Block a user