From ad73f1e5b3777c95573c920d6f2e4d46c5343b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Sat, 4 Apr 2026 10:58:20 +0200 Subject: [PATCH] Gute Merkursichtbarkeit rein --- .codex-temp/php-server.err.log | 549 ++++++++++++++++++++++ public/monatsvorhersage_old.php | 97 ++++ public/py/__pycache__/api.cpython-312.pyc | Bin 142605 -> 155540 bytes public/py/api.py | 309 +++++++++++- todo.md | 5 +- 5 files changed, 954 insertions(+), 6 deletions(-) diff --git a/.codex-temp/php-server.err.log b/.codex-temp/php-server.err.log index e3a9de6..b939a54 100644 --- a/.codex-temp/php-server.err.log +++ b/.codex-temp/php-server.err.log @@ -197,3 +197,552 @@ [Fri Apr 3 18:53:24 2026] [::1]:53603 Accepted [Fri Apr 3 18:53:24 2026] [::1]:53603 [200]: GET /favicon.ico [Fri Apr 3 18:53:24 2026] [::1]:53603 Closing +[Fri Apr 3 18:57:24 2026] [::1]:60801 Accepted +[Fri Apr 3 18:57:25 2026] [::1]:60801 [200]: GET /meteorshowers.php +[Fri Apr 3 18:57:25 2026] [::1]:60801 Closing +[Fri Apr 3 18:57:48 2026] [::1]:58482 Accepted +[Fri Apr 3 18:57:49 2026] [::1]:58482 [200]: GET /index.php +[Fri Apr 3 18:57:49 2026] [::1]:58482 Closing +[Fri Apr 3 18:57:49 2026] [::1]:53042 Accepted +[Fri Apr 3 18:57:49 2026] [::1]:53042 [200]: GET /css/style.css +[Fri Apr 3 18:57:49 2026] [::1]:53042 Closing +[Fri Apr 3 18:57:49 2026] [::1]:61066 Accepted +[Fri Apr 3 18:57:49 2026] [::1]:58923 Accepted +[Fri Apr 3 18:57:49 2026] [::1]:61066 [200]: GET /images/star16x16.png +[Fri Apr 3 18:57:49 2026] [::1]:58923 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 18:57:49 2026] [::1]:61066 Closing +[Fri Apr 3 18:57:49 2026] [::1]:58923 Closing +[Fri Apr 3 18:57:49 2026] [::1]:59332 Accepted +[Fri Apr 3 18:57:50 2026] [::1]:59332 [200]: GET /favicon.ico +[Fri Apr 3 18:57:50 2026] [::1]:59332 Closing +[Fri Apr 3 18:57:51 2026] [::1]:63265 Accepted +[Fri Apr 3 18:57:52 2026] [::1]:63265 [200]: GET /meteorshowers.php +[Fri Apr 3 18:57:52 2026] [::1]:63265 Closing +[Fri Apr 3 18:57:52 2026] [::1]:63533 Accepted +[Fri Apr 3 18:57:52 2026] [::1]:63533 [200]: GET /css/style.css +[Fri Apr 3 18:57:52 2026] [::1]:63533 Closing +[Fri Apr 3 18:57:52 2026] [::1]:50081 Accepted +[Fri Apr 3 18:57:52 2026] [::1]:54913 Accepted +[Fri Apr 3 18:57:52 2026] [::1]:50081 [200]: GET /images/star16x16.png +[Fri Apr 3 18:57:52 2026] [::1]:54913 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 18:57:52 2026] [::1]:50081 Closing +[Fri Apr 3 18:57:52 2026] [::1]:54913 Closing +[Fri Apr 3 18:57:52 2026] [::1]:59072 Accepted +[Fri Apr 3 18:57:52 2026] [::1]:59072 [200]: GET /favicon.ico +[Fri Apr 3 18:57:52 2026] [::1]:59072 Closing +[Fri Apr 3 18:58:19 2026] [::1]:64090 Accepted +[Fri Apr 3 18:58:19 2026] [::1]:64090 [200]: GET /settings.php +[Fri Apr 3 18:58:19 2026] [::1]:64090 Closing +[Fri Apr 3 18:58:19 2026] [::1]:54419 Accepted +[Fri Apr 3 18:58:19 2026] [::1]:54419 [200]: GET /css/style.css +[Fri Apr 3 18:58:19 2026] [::1]:54419 Closing +[Fri Apr 3 18:58:19 2026] [::1]:60884 Accepted +[Fri Apr 3 18:58:19 2026] [::1]:49294 Accepted +[Fri Apr 3 18:58:19 2026] [::1]:60884 [200]: GET /images/star16x16.png +[Fri Apr 3 18:58:19 2026] [::1]:49294 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 18:58:19 2026] [::1]:60884 Closing +[Fri Apr 3 18:58:19 2026] [::1]:49294 Closing +[Fri Apr 3 18:58:20 2026] [::1]:58993 Accepted +[Fri Apr 3 18:58:20 2026] [::1]:58993 [200]: GET /favicon.ico +[Fri Apr 3 18:58:20 2026] [::1]:58993 Closing +[Fri Apr 3 18:58:24 2026] [::1]:56108 Accepted +[Fri Apr 3 18:58:25 2026] [::1]:56108 [200]: POST /settings.php +[Fri Apr 3 18:58:25 2026] [::1]:56108 Closing +[Fri Apr 3 18:58:25 2026] [::1]:49436 Accepted +[Fri Apr 3 18:58:25 2026] [::1]:49436 [200]: GET /css/style.css +[Fri Apr 3 18:58:25 2026] [::1]:49436 Closing +[Fri Apr 3 18:58:25 2026] [::1]:50060 Accepted +[Fri Apr 3 18:58:25 2026] [::1]:52218 Accepted +[Fri Apr 3 18:58:25 2026] [::1]:50060 [200]: GET /images/star16x16.png +[Fri Apr 3 18:58:25 2026] [::1]:52218 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 18:58:25 2026] [::1]:50060 Closing +[Fri Apr 3 18:58:25 2026] [::1]:52218 Closing +[Fri Apr 3 18:58:25 2026] [::1]:54880 Accepted +[Fri Apr 3 18:58:26 2026] [::1]:54880 [200]: GET /favicon.ico +[Fri Apr 3 18:58:26 2026] [::1]:54880 Closing +[Fri Apr 3 18:58:28 2026] [::1]:50962 Accepted +[Fri Apr 3 18:58:28 2026] [::1]:50962 [200]: GET /meteorshowers.php +[Fri Apr 3 18:58:28 2026] [::1]:50962 Closing +[Fri Apr 3 18:58:28 2026] [::1]:49723 Accepted +[Fri Apr 3 18:58:28 2026] [::1]:49723 [200]: GET /css/style.css +[Fri Apr 3 18:58:28 2026] [::1]:49723 Closing +[Fri Apr 3 18:58:28 2026] [::1]:58984 Accepted +[Fri Apr 3 18:58:28 2026] [::1]:56485 Accepted +[Fri Apr 3 18:58:28 2026] [::1]:58984 [200]: GET /images/star16x16.png +[Fri Apr 3 18:58:28 2026] [::1]:56485 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 18:58:28 2026] [::1]:58984 Closing +[Fri Apr 3 18:58:28 2026] [::1]:56485 Closing +[Fri Apr 3 18:58:28 2026] [::1]:50844 Accepted +[Fri Apr 3 18:58:29 2026] [::1]:50844 [200]: GET /favicon.ico +[Fri Apr 3 18:58:29 2026] [::1]:50844 Closing +[Fri Apr 3 19:08:05 2026] [::1]:63421 Accepted +[Fri Apr 3 19:08:11 2026] [::1]:63421 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:08:11 2026] [::1]:63421 Closing +[Fri Apr 3 19:08:20 2026] [::1]:61797 Accepted +[Fri Apr 3 19:08:20 2026] [::1]:61797 [200]: GET /monatsvorhersage.php +[Fri Apr 3 19:08:20 2026] [::1]:61797 Closing +[Fri Apr 3 19:08:20 2026] [::1]:54301 Accepted +[Fri Apr 3 19:08:20 2026] [::1]:54301 [200]: GET /css/style.css +[Fri Apr 3 19:08:20 2026] [::1]:54301 Closing +[Fri Apr 3 19:08:20 2026] [::1]:53037 Accepted +[Fri Apr 3 19:08:20 2026] [::1]:49480 Accepted +[Fri Apr 3 19:08:20 2026] [::1]:53037 [200]: GET /images/star16x16.png +[Fri Apr 3 19:08:20 2026] [::1]:49480 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:08:20 2026] [::1]:53037 Closing +[Fri Apr 3 19:08:20 2026] [::1]:49480 Closing +[Fri Apr 3 19:08:20 2026] [::1]:63715 Accepted +[Fri Apr 3 19:08:21 2026] [::1]:63715 [200]: GET /favicon.ico +[Fri Apr 3 19:08:21 2026] [::1]:63715 Closing +[Fri Apr 3 19:08:24 2026] [::1]:61477 Accepted +[Fri Apr 3 19:08:29 2026] [::1]:61477 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:08:29 2026] [::1]:61477 Closing +[Fri Apr 3 19:08:29 2026] [::1]:57646 Accepted +[Fri Apr 3 19:08:29 2026] [::1]:52815 Accepted +[Fri Apr 3 19:08:29 2026] [::1]:57646 [200]: GET /css/style.css +[Fri Apr 3 19:08:29 2026] [::1]:52815 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:08:29 2026] [::1]:57646 Closing +[Fri Apr 3 19:08:29 2026] [::1]:52815 Closing +[Fri Apr 3 19:08:29 2026] [::1]:63573 Accepted +[Fri Apr 3 19:08:29 2026] [::1]:63053 Accepted +[Fri Apr 3 19:08:29 2026] [::1]:63573 [200]: GET /images/star16x16.png +[Fri Apr 3 19:08:29 2026] [::1]:63053 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:08:29 2026] [::1]:63573 Closing +[Fri Apr 3 19:08:29 2026] [::1]:63053 Closing +[Fri Apr 3 19:08:29 2026] [::1]:54963 Accepted +[Fri Apr 3 19:08:29 2026] [::1]:54963 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 19:08:29 2026] [::1]:54963 Closing +[Fri Apr 3 19:08:29 2026] [::1]:60128 Accepted +[Fri Apr 3 19:08:30 2026] [::1]:60128 [200]: GET /favicon.ico +[Fri Apr 3 19:08:30 2026] [::1]:60128 Closing +[Fri Apr 3 19:08:35 2026] [::1]:60130 Accepted +[Fri Apr 3 19:08:40 2026] [::1]:60130 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:08:40 2026] [::1]:60130 Closing +[Fri Apr 3 19:10:18 2026] [::1]:51297 Accepted +[Fri Apr 3 19:10:24 2026] [::1]:51297 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:10:24 2026] [::1]:51297 Closing +[Fri Apr 3 19:10:25 2026] [::1]:52467 Accepted +[Fri Apr 3 19:10:30 2026] [::1]:52467 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:10:30 2026] [::1]:52467 Closing +[Fri Apr 3 19:10:30 2026] [::1]:57852 Accepted +[Fri Apr 3 19:10:30 2026] [::1]:57852 [200]: GET /css/style.css +[Fri Apr 3 19:10:30 2026] [::1]:62622 Accepted +[Fri Apr 3 19:10:30 2026] [::1]:57852 Closing +[Fri Apr 3 19:10:30 2026] [::1]:62622 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:10:30 2026] [::1]:62622 Closing +[Fri Apr 3 19:10:30 2026] [::1]:57496 Accepted +[Fri Apr 3 19:10:30 2026] [::1]:57496 [200]: GET /images/star16x16.png +[Fri Apr 3 19:10:30 2026] [::1]:57496 Closing +[Fri Apr 3 19:10:30 2026] [::1]:51178 Accepted +[Fri Apr 3 19:10:30 2026] [::1]:51178 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:10:30 2026] [::1]:51178 Closing +[Fri Apr 3 19:10:30 2026] [::1]:56561 Accepted +[Fri Apr 3 19:10:30 2026] [::1]:56561 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 19:10:30 2026] [::1]:56561 Closing +[Fri Apr 3 19:10:31 2026] [::1]:49294 Accepted +[Fri Apr 3 19:10:31 2026] [::1]:49294 [200]: GET /favicon.ico +[Fri Apr 3 19:10:31 2026] [::1]:49294 Closing +[Fri Apr 3 19:13:50 2026] [::1]:63772 Accepted +[Fri Apr 3 19:13:55 2026] [::1]:63772 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:13:55 2026] [::1]:63772 Closing +[Fri Apr 3 19:13:55 2026] [::1]:64089 Accepted +[Fri Apr 3 19:13:55 2026] [::1]:57514 Accepted +[Fri Apr 3 19:13:55 2026] [::1]:64089 [200]: GET /css/style.css +[Fri Apr 3 19:13:55 2026] [::1]:57514 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:13:55 2026] [::1]:64089 Closing +[Fri Apr 3 19:13:55 2026] [::1]:57514 Closing +[Fri Apr 3 19:13:55 2026] [::1]:52083 Accepted +[Fri Apr 3 19:13:55 2026] [::1]:52083 [200]: GET /images/star16x16.png +[Fri Apr 3 19:13:55 2026] [::1]:57803 Accepted +[Fri Apr 3 19:13:55 2026] [::1]:57803 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:13:55 2026] [::1]:52083 Closing +[Fri Apr 3 19:13:55 2026] [::1]:57803 Closing +[Fri Apr 3 19:13:55 2026] [::1]:59010 Accepted +[Fri Apr 3 19:13:55 2026] [::1]:59010 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 19:13:55 2026] [::1]:59010 Closing +[Fri Apr 3 19:13:56 2026] [::1]:64375 Accepted +[Fri Apr 3 19:13:56 2026] [::1]:64375 [200]: GET /favicon.ico +[Fri Apr 3 19:13:56 2026] [::1]:64375 Closing +[Fri Apr 3 19:15:31 2026] [::1]:54019 Accepted +[Fri Apr 3 19:15:36 2026] [::1]:54019 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:15:36 2026] [::1]:54019 Closing +[Fri Apr 3 19:16:08 2026] [::1]:64974 Accepted +[Fri Apr 3 19:16:13 2026] [::1]:64974 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:16:13 2026] [::1]:64974 Closing +[Fri Apr 3 19:16:13 2026] [::1]:49441 Accepted +[Fri Apr 3 19:16:13 2026] [::1]:51970 Accepted +[Fri Apr 3 19:16:13 2026] [::1]:49441 [200]: GET /css/style.css +[Fri Apr 3 19:16:13 2026] [::1]:51970 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:16:13 2026] [::1]:49441 Closing +[Fri Apr 3 19:16:13 2026] [::1]:51970 Closing +[Fri Apr 3 19:16:13 2026] [::1]:59287 Accepted +[Fri Apr 3 19:16:13 2026] [::1]:51598 Accepted +[Fri Apr 3 19:16:13 2026] [::1]:59287 [200]: GET /images/star16x16.png +[Fri Apr 3 19:16:13 2026] [::1]:51598 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:16:13 2026] [::1]:59287 Closing +[Fri Apr 3 19:16:13 2026] [::1]:51598 Closing +[Fri Apr 3 19:16:13 2026] [::1]:49606 Accepted +[Fri Apr 3 19:16:13 2026] [::1]:49606 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 19:16:13 2026] [::1]:49606 Closing +[Fri Apr 3 19:16:13 2026] [::1]:50983 Accepted +[Fri Apr 3 19:16:14 2026] [::1]:50983 [200]: GET /favicon.ico +[Fri Apr 3 19:16:14 2026] [::1]:50983 Closing +[Fri Apr 3 19:16:33 2026] [::1]:49455 Accepted +[Fri Apr 3 19:16:39 2026] [::1]:49455 [200]: GET /monatsvorhersage_old.php?year=2026&month=12 +[Fri Apr 3 19:16:39 2026] [::1]:49455 Closing +[Fri Apr 3 19:16:39 2026] [::1]:52661 Accepted +[Fri Apr 3 19:16:39 2026] [::1]:63304 Accepted +[Fri Apr 3 19:16:39 2026] [::1]:52661 [200]: GET /css/style.css +[Fri Apr 3 19:16:39 2026] [::1]:63304 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:16:39 2026] [::1]:52661 Closing +[Fri Apr 3 19:16:39 2026] [::1]:63304 Closing +[Fri Apr 3 19:16:39 2026] [::1]:56487 Accepted +[Fri Apr 3 19:16:39 2026] [::1]:59433 Accepted +[Fri Apr 3 19:16:39 2026] [::1]:56487 [200]: GET /images/star16x16.png +[Fri Apr 3 19:16:39 2026] [::1]:59433 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:16:39 2026] [::1]:56487 Closing +[Fri Apr 3 19:16:39 2026] [::1]:59433 Closing +[Fri Apr 3 19:16:39 2026] [::1]:57362 Accepted +[Fri Apr 3 19:16:39 2026] [::1]:57362 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 19:16:39 2026] [::1]:57362 Closing +[Fri Apr 3 19:16:39 2026] [::1]:61331 Accepted +[Fri Apr 3 19:16:40 2026] [::1]:61331 [200]: GET /favicon.ico +[Fri Apr 3 19:16:40 2026] [::1]:61331 Closing +[Fri Apr 3 19:27:34 2026] [::1]:53963 Accepted +[Fri Apr 3 19:27:34 2026] [::1]:53963 [200]: GET /meteorshowers.php +[Fri Apr 3 19:27:34 2026] [::1]:53963 Closing +[Fri Apr 3 19:27:34 2026] [::1]:60622 Accepted +[Fri Apr 3 19:27:34 2026] [::1]:60622 [200]: GET /css/style.css +[Fri Apr 3 19:27:34 2026] [::1]:60622 Closing +[Fri Apr 3 19:27:34 2026] [::1]:64705 Accepted +[Fri Apr 3 19:27:34 2026] [::1]:49187 Accepted +[Fri Apr 3 19:27:34 2026] [::1]:64705 [200]: GET /images/star16x16.png +[Fri Apr 3 19:27:34 2026] [::1]:49187 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:27:34 2026] [::1]:64705 Closing +[Fri Apr 3 19:27:34 2026] [::1]:49187 Closing +[Fri Apr 3 19:27:34 2026] [::1]:57972 Accepted +[Fri Apr 3 19:27:35 2026] [::1]:57972 [200]: GET /favicon.ico +[Fri Apr 3 19:27:35 2026] [::1]:57972 Closing +[Fri Apr 3 19:27:47 2026] [::1]:63915 Accepted +[Fri Apr 3 19:27:52 2026] [::1]:63915 [200]: GET /monatsvorhersage.php +[Fri Apr 3 19:27:52 2026] [::1]:63915 Closing +[Fri Apr 3 19:27:52 2026] [::1]:52819 Accepted +[Fri Apr 3 19:27:52 2026] [::1]:52819 [200]: GET /css/style.css +[Fri Apr 3 19:27:52 2026] [::1]:57847 Accepted +[Fri Apr 3 19:27:52 2026] [::1]:52819 Closing +[Fri Apr 3 19:27:52 2026] [::1]:57847 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:27:52 2026] [::1]:57847 Closing +[Fri Apr 3 19:27:52 2026] [::1]:52228 Accepted +[Fri Apr 3 19:27:52 2026] [::1]:53187 Accepted +[Fri Apr 3 19:27:52 2026] [::1]:52228 [200]: GET /images/star16x16.png +[Fri Apr 3 19:27:52 2026] [::1]:53187 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:27:52 2026] [::1]:52228 Closing +[Fri Apr 3 19:27:52 2026] [::1]:53187 Closing +[Fri Apr 3 19:27:52 2026] [::1]:51302 Accepted +[Fri Apr 3 19:27:52 2026] [::1]:51302 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 19:27:52 2026] [::1]:51302 Closing +[Fri Apr 3 19:27:52 2026] [::1]:55608 Accepted +[Fri Apr 3 19:27:53 2026] [::1]:55608 [200]: GET /favicon.ico +[Fri Apr 3 19:27:53 2026] [::1]:55608 Closing +[Fri Apr 3 19:34:18 2026] [::1]:59427 Accepted +[Fri Apr 3 19:34:18 2026] [::1]:59427 [200]: GET /jupitersystem.php +[Fri Apr 3 19:34:18 2026] [::1]:59427 Closing +[Fri Apr 3 19:34:18 2026] [::1]:51539 Accepted +[Fri Apr 3 19:34:18 2026] [::1]:53971 Accepted +[Fri Apr 3 19:34:18 2026] [::1]:51539 [200]: GET /css/style.css +[Fri Apr 3 19:34:18 2026] [::1]:53971 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:34:18 2026] [::1]:51539 Closing +[Fri Apr 3 19:34:18 2026] [::1]:53971 Closing +[Fri Apr 3 19:34:18 2026] [::1]:53017 Accepted +[Fri Apr 3 19:34:18 2026] [::1]:53017 [200]: GET /images/star16x16.png +[Fri Apr 3 19:34:18 2026] [::1]:56923 Accepted +[Fri Apr 3 19:34:18 2026] [::1]:56923 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:34:18 2026] [::1]:53017 Closing +[Fri Apr 3 19:34:18 2026] [::1]:56923 Closing +[Fri Apr 3 19:34:18 2026] [::1]:63438 Accepted +[Fri Apr 3 19:34:18 2026] [::1]:63438 [200]: GET /js/three.module.js +[Fri Apr 3 19:34:18 2026] [::1]:63438 Closing +[Fri Apr 3 19:34:18 2026] [::1]:60150 Accepted +[Fri Apr 3 19:34:18 2026] [::1]:60150 [200]: GET /js/three.core.js +[Fri Apr 3 19:34:18 2026] [::1]:62413 Accepted +[Fri Apr 3 19:34:19 2026] [::1]:62413 [200]: GET /favicon.ico +[Fri Apr 3 19:34:19 2026] [::1]:62413 Closing +[Fri Apr 3 19:34:19 2026] [::1]:60150 Closing +[Fri Apr 3 19:34:19 2026] [::1]:49660 Accepted +[Fri Apr 3 19:34:19 2026] [::1]:49660 [200]: GET /jupitersystem.php?grs_api +[Fri Apr 3 19:34:19 2026] [::1]:49660 Closing +[Fri Apr 3 19:34:19 2026] [::1]:56296 Accepted +[Fri Apr 3 19:34:19 2026] [::1]:56296 [200]: GET /images/planets/jupiter_2048.jpg +[Fri Apr 3 19:34:19 2026] [::1]:49733 Accepted +[Fri Apr 3 19:34:19 2026] [::1]:64045 Accepted +[Fri Apr 3 19:34:19 2026] [::1]:57444 Accepted +[Fri Apr 3 19:34:19 2026] [::1]:49733 [200]: GET /images/moons/io.jpg +[Fri Apr 3 19:34:19 2026] [::1]:64045 [200]: GET /images/moons/europa.jpg +[Fri Apr 3 19:34:19 2026] [::1]:54549 Accepted +[Fri Apr 3 19:34:19 2026] [::1]:57444 [200]: GET /images/moons/ganymede.jpg +[Fri Apr 3 19:34:19 2026] [::1]:54549 [200]: GET /images/moons/callisto.jpg +[Fri Apr 3 19:34:19 2026] [::1]:56296 Closing +[Fri Apr 3 19:34:19 2026] [::1]:49733 Closing +[Fri Apr 3 19:34:19 2026] [::1]:57444 Closing +[Fri Apr 3 19:34:19 2026] [::1]:64045 Closing +[Fri Apr 3 19:34:19 2026] [::1]:54549 Closing +[Fri Apr 3 19:34:26 2026] [::1]:60747 Accepted +[Fri Apr 3 19:34:26 2026] [::1]:60747 [200]: GET /images/logoAM.png +[Fri Apr 3 19:34:26 2026] [::1]:60747 Closing +[Fri Apr 3 19:38:39 2026] [::1]:56708 Accepted +[Fri Apr 3 19:38:44 2026] [::1]:56708 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:38:44 2026] [::1]:56708 Closing +[Fri Apr 3 19:38:50 2026] [::1]:56710 Accepted +[Fri Apr 3 19:38:56 2026] [::1]:56710 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:38:56 2026] [::1]:56710 Closing +[Fri Apr 3 19:40:57 2026] [::1]:59669 Accepted +[Fri Apr 3 19:41:03 2026] [::1]:59669 [200]: GET /monatsvorhersage.php +[Fri Apr 3 19:41:03 2026] [::1]:59669 Closing +[Fri Apr 3 19:41:03 2026] [::1]:50751 Accepted +[Fri Apr 3 19:41:03 2026] [::1]:64367 Accepted +[Fri Apr 3 19:41:03 2026] [::1]:50751 [200]: GET /css/style.css +[Fri Apr 3 19:41:03 2026] [::1]:64367 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:41:03 2026] [::1]:50751 Closing +[Fri Apr 3 19:41:03 2026] [::1]:64367 Closing +[Fri Apr 3 19:41:03 2026] [::1]:54669 Accepted +[Fri Apr 3 19:41:03 2026] [::1]:54669 [200]: GET /images/star16x16.png +[Fri Apr 3 19:41:03 2026] [::1]:63084 Accepted +[Fri Apr 3 19:41:03 2026] [::1]:63084 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:41:03 2026] [::1]:54669 Closing +[Fri Apr 3 19:41:03 2026] [::1]:63084 Closing +[Fri Apr 3 19:41:03 2026] [::1]:57496 Accepted +[Fri Apr 3 19:41:03 2026] [::1]:57496 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 19:41:03 2026] [::1]:57496 Closing +[Fri Apr 3 19:41:03 2026] [::1]:49327 Accepted +[Fri Apr 3 19:41:04 2026] [::1]:49327 [200]: GET /favicon.ico +[Fri Apr 3 19:41:04 2026] [::1]:49327 Closing +[Fri Apr 3 19:41:05 2026] [::1]:59324 Accepted +[Fri Apr 3 19:41:11 2026] [::1]:59324 [200]: GET /monatsvorhersage_old.php +[Fri Apr 3 19:41:11 2026] [::1]:59324 Closing +[Fri Apr 3 19:41:11 2026] [::1]:52808 Accepted +[Fri Apr 3 19:41:11 2026] [::1]:63422 Accepted +[Fri Apr 3 19:41:11 2026] [::1]:52808 [200]: GET /css/style.css +[Fri Apr 3 19:41:11 2026] [::1]:63422 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:41:11 2026] [::1]:52808 Closing +[Fri Apr 3 19:41:11 2026] [::1]:63422 Closing +[Fri Apr 3 19:41:11 2026] [::1]:53705 Accepted +[Fri Apr 3 19:41:11 2026] [::1]:53705 [200]: GET /images/star16x16.png +[Fri Apr 3 19:41:11 2026] [::1]:61313 Accepted +[Fri Apr 3 19:41:11 2026] [::1]:61313 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:41:11 2026] [::1]:53705 Closing +[Fri Apr 3 19:41:11 2026] [::1]:61313 Closing +[Fri Apr 3 19:41:11 2026] [::1]:61457 Accepted +[Fri Apr 3 19:41:11 2026] [::1]:61457 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 19:41:11 2026] [::1]:61457 Closing +[Fri Apr 3 19:41:11 2026] [::1]:61144 Accepted +[Fri Apr 3 19:41:12 2026] [::1]:61144 [200]: GET /favicon.ico +[Fri Apr 3 19:41:12 2026] [::1]:61144 Closing +[Fri Apr 3 19:42:30 2026] [::1]:55014 Accepted +[Fri Apr 3 19:42:36 2026] [::1]:55014 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:42:36 2026] [::1]:55014 Closing +[Fri Apr 3 19:44:26 2026] [::1]:55985 Accepted +[Fri Apr 3 19:44:26 2026] [::1]:55985 [200]: GET /jupitersystem.php +[Fri Apr 3 19:44:26 2026] [::1]:55985 Closing +[Fri Apr 3 19:44:26 2026] [::1]:55563 Accepted +[Fri Apr 3 19:44:26 2026] [::1]:52283 Accepted +[Fri Apr 3 19:44:26 2026] [::1]:55563 [200]: GET /css/style.css +[Fri Apr 3 19:44:26 2026] [::1]:52283 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:44:26 2026] [::1]:55563 Closing +[Fri Apr 3 19:44:26 2026] [::1]:52283 Closing +[Fri Apr 3 19:44:26 2026] [::1]:54539 Accepted +[Fri Apr 3 19:44:26 2026] [::1]:61207 Accepted +[Fri Apr 3 19:44:26 2026] [::1]:54539 [200]: GET /images/star16x16.png +[Fri Apr 3 19:44:26 2026] [::1]:61207 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:44:26 2026] [::1]:54539 Closing +[Fri Apr 3 19:44:26 2026] [::1]:61207 Closing +[Fri Apr 3 19:44:26 2026] [::1]:51376 Accepted +[Fri Apr 3 19:44:26 2026] [::1]:51376 [200]: GET /js/three.module.js +[Fri Apr 3 19:44:26 2026] [::1]:51376 Closing +[Fri Apr 3 19:44:26 2026] [::1]:58649 Accepted +[Fri Apr 3 19:44:26 2026] [::1]:58649 [200]: GET /js/three.core.js +[Fri Apr 3 19:44:26 2026] [::1]:58038 Accepted +[Fri Apr 3 19:44:27 2026] [::1]:58038 [200]: GET /favicon.ico +[Fri Apr 3 19:44:27 2026] [::1]:58038 Closing +[Fri Apr 3 19:44:27 2026] [::1]:58649 Closing +[Fri Apr 3 19:44:27 2026] [::1]:59586 Accepted +[Fri Apr 3 19:44:27 2026] [::1]:59586 [200]: GET /jupitersystem.php?grs_api +[Fri Apr 3 19:44:27 2026] [::1]:59586 Closing +[Fri Apr 3 19:44:27 2026] [::1]:59600 Accepted +[Fri Apr 3 19:44:27 2026] [::1]:59600 [200]: GET /images/planets/jupiter_2048.jpg +[Fri Apr 3 19:44:27 2026] [::1]:49805 Accepted +[Fri Apr 3 19:44:27 2026] [::1]:49805 [200]: GET /images/moons/io.jpg +[Fri Apr 3 19:44:27 2026] [::1]:63920 Accepted +[Fri Apr 3 19:44:27 2026] [::1]:50291 Accepted +[Fri Apr 3 19:44:27 2026] [::1]:49805 Closing +[Fri Apr 3 19:44:27 2026] [::1]:51653 Accepted +[Fri Apr 3 19:44:27 2026] [::1]:63920 [200]: GET /images/moons/europa.jpg +[Fri Apr 3 19:44:27 2026] [::1]:50291 [200]: GET /images/moons/ganymede.jpg +[Fri Apr 3 19:44:27 2026] [::1]:51653 [200]: GET /images/moons/callisto.jpg +[Fri Apr 3 19:44:27 2026] [::1]:50291 Closing +[Fri Apr 3 19:44:27 2026] [::1]:59600 Closing +[Fri Apr 3 19:44:27 2026] [::1]:51653 Closing +[Fri Apr 3 19:44:27 2026] [::1]:63920 Closing +[Fri Apr 3 19:46:27 2026] [::1]:54531 Accepted +[Fri Apr 3 19:46:27 2026] [::1]:54531 [200]: GET /images/logoAM.png +[Fri Apr 3 19:46:27 2026] [::1]:54531 Closing +[Fri Apr 3 19:46:42 2026] [::1]:54533 Accepted +[Fri Apr 3 19:46:48 2026] [::1]:54533 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:46:48 2026] [::1]:54533 Closing +[Fri Apr 3 19:47:05 2026] [::1]:51453 Accepted +[Fri Apr 3 19:47:12 2026] [::1]:51453 [200]: GET /monatsvorhersage_old.php +[Fri Apr 3 19:47:12 2026] [::1]:51453 Closing +[Fri Apr 3 19:47:12 2026] [::1]:63972 Accepted +[Fri Apr 3 19:47:12 2026] [::1]:64765 Accepted +[Fri Apr 3 19:47:12 2026] [::1]:63972 [200]: GET /css/style.css +[Fri Apr 3 19:47:12 2026] [::1]:64765 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:47:12 2026] [::1]:63972 Closing +[Fri Apr 3 19:47:12 2026] [::1]:64765 Closing +[Fri Apr 3 19:47:12 2026] [::1]:64051 Accepted +[Fri Apr 3 19:47:12 2026] [::1]:49245 Accepted +[Fri Apr 3 19:47:12 2026] [::1]:64051 [200]: GET /images/star16x16.png +[Fri Apr 3 19:47:12 2026] [::1]:49245 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:47:12 2026] [::1]:64051 Closing +[Fri Apr 3 19:47:12 2026] [::1]:49245 Closing +[Fri Apr 3 19:47:12 2026] [::1]:51600 Accepted +[Fri Apr 3 19:47:12 2026] [::1]:51600 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 19:47:12 2026] [::1]:51600 Closing +[Fri Apr 3 19:47:12 2026] [::1]:64846 Accepted +[Fri Apr 3 19:47:13 2026] [::1]:64846 [200]: GET /favicon.ico +[Fri Apr 3 19:47:13 2026] [::1]:64846 Closing +[Fri Apr 3 19:54:01 2026] [::1]:52168 Accepted +[Fri Apr 3 19:54:08 2026] [::1]:52168 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:54:08 2026] [::1]:52168 Closing +[Fri Apr 3 19:54:29 2026] [::1]:63821 Accepted +[Fri Apr 3 19:54:35 2026] [::1]:63821 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 19:54:35 2026] [::1]:63821 Closing +[Fri Apr 3 19:55:02 2026] [::1]:64657 Accepted +[Fri Apr 3 19:55:07 2026] [::1]:64657 [200]: GET /monatsvorhersage_old.php +[Fri Apr 3 19:55:07 2026] [::1]:64657 Closing +[Fri Apr 3 19:55:07 2026] [::1]:62611 Accepted +[Fri Apr 3 19:55:07 2026] [::1]:57039 Accepted +[Fri Apr 3 19:55:07 2026] [::1]:62611 [200]: GET /css/style.css +[Fri Apr 3 19:55:07 2026] [::1]:57039 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:55:07 2026] [::1]:62611 Closing +[Fri Apr 3 19:55:07 2026] [::1]:57039 Closing +[Fri Apr 3 19:55:07 2026] [::1]:55565 Accepted +[Fri Apr 3 19:55:07 2026] [::1]:49810 Accepted +[Fri Apr 3 19:55:07 2026] [::1]:55565 [200]: GET /images/star16x16.png +[Fri Apr 3 19:55:07 2026] [::1]:49810 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:55:07 2026] [::1]:55565 Closing +[Fri Apr 3 19:55:07 2026] [::1]:49810 Closing +[Fri Apr 3 19:55:07 2026] [::1]:51843 Accepted +[Fri Apr 3 19:55:07 2026] [::1]:51843 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 19:55:07 2026] [::1]:51843 Closing +[Fri Apr 3 19:55:08 2026] [::1]:64708 Accepted +[Fri Apr 3 19:55:08 2026] [::1]:64708 [200]: GET /favicon.ico +[Fri Apr 3 19:55:08 2026] [::1]:64708 Closing +[Fri Apr 3 19:56:42 2026] [::1]:60236 Accepted +[Fri Apr 3 19:56:47 2026] [::1]:60236 [200]: GET /monatsvorhersage_old.php +[Fri Apr 3 19:56:47 2026] [::1]:60236 Closing +[Fri Apr 3 19:56:47 2026] [::1]:65013 Accepted +[Fri Apr 3 19:56:47 2026] [::1]:65013 [200]: GET /css/style.css +[Fri Apr 3 19:56:47 2026] [::1]:53017 Accepted +[Fri Apr 3 19:56:47 2026] [::1]:65013 Closing +[Fri Apr 3 19:56:47 2026] [::1]:53017 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 19:56:47 2026] [::1]:53017 Closing +[Fri Apr 3 19:56:47 2026] [::1]:59924 Accepted +[Fri Apr 3 19:56:47 2026] [::1]:59924 [200]: GET /images/star16x16.png +[Fri Apr 3 19:56:47 2026] [::1]:56687 Accepted +[Fri Apr 3 19:56:47 2026] [::1]:59924 Closing +[Fri Apr 3 19:56:47 2026] [::1]:56687 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 19:56:47 2026] [::1]:56687 Closing +[Fri Apr 3 19:56:48 2026] [::1]:61438 Accepted +[Fri Apr 3 19:56:48 2026] [::1]:61438 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 19:56:48 2026] [::1]:61438 Closing +[Fri Apr 3 19:56:48 2026] [::1]:60578 Accepted +[Fri Apr 3 19:56:48 2026] [::1]:60578 [200]: GET /favicon.ico +[Fri Apr 3 19:56:48 2026] [::1]:60578 Closing +[Fri Apr 3 20:02:39 2026] [::1]:62230 Accepted +[Fri Apr 3 20:02:45 2026] [::1]:62230 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 20:02:45 2026] [::1]:62230 Closing +[Fri Apr 3 20:02:50 2026] [::1]:63167 Accepted +[Fri Apr 3 20:02:57 2026] [::1]:63167 [200]: GET /monatsvorhersage_old.php +[Fri Apr 3 20:02:57 2026] [::1]:63167 Closing +[Fri Apr 3 20:02:57 2026] [::1]:64749 Accepted +[Fri Apr 3 20:02:57 2026] [::1]:64749 [200]: GET /css/style.css +[Fri Apr 3 20:02:57 2026] [::1]:53760 Accepted +[Fri Apr 3 20:02:57 2026] [::1]:64749 Closing +[Fri Apr 3 20:02:57 2026] [::1]:53760 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 20:02:57 2026] [::1]:53760 Closing +[Fri Apr 3 20:02:57 2026] [::1]:50625 Accepted +[Fri Apr 3 20:02:57 2026] [::1]:56453 Accepted +[Fri Apr 3 20:02:57 2026] [::1]:50625 [200]: GET /images/star16x16.png +[Fri Apr 3 20:02:57 2026] [::1]:56453 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 20:02:57 2026] [::1]:50625 Closing +[Fri Apr 3 20:02:57 2026] [::1]:56453 Closing +[Fri Apr 3 20:02:57 2026] [::1]:50074 Accepted +[Fri Apr 3 20:02:57 2026] [::1]:50074 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 20:02:57 2026] [::1]:50074 Closing +[Fri Apr 3 20:02:57 2026] [::1]:59868 Accepted +[Fri Apr 3 20:02:58 2026] [::1]:59868 [200]: GET /favicon.ico +[Fri Apr 3 20:02:58 2026] [::1]:59868 Closing +[Fri Apr 3 20:02:58 2026] [::1]:52829 Accepted +[Fri Apr 3 20:02:58 2026] [::1]:52829 [200]: GET /jupitersystem.php +[Fri Apr 3 20:02:58 2026] [::1]:52829 Closing +[Fri Apr 3 20:02:58 2026] [::1]:62831 Accepted +[Fri Apr 3 20:02:58 2026] [::1]:62831 [200]: GET /css/style.css +[Fri Apr 3 20:02:58 2026] [::1]:56907 Accepted +[Fri Apr 3 20:02:58 2026] [::1]:56907 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 20:02:58 2026] [::1]:62831 Closing +[Fri Apr 3 20:02:58 2026] [::1]:56907 Closing +[Fri Apr 3 20:02:58 2026] [::1]:50191 Accepted +[Fri Apr 3 20:02:58 2026] [::1]:58317 Accepted +[Fri Apr 3 20:02:58 2026] [::1]:50191 [200]: GET /images/star16x16.png +[Fri Apr 3 20:02:58 2026] [::1]:58317 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 20:02:58 2026] [::1]:50191 Closing +[Fri Apr 3 20:02:58 2026] [::1]:58317 Closing +[Fri Apr 3 20:02:58 2026] [::1]:49612 Accepted +[Fri Apr 3 20:02:58 2026] [::1]:49612 [200]: GET /js/three.module.js +[Fri Apr 3 20:02:58 2026] [::1]:49612 Closing +[Fri Apr 3 20:02:58 2026] [::1]:57626 Accepted +[Fri Apr 3 20:02:58 2026] [::1]:51326 Accepted +[Fri Apr 3 20:02:58 2026] [::1]:51326 [200]: GET /js/three.core.js +[Fri Apr 3 20:02:59 2026] [::1]:57626 [200]: GET /favicon.ico +[Fri Apr 3 20:02:59 2026] [::1]:57626 Closing +[Fri Apr 3 20:02:59 2026] [::1]:51326 Closing +[Fri Apr 3 20:02:59 2026] [::1]:60870 Accepted +[Fri Apr 3 20:02:59 2026] [::1]:60870 [200]: GET /jupitersystem.php?grs_api +[Fri Apr 3 20:02:59 2026] [::1]:60870 Closing +[Fri Apr 3 20:02:59 2026] [::1]:51387 Accepted +[Fri Apr 3 20:02:59 2026] [::1]:50529 Accepted +[Fri Apr 3 20:02:59 2026] [::1]:62844 Accepted +[Fri Apr 3 20:02:59 2026] [::1]:51387 [200]: GET /images/planets/jupiter_2048.jpg +[Fri Apr 3 20:02:59 2026] [::1]:52071 Accepted +[Fri Apr 3 20:02:59 2026] [::1]:50529 [200]: GET /images/moons/io.jpg +[Fri Apr 3 20:02:59 2026] [::1]:62844 [200]: GET /images/moons/europa.jpg +[Fri Apr 3 20:02:59 2026] [::1]:52881 Accepted +[Fri Apr 3 20:02:59 2026] [::1]:52071 [200]: GET /images/moons/ganymede.jpg +[Fri Apr 3 20:02:59 2026] [::1]:52881 [200]: GET /images/moons/callisto.jpg +[Fri Apr 3 20:02:59 2026] [::1]:50529 Closing +[Fri Apr 3 20:02:59 2026] [::1]:52071 Closing +[Fri Apr 3 20:02:59 2026] [::1]:51387 Closing +[Fri Apr 3 20:03:00 2026] [::1]:62844 Closing +[Fri Apr 3 20:03:00 2026] [::1]:52881 Closing +[Fri Apr 3 20:08:07 2026] [::1]:53517 Accepted +[Fri Apr 3 20:08:13 2026] [::1]:53517 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 20:08:13 2026] [::1]:53517 Closing +[Fri Apr 3 20:08:45 2026] [::1]:57076 Accepted +[Fri Apr 3 20:08:51 2026] [::1]:57076 [200]: GET /monatsvorhersage_old.php +[Fri Apr 3 20:08:51 2026] [::1]:57076 Closing +[Fri Apr 3 20:08:51 2026] [::1]:49850 Accepted +[Fri Apr 3 20:08:51 2026] [::1]:49850 [200]: GET /css/style.css +[Fri Apr 3 20:08:51 2026] [::1]:49850 Closing +[Fri Apr 3 20:08:51 2026] [::1]:58903 Accepted +[Fri Apr 3 20:08:51 2026] [::1]:58903 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 20:08:51 2026] [::1]:58903 Closing +[Fri Apr 3 20:08:51 2026] [::1]:63669 Accepted +[Fri Apr 3 20:08:51 2026] [::1]:62908 Accepted +[Fri Apr 3 20:08:51 2026] [::1]:63669 [200]: GET /images/star16x16.png +[Fri Apr 3 20:08:51 2026] [::1]:62908 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 20:08:51 2026] [::1]:63669 Closing +[Fri Apr 3 20:08:51 2026] [::1]:62908 Closing +[Fri Apr 3 20:08:51 2026] [::1]:63413 Accepted +[Fri Apr 3 20:08:51 2026] [::1]:63413 [200]: GET /images/moons/moon4geocron.png +[Fri Apr 3 20:08:51 2026] [::1]:63413 Closing +[Fri Apr 3 20:08:51 2026] [::1]:62755 Accepted +[Fri Apr 3 20:08:52 2026] [::1]:62755 [200]: GET /favicon.ico +[Fri Apr 3 20:08:52 2026] [::1]:62755 Closing diff --git a/public/monatsvorhersage_old.php b/public/monatsvorhersage_old.php index 659d336..927dc6c 100644 --- a/public/monatsvorhersage_old.php +++ b/public/monatsvorhersage_old.php @@ -17,8 +17,26 @@ $starLabelMagnitudeLimit = 2.0; $messierDatabaseMagnitudeLimit = 4.0; $messierDisplayMagnitudeLimit = 1.0; $moonPlanetMaxSeparationDeg = 1.5; +$moonDeepSkyMaxSeparationDeg = 1.0; $planetConjunctionMaxSeparationDeg = 1.0; $moonOccultationMaxMag = 2.0; +// Gute Merkur-Sichtbarkeit wird nicht nur über Elongation, sondern über echte +// Beobachtbarkeit am Himmel definiert: Wir prüfen pro Tag zu einem festen +// Zeitpunkt relativ zu Sonnenauf- oder -untergang, ob Merkur hoch genug steht +// und die Sonne bereits tief genug unter dem Horizont ist. +$mercuryGoodVisibilitySampleOffsetMinutes = 45; +// Morgens: so viele Minuten VOR Sonnenaufgang prüfen. +// Abends: so viele Minuten NACH Sonnenuntergang prüfen. +$mercuryGoodVisibilityMinAltitudeDeg = 7.0; +// Merkur muss bei diesem Prüfzeitpunkt mindestens so hoch über dem Horizont +// stehen, damit wir die Sichtbarkeit als "gut" einstufen. +$mercuryGoodVisibilityMaxSunAltitudeDeg = -3.0; +// Die Sonne muss gleichzeitig mindestens 4 Grad unter dem Horizont stehen. +// So vermeiden wir Treffer, bei denen Merkur zwar formal da ist, aber noch zu +// stark in der hellen Dämmerung untergeht. +$mercuryGoodVisibilityMinConsecutiveDays = 3; +// Einzelne gute Tage sind oft zu zufällig. Erst ab dieser Anzahl +// aufeinanderfolgender Tage erzeugen wir ein Monatsereignis. $years = range($currentYear - 2, $currentYear + 5); $months = [ @@ -59,6 +77,8 @@ $moonData = null; $moonPhaseEvents = []; $goldenHandleEvents = []; $moonPlanetApproaches = []; +$moonDeepSkyApproaches = []; +$mercuryGoodVisibilityEvents = []; $planetConjunctions = []; $eclipseEvents = []; $moonApsisEvents = []; @@ -655,6 +675,27 @@ if (is_array($moonPlanetDecoded) && ($moonPlanetDecoded['ok'] ?? false)) { $moonPlanetApproaches = is_array($moonPlanetDecoded['approaches'] ?? null) ? $moonPlanetDecoded['approaches'] : []; } +$moonDeepSkyOutput = []; +$moonDeepSkyExitCode = 0; +$moonDeepSkyArgs = [ + $pythonScriptPath, + 'moon_deep_sky_approaches_for_month', + (string) $chartLatitude, + (string) $chartLongitude, + (string) $chartElevation, + (string) $selectedYear, + (string) $selectedMonth, + $chartTimezone, + (string) $moonDeepSkyMaxSeparationDeg, +]; +$moonDeepSkyCommand = $pythonExecutable . ' ' . implode(' ', array_map('escapeshellarg', $moonDeepSkyArgs)) . ' 2>&1'; +exec($moonDeepSkyCommand, $moonDeepSkyOutput, $moonDeepSkyExitCode); +$moonDeepSkyRaw = trim(implode("\n", $moonDeepSkyOutput)); +$moonDeepSkyDecoded = json_decode($moonDeepSkyRaw, true); +if (is_array($moonDeepSkyDecoded) && ($moonDeepSkyDecoded['ok'] ?? false)) { + $moonDeepSkyApproaches = is_array($moonDeepSkyDecoded['approaches'] ?? null) ? $moonDeepSkyDecoded['approaches'] : []; +} + $planetConjunctionOutput = []; $planetConjunctionExitCode = 0; $planetConjunctionArgs = [ @@ -676,6 +717,30 @@ if (is_array($planetConjunctionDecoded) && ($planetConjunctionDecoded['ok'] ?? f $planetConjunctions = is_array($planetConjunctionDecoded['conjunctions'] ?? null) ? $planetConjunctionDecoded['conjunctions'] : []; } +$mercuryGoodVisibilityOutput = []; +$mercuryGoodVisibilityExitCode = 0; +$mercuryGoodVisibilityArgs = [ + $pythonScriptPath, + 'mercury_good_visibility_for_month', + (string) $chartLatitude, + (string) $chartLongitude, + (string) $chartElevation, + (string) $selectedYear, + (string) $selectedMonth, + $chartTimezone, + (string) $mercuryGoodVisibilitySampleOffsetMinutes, + (string) $mercuryGoodVisibilityMinAltitudeDeg, + (string) $mercuryGoodVisibilityMaxSunAltitudeDeg, + (string) $mercuryGoodVisibilityMinConsecutiveDays, +]; +$mercuryGoodVisibilityCommand = $pythonExecutable . ' ' . implode(' ', array_map('escapeshellarg', $mercuryGoodVisibilityArgs)) . ' 2>&1'; +exec($mercuryGoodVisibilityCommand, $mercuryGoodVisibilityOutput, $mercuryGoodVisibilityExitCode); +$mercuryGoodVisibilityRaw = trim(implode("\n", $mercuryGoodVisibilityOutput)); +$mercuryGoodVisibilityDecoded = json_decode($mercuryGoodVisibilityRaw, true); +if (is_array($mercuryGoodVisibilityDecoded) && ($mercuryGoodVisibilityDecoded['ok'] ?? false)) { + $mercuryGoodVisibilityEvents = is_array($mercuryGoodVisibilityDecoded['events'] ?? null) ? $mercuryGoodVisibilityDecoded['events'] : []; +} + $moonOccultationStars = []; try { if (isset($pdo)) { @@ -986,6 +1051,24 @@ foreach ($moonPlanetApproaches as $approachEvent) { ]; } +foreach ($moonDeepSkyApproaches as $approachEvent) { + if (!is_array($approachEvent)) { + continue; + } + + $distanceText = isset($approachEvent['separation_deg']) + ? number_format((float) ($approachEvent['separation_deg']), 2, ',', '') . ' Grad' + : ''; + + $monthEventList[] = [ + 'event' => trim((string) ($approachEvent['label'] ?? 'Mond nahe Sternhaufen') . ($distanceText !== '' ? ' (' . $distanceText . ')' : '')), + 'date' => (string) ($approachEvent['local_date'] ?? ''), + 'time' => (string) ($approachEvent['local_time'] ?? ''), + 'local_iso' => (string) ($approachEvent['local_iso'] ?? ''), + 'type' => 'moon_deep_sky', + ]; +} + foreach ($planetConjunctions as $conjunctionEvent) { if (!is_array($conjunctionEvent)) { continue; @@ -1004,6 +1087,20 @@ foreach ($planetConjunctions as $conjunctionEvent) { ]; } +foreach ($mercuryGoodVisibilityEvents as $visibilityEvent) { + if (!is_array($visibilityEvent)) { + continue; + } + + $monthEventList[] = [ + 'event' => (string) ($visibilityEvent['label'] ?? 'Gute Merkur-Sichtbarkeit'), + 'date' => (string) ($visibilityEvent['local_date'] ?? ''), + 'time' => (string) ($visibilityEvent['local_time'] ?? ''), + 'local_iso' => (string) ($visibilityEvent['local_iso'] ?? ''), + 'type' => 'mercury_good_visibility', + ]; +} + foreach ($moonOccultations as $occultationEvent) { if (!is_array($occultationEvent)) { continue; diff --git a/public/py/__pycache__/api.cpython-312.pyc b/public/py/__pycache__/api.cpython-312.pyc index 8ccc3cd0ba9bf8d8bd47e905e7cb91d1441e5872..f132f926b89f2d0a31bbbf3336ac282650f77635 100644 GIT binary patch delta 20328 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 delta 13136 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 Lmx(1F*5UsE4mf|@ diff --git a/public/py/api.py b/public/py/api.py index 875adf2..265c9ba 100644 --- a/public/py/api.py +++ b/public/py/api.py @@ -262,6 +262,17 @@ def action_planet_rise_set(args: list[str]) -> dict: } +def body_altitude_deg( + body: astronomy.Body, + observer: astronomy.Observer, + dt_utc: datetime, +) -> float: + time_value = dt_to_time(dt_utc) + eq = astronomy.Equator(body, time_value, observer, True, True) + hor = astronomy.Horizon(time_value, observer, eq.ra, eq.dec, astronomy.Refraction.Normal) + return float(hor.altitude) + + def serialize_body_position( key: str, label: str, @@ -293,6 +304,148 @@ def serialize_body_position( return payload +def action_mercury_good_visibility_for_month(args: list[str]) -> dict: + if len(args) != 10: + fail( + "Aktion mercury_good_visibility_for_month erwartet 10 Argumente: latitude longitude elevation year month timezone sample_offset_minutes min_mercury_alt_deg max_sun_alt_deg min_consecutive_days", + extra={"argv": args}, + ) + + latitude = parse_float(args[0], "Latitude") + longitude = parse_float(args[1], "Longitude") + elevation = parse_float(args[2], "Elevation") + + try: + year = int(args[3]) + month = int(args[4]) + sample_offset_minutes = int(args[6]) + min_consecutive_days = int(args[9]) + except ValueError as exc: + fail("Jahr, Monat oder Sichtbarkeitsparameter sind ungueltig.", extra={"details": str(exc), "argv": args}) + + if month < 1 or month > 12: + fail("Monat muss zwischen 1 und 12 liegen.", extra={"month": month}) + + timezone_name = args[5] + min_mercury_alt_deg = parse_float(args[7], "Minimale Merkurhoehe") + max_sun_alt_deg = parse_float(args[8], "Maximale Sonnenhoehe") + + try: + tz = ZoneInfo(timezone_name) + except Exception as exc: + fail("Zeitzone ist ungueltig oder auf dem Server nicht verfuegbar.", extra={"details": str(exc)}) + + observer = astronomy.Observer(latitude, longitude, elevation) + local_start = datetime(year, month, 1, 0, 0, 0, tzinfo=tz) + if month == 12: + local_end = datetime(year + 1, 1, 1, 0, 0, 0, tzinfo=tz) + else: + local_end = datetime(year, month + 1, 1, 0, 0, 0, tzinfo=tz) + + daily_checks: list[dict] = [] + current_local = local_start + while current_local < local_end: + day_start_utc = current_local.astimezone(timezone.utc) + next_day_utc = (current_local + timedelta(days=1)).astimezone(timezone.utc) + start_time = dt_to_time(day_start_utc) + + sunrise = search_event(astronomy.Body.Sun, astronomy.Direction.Rise, observer, start_time, next_day_utc) + sunset = search_event(astronomy.Body.Sun, astronomy.Direction.Set, observer, start_time, next_day_utc) + + morning_ok = False + morning_dt_local = None + morning_mercury_alt = None + morning_sun_alt = None + if sunrise is not None: + sunrise_local = time_to_datetime(sunrise).astimezone(tz) + morning_dt_local = sunrise_local - timedelta(minutes=sample_offset_minutes) + morning_dt_utc = morning_dt_local.astimezone(timezone.utc) + morning_mercury_alt = body_altitude_deg(astronomy.Body.Mercury, observer, morning_dt_utc) + morning_sun_alt = body_altitude_deg(astronomy.Body.Sun, observer, morning_dt_utc) + morning_ok = morning_mercury_alt >= min_mercury_alt_deg and morning_sun_alt <= max_sun_alt_deg + + evening_ok = False + evening_dt_local = None + evening_mercury_alt = None + evening_sun_alt = None + if sunset is not None: + sunset_local = time_to_datetime(sunset).astimezone(tz) + evening_dt_local = sunset_local + timedelta(minutes=sample_offset_minutes) + evening_dt_utc = evening_dt_local.astimezone(timezone.utc) + evening_mercury_alt = body_altitude_deg(astronomy.Body.Mercury, observer, evening_dt_utc) + evening_sun_alt = body_altitude_deg(astronomy.Body.Sun, observer, evening_dt_utc) + evening_ok = evening_mercury_alt >= min_mercury_alt_deg and evening_sun_alt <= max_sun_alt_deg + + daily_checks.append({ + "date": current_local.strftime("%d.%m.%Y"), + "morning_ok": morning_ok, + "morning_local": morning_dt_local, + "morning_mercury_alt_deg": morning_mercury_alt, + "morning_sun_alt_deg": morning_sun_alt, + "evening_ok": evening_ok, + "evening_local": evening_dt_local, + "evening_mercury_alt_deg": evening_mercury_alt, + "evening_sun_alt_deg": evening_sun_alt, + }) + + current_local += timedelta(days=1) + + def build_windows(period_key: str, label_text: str) -> list[dict]: + events = [] + start_index = None + + for index, day in enumerate(daily_checks): + is_ok = bool(day[f"{period_key}_ok"]) + if is_ok and start_index is None: + start_index = index + is_last = index == len(daily_checks) - 1 + if start_index is not None and (not is_ok or is_last): + end_index = index if (is_ok and is_last) else index - 1 + duration_days = end_index - start_index + 1 + if duration_days >= min_consecutive_days: + start_day = daily_checks[start_index] + end_day = daily_checks[end_index] + start_local = start_day[f"{period_key}_local"] + if start_local is not None: + range_text = ( + start_day["date"] + if start_index == end_index + else f'{start_day["date"]} bis {end_day["date"]}' + ) + events.append({ + "period": period_key, + "label": f"Gute Merkur-Sichtbarkeit am {label_text} ({range_text})", + "utc_iso": start_local.astimezone(timezone.utc).isoformat().replace("+00:00", "Z"), + "local_iso": start_local.isoformat(), + "local_date": start_local.strftime("%d.%m.%Y"), + "local_time": start_local.strftime("%H:%M"), + "end_local_date": end_day["date"], + "duration_days": duration_days, + }) + start_index = None + + return events + + events = build_windows("morning", "Morgen") + events.extend(build_windows("evening", "Abend")) + events.sort(key=lambda item: item["local_iso"]) + + return { + "ok": True, + "action": "mercury_good_visibility_for_month", + "selected": { + "year": year, + "month": month, + "timezone": timezone_name, + "sample_offset_minutes": sample_offset_minutes, + "min_mercury_alt_deg": min_mercury_alt_deg, + "max_sun_alt_deg": max_sun_alt_deg, + "min_consecutive_days": min_consecutive_days, + }, + "events": events, + } + + def action_month_sky_context(args: list[str]) -> dict: if len(args) != 8: fail( @@ -774,6 +927,17 @@ def moon_planet_separation_deg( return spherical_separation_deg(float(moon_eq.ra), float(moon_eq.dec), float(body_eq.ra), float(body_eq.dec)) +def moon_fixed_equatorial_separation_deg( + ra_hours: float, + dec_deg: float, + observer: astronomy.Observer, + dt_utc: datetime, +) -> float: + time_value = dt_to_time(dt_utc) + moon_eq = astronomy.Equator(astronomy.Body.Moon, time_value, observer, True, True) + return spherical_separation_deg(float(moon_eq.ra), float(moon_eq.dec), float(ra_hours), float(dec_deg)) + + def planet_pair_separation_deg( body_a: astronomy.Body, body_b: astronomy.Body, @@ -835,6 +999,31 @@ def refine_planet_pair_minimum_separation( return best, planet_pair_separation_deg(body_a, body_b, observer, best) +def refine_fixed_target_minimum_separation( + ra_hours: float, + dec_deg: float, + observer: astronomy.Observer, + left_utc: datetime, + right_utc: datetime, +) -> tuple[datetime, float]: + left = left_utc + right = right_utc + + for _ in range(32): + span = (right - left) / 3 + m1 = left + span + m2 = right - span + f1 = moon_fixed_equatorial_separation_deg(ra_hours, dec_deg, observer, m1) + f2 = moon_fixed_equatorial_separation_deg(ra_hours, dec_deg, observer, m2) + if f1 <= f2: + right = m2 + else: + left = m1 + + best = left + (right - left) / 2 + return best, moon_fixed_equatorial_separation_deg(ra_hours, dec_deg, observer, best) + + def action_moon_planet_approaches(args: list[str]) -> dict: if len(args) != 7: fail( @@ -946,6 +1135,112 @@ def action_moon_planet_approaches(args: list[str]) -> dict: } +def action_moon_deep_sky_approaches_for_month(args: list[str]) -> dict: + if len(args) != 7: + fail( + "Aktion moon_deep_sky_approaches_for_month erwartet 7 Argumente: latitude longitude elevation year month timezone max_sep_deg", + extra={"argv": args}, + ) + + latitude = parse_float(args[0], "Latitude") + longitude = parse_float(args[1], "Longitude") + elevation = parse_float(args[2], "Elevation") + + try: + year = int(args[3]) + month = int(args[4]) + except ValueError as exc: + fail("Jahr oder Monat sind ungueltig.", extra={"details": str(exc), "argv": args}) + + if month < 1 or month > 12: + fail("Monat muss zwischen 1 und 12 liegen.", extra={"month": month}) + + timezone_name = args[5] + max_sep_deg = parse_float(args[6], "Maximalabstand") + + try: + tz = ZoneInfo(timezone_name) + except Exception as exc: + fail("Zeitzone ist ungueltig oder auf dem Server nicht verfuegbar.", extra={"details": str(exc)}) + + observer = astronomy.Observer(latitude, longitude, elevation) + local_start = datetime(year, month, 1, 0, 0, 0, tzinfo=tz) + if month == 12: + local_end = datetime(year + 1, 1, 1, 0, 0, 0, tzinfo=tz) + else: + local_end = datetime(year, month + 1, 1, 0, 0, 0, tzinfo=tz) + + utc_start = local_start.astimezone(timezone.utc) + utc_end = local_end.astimezone(timezone.utc) + scan_step = timedelta(hours=1) + coarse_threshold = max_sep_deg + 1.0 + + target_defs = [ + ("pleiades", "Plejaden", 3.7833, 24.1167), + ("praesepe", "Praesepe", 8.6667, 19.9833), + ] + + approaches = [] + for key, label, ra_hours, dec_deg in target_defs: + samples: list[tuple[datetime, float]] = [] + current = utc_start + while current <= utc_end: + samples.append((current, moon_fixed_equatorial_separation_deg(ra_hours, dec_deg, observer, current))) + current += scan_step + if samples[-1][0] < utc_end: + samples.append((utc_end, moon_fixed_equatorial_separation_deg(ra_hours, dec_deg, observer, utc_end))) + + seen_ranges: list[tuple[datetime, datetime]] = [] + for index in range(1, len(samples) - 1): + curr_t, curr_sep = samples[index] + prev_sep = samples[index - 1][1] + next_sep = samples[index + 1][1] + + if curr_sep > coarse_threshold: + continue + if curr_sep > prev_sep or curr_sep > next_sep: + continue + + left = max(utc_start, curr_t - scan_step) + right = min(utc_end, curr_t + scan_step) + + if any(not (right <= seen_left or left >= seen_right) for seen_left, seen_right in seen_ranges): + continue + + min_time_utc, min_sep = refine_fixed_target_minimum_separation(ra_hours, dec_deg, observer, left, right) + local_dt = min_time_utc.astimezone(tz) + if local_dt.year != year or local_dt.month != month: + continue + if min_sep > max_sep_deg: + continue + + seen_ranges.append((left, right)) + approaches.append({ + "target_key": key, + "target_label": label, + "label": f"Mond nahe {label}", + "separation_deg": float(min_sep), + "utc_iso": min_time_utc.isoformat().replace("+00:00", "Z"), + "local_iso": local_dt.isoformat(), + "local_date": local_dt.strftime("%d.%m.%Y"), + "local_time": local_dt.strftime("%H:%M"), + }) + + approaches.sort(key=lambda item: item["local_iso"]) + + return { + "ok": True, + "action": "moon_deep_sky_approaches_for_month", + "selected": { + "year": year, + "month": month, + "timezone": timezone_name, + "max_separation_deg": max_sep_deg, + }, + "approaches": approaches, + } + + def action_planet_conjunctions_for_month(args: list[str]) -> dict: if len(args) != 7: fail( @@ -3135,7 +3430,7 @@ def action_satellite_passes(args: list[str]) -> dict: def main() -> None: if len(sys.argv) < 2: - fail("Es wurde keine Aktion uebergeben.", extra={"available_actions": ["sun_moon_rise_set", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "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", "moon_star_occultations_for_month"]}) + fail("Es wurde keine Aktion uebergeben.", extra={"available_actions": ["sun_moon_rise_set", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "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_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", "moon_star_occultations_for_month"]}) action = sys.argv[1] args = sys.argv[2:] @@ -3195,6 +3490,11 @@ def main() -> None: print(json.dumps(result, ensure_ascii=False)) return + if action == "moon_deep_sky_approaches_for_month": + result = action_moon_deep_sky_approaches_for_month(args) + print(json.dumps(result, ensure_ascii=False)) + return + if action == "planet_conjunctions_for_month": result = action_planet_conjunctions_for_month(args) print(json.dumps(result, ensure_ascii=False)) @@ -3240,12 +3540,17 @@ def main() -> None: print(json.dumps(result, ensure_ascii=False)) return + if action == "mercury_good_visibility_for_month": + result = action_mercury_good_visibility_for_month(args) + print(json.dumps(result, ensure_ascii=False)) + return + if action == "moon_star_occultations_for_month": result = action_moon_star_occultations_for_month(args) print(json.dumps(result, ensure_ascii=False)) return - fail("Unbekannte Aktion.", extra={"action": action, "available_actions": ["sun_moon_rise_set", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "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", "moon_star_occultations_for_month"]}) + fail("Unbekannte Aktion.", extra={"action": action, "available_actions": ["sun_moon_rise_set", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "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_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", "moon_star_occultations_for_month"]}) if __name__ == "__main__": diff --git a/todo.md b/todo.md index dbee541..14b9d88 100644 --- a/todo.md +++ b/todo.md @@ -2,11 +2,8 @@ - Besonders enge Mond-Stern-Begegnungen heller Sterne ergaenzen, auch ohne Bedeckung - Helle Stern-/Planeten-Begegnungen aufnehmen, z. B. Venus nahe Regulus oder Mars nahe Spica -- Mond nahe Plejaden und Mond nahe Praesepe als eigene Ereignisse pruefen - Auffaellige Planeten-Sichtbarkeit redaktionell ausgeben, z. B. Morgenstern/Abendstern, ganze Nacht sichtbar -- Gute Merkur-Sichtbarkeit ausgeben, nicht nur groesste Elongation -- Supermond / Minimon d als populaere Monatsereignisse pruefen +- Supermond / Minimond als populaere Monatsereignisse pruefen - Sichtbare ISS-Ueberfluege fuer den Standort ergaenzen -- Zodiacallicht als saisonalen Beobachtungshinweis pruefen - Sehr dunkle Naechte um Neumond / Milchstrassen-Beobachtungsfenster als Hinweis pruefen - Hesiodusstrahl als eigenes Mondlichtphaenomen fuer die Monatsvorschau ergaenzen