diff --git a/.codex-temp/php-server.err.log b/.codex-temp/php-server.err.log index e69de29..7494f4e 100644 --- a/.codex-temp/php-server.err.log +++ b/.codex-temp/php-server.err.log @@ -0,0 +1,244 @@ +[Fri Apr 3 12:55:30 2026] PHP 8.5.4 Development Server (http://127.0.0.1:8000) started +[Fri Apr 3 12:55:31 2026] 127.0.0.1:61744 Accepted +[Fri Apr 3 12:55:31 2026] 127.0.0.1:61744 [200]: GET / +[Fri Apr 3 12:55:31 2026] 127.0.0.1:61744 Closing +[Fri Apr 3 12:55:43 2026] 127.0.0.1:62501 Accepted +[Fri Apr 3 12:55:43 2026] 127.0.0.1:62501 [200]: GET / +[Fri Apr 3 12:55:43 2026] 127.0.0.1:62501 Closing +[Fri Apr 3 12:55:43 2026] 127.0.0.1:57288 Accepted +[Fri Apr 3 12:55:43 2026] 127.0.0.1:57288 [200]: GET /css/style.css +[Fri Apr 3 12:55:43 2026] 127.0.0.1:57288 Closing +[Fri Apr 3 12:55:43 2026] 127.0.0.1:60157 Accepted +[Fri Apr 3 12:55:43 2026] 127.0.0.1:59285 Accepted +[Fri Apr 3 12:55:43 2026] 127.0.0.1:60157 [200]: GET /images/star16x16.png +[Fri Apr 3 12:55:43 2026] 127.0.0.1:59285 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 12:55:43 2026] 127.0.0.1:60157 Closing +[Fri Apr 3 12:55:43 2026] 127.0.0.1:59285 Closing +[Fri Apr 3 12:55:43 2026] 127.0.0.1:51393 Accepted +[Fri Apr 3 12:55:43 2026] 127.0.0.1:51393 [200]: GET /favicon.ico +[Fri Apr 3 12:55:43 2026] 127.0.0.1:51393 Closing +[Fri Apr 3 12:55:45 2026] 127.0.0.1:61468 Accepted +[Fri Apr 3 12:55:45 2026] 127.0.0.1:61468 [200]: GET /login.php +[Fri Apr 3 12:55:45 2026] 127.0.0.1:61468 Closing +[Fri Apr 3 12:55:45 2026] 127.0.0.1:63560 Accepted +[Fri Apr 3 12:55:45 2026] 127.0.0.1:63560 [200]: GET /css/style.css +[Fri Apr 3 12:55:45 2026] 127.0.0.1:63560 Closing +[Fri Apr 3 12:55:45 2026] 127.0.0.1:63181 Accepted +[Fri Apr 3 12:55:45 2026] 127.0.0.1:58293 Accepted +[Fri Apr 3 12:55:45 2026] 127.0.0.1:63181 [200]: GET /images/star16x16.png +[Fri Apr 3 12:55:45 2026] 127.0.0.1:58293 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 12:55:45 2026] 127.0.0.1:63181 Closing +[Fri Apr 3 12:55:45 2026] 127.0.0.1:58293 Closing +[Fri Apr 3 12:55:45 2026] 127.0.0.1:59169 Accepted +[Fri Apr 3 12:55:45 2026] 127.0.0.1:59169 [200]: GET /favicon.ico +[Fri Apr 3 12:55:45 2026] 127.0.0.1:59169 Closing +[Fri Apr 3 12:55:52 2026] 127.0.0.1:61270 Accepted +[Fri Apr 3 12:55:52 2026] 127.0.0.1:61270 [302]: POST /login.php +[Fri Apr 3 12:55:52 2026] 127.0.0.1:61270 Closing +[Fri Apr 3 12:55:52 2026] 127.0.0.1:53857 Accepted +[Fri Apr 3 12:55:54 2026] 127.0.0.1:53857 [200]: GET /index.php +[Fri Apr 3 12:55:54 2026] 127.0.0.1:53857 Closing +[Fri Apr 3 12:55:54 2026] 127.0.0.1:60472 Accepted +[Fri Apr 3 12:55:54 2026] 127.0.0.1:60472 [200]: GET /css/style.css +[Fri Apr 3 12:55:54 2026] 127.0.0.1:60472 Closing +[Fri Apr 3 12:55:54 2026] 127.0.0.1:51512 Accepted +[Fri Apr 3 12:55:54 2026] 127.0.0.1:55657 Accepted +[Fri Apr 3 12:55:54 2026] 127.0.0.1:51512 [200]: GET /images/star16x16.png +[Fri Apr 3 12:55:54 2026] 127.0.0.1:55657 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 12:55:54 2026] 127.0.0.1:51512 Closing +[Fri Apr 3 12:55:54 2026] 127.0.0.1:55657 Closing +[Fri Apr 3 12:55:54 2026] 127.0.0.1:65352 Accepted +[Fri Apr 3 12:55:55 2026] 127.0.0.1:65352 [200]: GET /favicon.ico +[Fri Apr 3 12:55:55 2026] 127.0.0.1:65352 Closing +[Fri Apr 3 12:56:03 2026] 127.0.0.1:55831 Accepted +[Fri Apr 3 12:56:03 2026] 127.0.0.1:55831 [200]: GET /monatsvorhersage.php +[Fri Apr 3 12:56:03 2026] 127.0.0.1:55831 Closing +[Fri Apr 3 12:56:03 2026] 127.0.0.1:49989 Accepted +[Fri Apr 3 12:56:03 2026] 127.0.0.1:49989 [200]: GET /css/style.css +[Fri Apr 3 12:56:03 2026] 127.0.0.1:49989 Closing +[Fri Apr 3 12:56:03 2026] 127.0.0.1:59540 Accepted +[Fri Apr 3 12:56:03 2026] 127.0.0.1:58424 Accepted +[Fri Apr 3 12:56:03 2026] 127.0.0.1:59540 [200]: GET /images/star16x16.png +[Fri Apr 3 12:56:03 2026] 127.0.0.1:58424 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 12:56:03 2026] 127.0.0.1:59540 Closing +[Fri Apr 3 12:56:03 2026] 127.0.0.1:58424 Closing +[Fri Apr 3 12:56:03 2026] 127.0.0.1:53882 Accepted +[Fri Apr 3 12:56:04 2026] 127.0.0.1:53882 [200]: GET /favicon.ico +[Fri Apr 3 12:56:04 2026] 127.0.0.1:53882 Closing +[Fri Apr 3 12:56:06 2026] 127.0.0.1:57400 Accepted +[Fri Apr 3 12:56:09 2026] 127.0.0.1:57400 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 12:56:09 2026] 127.0.0.1:57400 Closing +[Fri Apr 3 12:56:09 2026] 127.0.0.1:57166 Accepted +[Fri Apr 3 12:56:09 2026] 127.0.0.1:57166 [200]: GET /css/style.css +[Fri Apr 3 12:56:09 2026] 127.0.0.1:53955 Accepted +[Fri Apr 3 12:56:09 2026] 127.0.0.1:53955 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 12:56:09 2026] 127.0.0.1:57166 Closing +[Fri Apr 3 12:56:09 2026] 127.0.0.1:53955 Closing +[Fri Apr 3 12:56:09 2026] 127.0.0.1:61310 Accepted +[Fri Apr 3 12:56:09 2026] 127.0.0.1:61310 [200]: GET /images/star16x16.png +[Fri Apr 3 12:56:09 2026] 127.0.0.1:53333 Accepted +[Fri Apr 3 12:56:09 2026] 127.0.0.1:53333 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 12:56:09 2026] 127.0.0.1:61310 Closing +[Fri Apr 3 12:56:09 2026] 127.0.0.1:53333 Closing +[Fri Apr 3 12:56:09 2026] 127.0.0.1:57930 Accepted +[Fri Apr 3 12:56:10 2026] 127.0.0.1:57930 [200]: GET /favicon.ico +[Fri Apr 3 12:56:10 2026] 127.0.0.1:57930 Closing +[Fri Apr 3 13:07:35 2026] 127.0.0.1:62131 Accepted +[Fri Apr 3 13:07:45 2026] 127.0.0.1:62131 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 13:07:45 2026] 127.0.0.1:62131 Closing +[Fri Apr 3 13:08:21 2026] 127.0.0.1:58476 Accepted +[Fri Apr 3 13:08:31 2026] 127.0.0.1:58476 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 13:08:31 2026] 127.0.0.1:58476 Closing +[Fri Apr 3 13:08:31 2026] 127.0.0.1:59671 Accepted +[Fri Apr 3 13:08:31 2026] 127.0.0.1:49906 Accepted +[Fri Apr 3 13:08:31 2026] 127.0.0.1:59671 [200]: GET /css/style.css +[Fri Apr 3 13:08:31 2026] 127.0.0.1:49906 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 13:08:31 2026] 127.0.0.1:59671 Closing +[Fri Apr 3 13:08:31 2026] 127.0.0.1:49906 Closing +[Fri Apr 3 13:08:31 2026] 127.0.0.1:56322 Accepted +[Fri Apr 3 13:08:31 2026] 127.0.0.1:56322 [200]: GET /images/star16x16.png +[Fri Apr 3 13:08:31 2026] 127.0.0.1:64778 Accepted +[Fri Apr 3 13:08:31 2026] 127.0.0.1:64778 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 13:08:31 2026] 127.0.0.1:56322 Closing +[Fri Apr 3 13:08:31 2026] 127.0.0.1:64778 Closing +[Fri Apr 3 13:08:31 2026] 127.0.0.1:57777 Accepted +[Fri Apr 3 13:08:32 2026] 127.0.0.1:57777 [200]: GET /favicon.ico +[Fri Apr 3 13:08:32 2026] 127.0.0.1:57777 Closing +[Fri Apr 3 13:10:24 2026] 127.0.0.1:55499 Accepted +[Fri Apr 3 13:10:36 2026] 127.0.0.1:55499 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 13:10:36 2026] 127.0.0.1:55499 Closing +[Fri Apr 3 13:10:36 2026] 127.0.0.1:55501 Accepted +[Fri Apr 3 13:10:47 2026] 127.0.0.1:55501 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 13:10:47 2026] 127.0.0.1:55501 Closing +[Fri Apr 3 13:11:58 2026] 127.0.0.1:65503 Accepted +[Fri Apr 3 13:12:08 2026] 127.0.0.1:65503 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 13:12:08 2026] 127.0.0.1:65503 Closing +[Fri Apr 3 13:12:08 2026] 127.0.0.1:62139 Accepted +[Fri Apr 3 13:12:08 2026] 127.0.0.1:62139 [200]: GET /css/style.css +[Fri Apr 3 13:12:08 2026] 127.0.0.1:62139 Closing +[Fri Apr 3 13:12:08 2026] 127.0.0.1:53163 Accepted +[Fri Apr 3 13:12:08 2026] 127.0.0.1:53163 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 13:12:08 2026] 127.0.0.1:53163 Closing +[Fri Apr 3 13:12:08 2026] 127.0.0.1:57019 Accepted +[Fri Apr 3 13:12:08 2026] 127.0.0.1:57019 [200]: GET /images/star16x16.png +[Fri Apr 3 13:12:08 2026] 127.0.0.1:55337 Accepted +[Fri Apr 3 13:12:08 2026] 127.0.0.1:55337 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 13:12:08 2026] 127.0.0.1:57019 Closing +[Fri Apr 3 13:12:08 2026] 127.0.0.1:55337 Closing +[Fri Apr 3 13:12:08 2026] 127.0.0.1:60473 Accepted +[Fri Apr 3 13:12:09 2026] 127.0.0.1:60473 [200]: GET /favicon.ico +[Fri Apr 3 13:12:09 2026] 127.0.0.1:60473 Closing +[Fri Apr 3 13:17:32 2026] 127.0.0.1:61313 Accepted +[Fri Apr 3 13:17:32 2026] PHP Fatal error: strict_types declaration must be the very first statement in the script in C:\Users\HP\source\repos\skyview.astronomiemuseum.de\public\monatsvorhersage_old.php on line 2 +Stack trace: +#0 {main} +[Fri Apr 3 13:17:32 2026] 127.0.0.1:61313 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 - strict_types declaration must be the very first statement in the script in C:\Users\HP\source\repos\skyview.astronomiemuseum.de\public\monatsvorhersage_old.php on line 2 +[Fri Apr 3 13:17:32 2026] 127.0.0.1:61313 Closing +[Fri Apr 3 13:17:45 2026] 127.0.0.1:65268 Accepted +[Fri Apr 3 13:17:56 2026] 127.0.0.1:65268 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 13:17:56 2026] 127.0.0.1:65268 Closing +[Fri Apr 3 13:18:58 2026] 127.0.0.1:49481 Accepted +[Fri Apr 3 13:19:07 2026] 127.0.0.1:49481 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 13:19:07 2026] 127.0.0.1:49481 Closing +[Fri Apr 3 13:19:07 2026] 127.0.0.1:55985 Accepted +[Fri Apr 3 13:19:07 2026] 127.0.0.1:64118 Accepted +[Fri Apr 3 13:19:07 2026] 127.0.0.1:55985 [200]: GET /css/style.css +[Fri Apr 3 13:19:07 2026] 127.0.0.1:64118 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 13:19:07 2026] 127.0.0.1:55985 Closing +[Fri Apr 3 13:19:07 2026] 127.0.0.1:64118 Closing +[Fri Apr 3 13:19:07 2026] 127.0.0.1:53485 Accepted +[Fri Apr 3 13:19:07 2026] 127.0.0.1:49504 Accepted +[Fri Apr 3 13:19:07 2026] 127.0.0.1:53485 [200]: GET /images/star16x16.png +[Fri Apr 3 13:19:07 2026] 127.0.0.1:49504 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 13:19:07 2026] 127.0.0.1:53485 Closing +[Fri Apr 3 13:19:07 2026] 127.0.0.1:49504 Closing +[Fri Apr 3 13:19:07 2026] 127.0.0.1:55983 Accepted +[Fri Apr 3 13:19:09 2026] 127.0.0.1:55983 [200]: GET /favicon.ico +[Fri Apr 3 13:19:09 2026] 127.0.0.1:55983 Closing +[Fri Apr 3 13:26:13 2026] 127.0.0.1:54897 Accepted +[Fri Apr 3 13:26:21 2026] 127.0.0.1:54897 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 13:26:21 2026] 127.0.0.1:54897 Closing +[Fri Apr 3 13:26:54 2026] 127.0.0.1:58751 Accepted +[Fri Apr 3 13:27:02 2026] 127.0.0.1:58751 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 13:27:02 2026] 127.0.0.1:58751 Closing +[Fri Apr 3 13:27:02 2026] 127.0.0.1:57821 Accepted +[Fri Apr 3 13:27:02 2026] 127.0.0.1:57821 [200]: GET /css/style.css +[Fri Apr 3 13:27:02 2026] 127.0.0.1:57821 Closing +[Fri Apr 3 13:27:02 2026] 127.0.0.1:60458 Accepted +[Fri Apr 3 13:27:02 2026] 127.0.0.1:60458 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 13:27:02 2026] 127.0.0.1:60458 Closing +[Fri Apr 3 13:27:02 2026] 127.0.0.1:65479 Accepted +[Fri Apr 3 13:27:02 2026] 127.0.0.1:53843 Accepted +[Fri Apr 3 13:27:02 2026] 127.0.0.1:65479 [200]: GET /images/star16x16.png +[Fri Apr 3 13:27:02 2026] 127.0.0.1:53843 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 13:27:02 2026] 127.0.0.1:65479 Closing +[Fri Apr 3 13:27:02 2026] 127.0.0.1:53843 Closing +[Fri Apr 3 13:27:02 2026] 127.0.0.1:49425 Accepted +[Fri Apr 3 13:27:03 2026] 127.0.0.1:49425 [200]: GET /favicon.ico +[Fri Apr 3 13:27:03 2026] 127.0.0.1:49425 Closing +[Fri Apr 3 13:27:40 2026] 127.0.0.1:56116 Accepted +[Fri Apr 3 13:27:55 2026] 127.0.0.1:56116 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 13:27:55 2026] 127.0.0.1:56116 Closing +[Fri Apr 3 13:27:55 2026] 127.0.0.1:62096 Accepted +[Fri Apr 3 13:27:55 2026] 127.0.0.1:62096 [200]: GET /css/style.css +[Fri Apr 3 13:27:55 2026] 127.0.0.1:62096 Closing +[Fri Apr 3 13:27:55 2026] 127.0.0.1:63051 Accepted +[Fri Apr 3 13:27:55 2026] 127.0.0.1:63051 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 13:27:55 2026] 127.0.0.1:63051 Closing +[Fri Apr 3 13:27:55 2026] 127.0.0.1:56973 Accepted +[Fri Apr 3 13:27:55 2026] 127.0.0.1:56973 [200]: GET /images/star16x16.png +[Fri Apr 3 13:27:55 2026] 127.0.0.1:59670 Accepted +[Fri Apr 3 13:27:55 2026] 127.0.0.1:59670 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 13:27:55 2026] 127.0.0.1:56973 Closing +[Fri Apr 3 13:27:55 2026] 127.0.0.1:59670 Closing +[Fri Apr 3 13:27:55 2026] 127.0.0.1:55675 Accepted +[Fri Apr 3 13:27:56 2026] 127.0.0.1:55675 [200]: GET /favicon.ico +[Fri Apr 3 13:27:56 2026] 127.0.0.1:55675 Closing +[Fri Apr 3 13:29:57 2026] 127.0.0.1:50606 Accepted +[Fri Apr 3 13:29:57 2026] PHP Fatal error: strict_types declaration must be the very first statement in the script in C:\Users\HP\source\repos\skyview.astronomiemuseum.de\public\monatsvorhersage_old.php on line 2 +Stack trace: +#0 {main} +[Fri Apr 3 13:29:57 2026] 127.0.0.1:50606 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 - strict_types declaration must be the very first statement in the script in C:\Users\HP\source\repos\skyview.astronomiemuseum.de\public\monatsvorhersage_old.php on line 2 +[Fri Apr 3 13:29:57 2026] 127.0.0.1:50606 Closing +[Fri Apr 3 13:30:21 2026] 127.0.0.1:53183 Accepted +[Fri Apr 3 13:30:35 2026] 127.0.0.1:53183 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 13:30:35 2026] 127.0.0.1:53183 Closing +[Fri Apr 3 13:30:35 2026] 127.0.0.1:54365 Accepted +[Fri Apr 3 13:30:35 2026] 127.0.0.1:57332 Accepted +[Fri Apr 3 13:30:35 2026] 127.0.0.1:54365 [200]: GET /css/style.css +[Fri Apr 3 13:30:35 2026] 127.0.0.1:57332 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 13:30:35 2026] 127.0.0.1:54365 Closing +[Fri Apr 3 13:30:35 2026] 127.0.0.1:57332 Closing +[Fri Apr 3 13:30:35 2026] 127.0.0.1:63339 Accepted +[Fri Apr 3 13:30:35 2026] 127.0.0.1:61606 Accepted +[Fri Apr 3 13:30:35 2026] 127.0.0.1:63339 [200]: GET /images/star16x16.png +[Fri Apr 3 13:30:35 2026] 127.0.0.1:61606 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 13:30:35 2026] 127.0.0.1:63339 Closing +[Fri Apr 3 13:30:35 2026] 127.0.0.1:61606 Closing +[Fri Apr 3 13:30:35 2026] 127.0.0.1:62852 Accepted +[Fri Apr 3 13:30:36 2026] 127.0.0.1:62852 [200]: GET /favicon.ico +[Fri Apr 3 13:30:36 2026] 127.0.0.1:62852 Closing +[Fri Apr 3 13:31:31 2026] 127.0.0.1:55128 Accepted +[Fri Apr 3 13:31:39 2026] 127.0.0.1:55128 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 13:31:39 2026] 127.0.0.1:55128 Closing +[Fri Apr 3 13:33:09 2026] 127.0.0.1:59634 Accepted +[Fri Apr 3 13:33:17 2026] 127.0.0.1:59634 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 +[Fri Apr 3 13:33:17 2026] 127.0.0.1:59634 Closing +[Fri Apr 3 13:34:05 2026] 127.0.0.1:55782 Accepted +[Fri Apr 3 13:34:19 2026] 127.0.0.1:55782 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 13:34:19 2026] 127.0.0.1:55782 Closing +[Fri Apr 3 13:34:19 2026] 127.0.0.1:63401 Accepted +[Fri Apr 3 13:34:19 2026] 127.0.0.1:63401 [200]: GET /css/style.css +[Fri Apr 3 13:34:19 2026] 127.0.0.1:63401 Closing +[Fri Apr 3 13:34:19 2026] 127.0.0.1:53737 Accepted +[Fri Apr 3 13:34:19 2026] 127.0.0.1:53737 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 13:34:19 2026] 127.0.0.1:53737 Closing +[Fri Apr 3 13:34:19 2026] 127.0.0.1:63715 Accepted +[Fri Apr 3 13:34:19 2026] 127.0.0.1:54210 Accepted +[Fri Apr 3 13:34:19 2026] 127.0.0.1:63715 [200]: GET /images/star16x16.png +[Fri Apr 3 13:34:19 2026] 127.0.0.1:54210 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 13:34:19 2026] 127.0.0.1:63715 Closing +[Fri Apr 3 13:34:19 2026] 127.0.0.1:54210 Closing +[Fri Apr 3 13:34:19 2026] 127.0.0.1:63048 Accepted +[Fri Apr 3 13:34:20 2026] 127.0.0.1:63048 [200]: GET /favicon.ico +[Fri Apr 3 13:34:20 2026] 127.0.0.1:63048 Closing diff --git a/public/monatsvorhersage_old.php b/public/monatsvorhersage_old.php index 1d7ef8d..b3598e3 100644 --- a/public/monatsvorhersage_old.php +++ b/public/monatsvorhersage_old.php @@ -59,6 +59,7 @@ $moonData = null; $moonPhaseEvents = []; $moonPlanetApproaches = []; $planetConjunctions = []; +$eclipseEvents = []; $moonOccultations = []; $seasonChanges = []; $monthEventList = []; @@ -347,6 +348,26 @@ if (is_array($seasonDecoded) && ($seasonDecoded['ok'] ?? false)) { $seasonChanges = is_array($seasonDecoded['changes'] ?? null) ? $seasonDecoded['changes'] : []; } +$eclipseOutput = []; +$eclipseExitCode = 0; +$eclipseArgs = [ + $pythonScriptPath, + 'eclipses_for_month', + (string) $chartLatitude, + (string) $chartLongitude, + (string) $chartElevation, + (string) $selectedYear, + (string) $selectedMonth, + $chartTimezone, +]; +$eclipseCommand = $pythonExecutable . ' ' . implode(' ', array_map('escapeshellarg', $eclipseArgs)) . ' 2>&1'; +exec($eclipseCommand, $eclipseOutput, $eclipseExitCode); +$eclipseRaw = trim(implode("\n", $eclipseOutput)); +$eclipseDecoded = json_decode($eclipseRaw, true); +if (is_array($eclipseDecoded) && ($eclipseDecoded['ok'] ?? false)) { + $eclipseEvents = is_array($eclipseDecoded['events'] ?? null) ? $eclipseDecoded['events'] : []; +} + $moonPlanetOutput = []; $moonPlanetExitCode = 0; $moonPlanetArgs = [ @@ -482,6 +503,20 @@ foreach ($seasonChanges as $seasonChange) { ]; } +foreach ($eclipseEvents as $eclipseEvent) { + if (!is_array($eclipseEvent)) { + continue; + } + + $monthEventList[] = [ + 'event' => (string) ($eclipseEvent['label'] ?? 'Finsternis'), + 'date' => (string) ($eclipseEvent['local_date'] ?? ''), + 'time' => (string) ($eclipseEvent['local_time'] ?? ''), + 'local_iso' => (string) ($eclipseEvent['local_iso'] ?? ''), + 'type' => (string) ($eclipseEvent['category'] ?? 'eclipse'), + ]; +} + foreach ($moonPlanetApproaches as $approachEvent) { if (!is_array($approachEvent)) { continue; diff --git a/public/py/__pycache__/api.cpython-314.pyc b/public/py/__pycache__/api.cpython-314.pyc index 79ef597..2a0d7ec 100644 Binary files a/public/py/__pycache__/api.cpython-314.pyc and b/public/py/__pycache__/api.cpython-314.pyc differ diff --git a/public/py/api.py b/public/py/api.py index f9e5b35..d957fbb 100644 --- a/public/py/api.py +++ b/public/py/api.py @@ -826,6 +826,194 @@ def action_planet_conjunctions_for_month(args: list[str]) -> dict: } +def eclipse_kind_label(kind: astronomy.EclipseKind) -> str: + if kind == astronomy.EclipseKind.Penumbral: + return "Halbschatten" + if kind == astronomy.EclipseKind.Partial: + return "Partielle" + if kind == astronomy.EclipseKind.Annular: + return "Ringfoermige" + if kind == astronomy.EclipseKind.Total: + return "Totale" + return "Unbekannte" + + +def serialize_time_only(time_value: astronomy.Time, tz: ZoneInfo) -> dict: + dt_utc = time_to_datetime(time_value) + local_dt = dt_utc.astimezone(tz) + return { + "utc_iso": dt_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"), + } + + +def action_eclipses_for_month(args: list[str]) -> dict: + if len(args) != 6: + fail( + "Aktion eclipses_for_month erwartet 6 Argumente: latitude longitude elevation year month timezone", + 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] + 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_start = dt_to_time(utc_start - timedelta(days=40)) + + events: list[dict] = [] + + lunar = astronomy.SearchLunarEclipse(scan_start) + while True: + peak_dt_utc = time_to_datetime(lunar.peak) + if peak_dt_utc >= utc_end: + break + + local_peak = peak_dt_utc.astimezone(tz) + if local_peak >= local_start: + kind_label = eclipse_kind_label(lunar.kind) + penum_begin = lunar.peak.AddDays(-lunar.sd_penum / 1440.0) + penum_end = lunar.peak.AddDays(+lunar.sd_penum / 1440.0) + + events.append({ + "category": "lunar_eclipse", + "stage": "peak", + "kind": lunar.kind.name.lower(), + "label": f"{kind_label} Mondfinsternis - Maximum", + **serialize_time_only(lunar.peak, tz), + }) + + if lunar.sd_penum > 0: + events.append({ + "category": "lunar_eclipse", + "stage": "penumbral_begin", + "kind": lunar.kind.name.lower(), + "label": f"{kind_label} Mondfinsternis - Halbschatten beginnt", + **serialize_time_only(penum_begin, tz), + }) + events.append({ + "category": "lunar_eclipse", + "stage": "penumbral_end", + "kind": lunar.kind.name.lower(), + "label": f"{kind_label} Mondfinsternis - Halbschatten endet", + **serialize_time_only(penum_end, tz), + }) + + if lunar.sd_partial > 0: + partial_begin = lunar.peak.AddDays(-lunar.sd_partial / 1440.0) + partial_end = lunar.peak.AddDays(+lunar.sd_partial / 1440.0) + events.append({ + "category": "lunar_eclipse", + "stage": "partial_begin", + "kind": lunar.kind.name.lower(), + "label": f"{kind_label} Mondfinsternis - Partielle Phase beginnt", + **serialize_time_only(partial_begin, tz), + }) + events.append({ + "category": "lunar_eclipse", + "stage": "partial_end", + "kind": lunar.kind.name.lower(), + "label": f"{kind_label} Mondfinsternis - Partielle Phase endet", + **serialize_time_only(partial_end, tz), + }) + + if lunar.sd_total > 0: + total_begin = lunar.peak.AddDays(-lunar.sd_total / 1440.0) + total_end = lunar.peak.AddDays(+lunar.sd_total / 1440.0) + events.append({ + "category": "lunar_eclipse", + "stage": "total_begin", + "kind": lunar.kind.name.lower(), + "label": "Totale Mondfinsternis - Totalitaet beginnt", + **serialize_time_only(total_begin, tz), + }) + events.append({ + "category": "lunar_eclipse", + "stage": "total_end", + "kind": lunar.kind.name.lower(), + "label": "Totale Mondfinsternis - Totalitaet endet", + **serialize_time_only(total_end, tz), + }) + + lunar = astronomy.NextLunarEclipse(lunar.peak) + + solar = astronomy.SearchLocalSolarEclipse(scan_start, observer) + while True: + peak_dt_utc = time_to_datetime(solar.peak.time) + if peak_dt_utc >= utc_end: + break + + local_peak = peak_dt_utc.astimezone(tz) + if local_peak >= local_start: + kind_label = eclipse_kind_label(solar.kind) + + def solar_event_payload(label: str, event: astronomy.EclipseEvent, stage: str) -> dict: + payload = { + "category": "solar_eclipse", + "stage": stage, + "kind": solar.kind.name.lower(), + "label": label, + "sun_altitude_deg": float(event.altitude), + "above_horizon": float(event.altitude) >= 0.0, + } + payload.update(serialize_time_only(event.time, tz)) + return payload + + events.append(solar_event_payload(f"{kind_label} Sonnenfinsternis - Beginn", solar.partial_begin, "partial_begin")) + events.append(solar_event_payload(f"{kind_label} Sonnenfinsternis - Maximum", solar.peak, "peak")) + if solar.total_begin is not None: + phase_label = "Ringphase beginnt" if solar.kind == astronomy.EclipseKind.Annular else "Totalitaet beginnt" + events.append(solar_event_payload(f"{kind_label} Sonnenfinsternis - {phase_label}", solar.total_begin, "central_begin")) + if solar.total_end is not None: + phase_label = "Ringphase endet" if solar.kind == astronomy.EclipseKind.Annular else "Totalitaet endet" + events.append(solar_event_payload(f"{kind_label} Sonnenfinsternis - {phase_label}", solar.total_end, "central_end")) + events.append(solar_event_payload(f"{kind_label} Sonnenfinsternis - Ende", solar.partial_end, "partial_end")) + + solar = astronomy.NextLocalSolarEclipse(solar.peak.time, observer) + + events = [ + event for event in events + if local_start <= datetime.fromisoformat(event["local_iso"]) < local_end + ] + events.sort(key=lambda item: item["local_iso"]) + + return { + "ok": True, + "action": "eclipses_for_month", + "selected": { + "year": year, + "month": month, + "timezone": timezone_name, + }, + "events": events, + } + + def action_moon_star_occultations_for_month(args: list[str]) -> dict: if len(args) != 7: fail( @@ -1882,7 +2070,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", "season_changes_for_month", "moon_planet_approaches", "planet_conjunctions_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", "season_changes_for_month", "moon_planet_approaches", "planet_conjunctions_for_month", "eclipses_for_month", "moon_star_occultations_for_month"]}) action = sys.argv[1] args = sys.argv[2:] @@ -1937,12 +2125,17 @@ def main() -> None: print(json.dumps(result, ensure_ascii=False)) return + if action == "eclipses_for_month": + result = action_eclipses_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", "season_changes_for_month", "moon_planet_approaches", "planet_conjunctions_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", "season_changes_for_month", "moon_planet_approaches", "planet_conjunctions_for_month", "eclipses_for_month", "moon_star_occultations_for_month"]}) if __name__ == "__main__":