[php] zonsopgang/ondergang berekenen

Pagina: 1
Acties:
  • 952 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Johnny
  • Registratie: December 2001
  • Laatst online: 03-07 13:19

Johnny

ondergewaardeerde internetguru

Topicstarter
Ik wil een script hebben dat berekent of de zon op, of onder is. Na even zoeken had ik al wat bruikbaars gevonden, wel in een andere taal maar omzetten naar PHP was niet zoveel werk.

Ik kan er echter geen nuttige resultaten uit krijgen.
Ik heb de coordinaten van Rotterdam ingevuld, maar ik weet niet of ze wel in het juiste formaat zijn. En de zenith (zon's hoogste punt) op 95 gezet.

Ook weet ik niet wat er met afkortingen zoals UTC en UT wordt bedoeld of wat er met "potentially needs to be adjusted into the range" wordt bedoeld.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php

/*Source:
http://williams.best.vwh.net/sunrise_sunset_algorithm.htm

Inputs:
    day, month, year:      date of sunrise/sunset
    latitude, longitude:   location for sunrise/sunset
    zenith:                Sun's zenith for sunrise/sunset
      offical      = 90 degrees 50'
      civil        = 96 degrees
      nautical     = 102 degrees
      astronomical = 108 degrees
    
    NOTE: longitude is positive for East and negative for West
*/

    //tijdzone GMT +1.00
    $localOffset = 1;

    //zon's hoogste punt
    $zenith = 95;

    //Locatie Rotterdam 51,55 N - 4,29 E
    $latitude = 51.55;
    $longitude = 4.29;


//1. first calculate the day of the year

    //daar hebben we in PHP al een functie voor
    $N = date("z");

echo("N: ".$N."<br>");

//2. convert the longitude to hour value and calculate an approximate time

    $lngHour = $longitude / 15;
    
    //if rising time is desired:
     // $t = $N + ((6 - $lngHour) / 24);
    //if setting time is desired:
      $t = $N + ((18 - $lngHour) / 24);

//3. calculate the Sun's mean anomaly
    
    $M = (0.9856 * $t) - 3.289;

//4. calculate the Sun's true longitude
    
    $L = $M + (1.916 * sin($M)) + (0.020 * sin(2 * $M)) + 282.634;
    //NOTE: L potentially needs to be adjusted into the range [0,360) 
//by adding/subtracting 360

//5a. calculate the Sun's right ascension
    
    $RA = atan(0.91764 * tan($L));
    //NOTE: RA potentially needs to be adjusted into the range [0,360) 
//by adding/subtracting 360

//5b. right ascension value needs to be in the same quadrant as L

    $Lquadrant  = (floor($L / 90)) * 90;
    $RAquadrant = (floor($RA / 90)) * 90;
    $RA = $RA + ($Lquadrant - $RAquadrant);

//5c. right ascension value needs to be converted into hours

    $RA = $RA / 15;

echo("RA: ".$RA."<br>");

//6. calculate the Sun's declination

    $sinDec = 0.39782 * sin($L);
    $cosDec = cos(asin($sinDec));

//7a. calculate the Sun's local hour angle
    
    $cosH = (cos($zenith) - ($sinDec * sin($latitude))) / ($cosDec * cos($latitude));

echo("cosH: ".$cosH."<br>");
    
    if($cosH >  1)
        {echo("De zon komt hier niet op<br>");}
      //the sun never rises on this location (on the specified date)
    if($cosH < -1)
        {echo("De zon gaat hier niet onder<br>");}
      //the sun never sets on this location (on the specified date)

//7b. finish calculating H and convert into hours
    
    //if if rising time is desired:
    //  $H = 360 - acos(cosH)
    //if setting time is desired:
      $H = acos($cosH);
    
    $H = $H / 15;

//8. calculate local mean time of rising/setting
    
    $T = $H + $RA - (0.06571 * $t) - 6.622;

//9. adjust back to UTC
    
    $UT = $T - $lngHour;
    //NOTE: UT potentially needs to be adjusted into the range [0,24) 
//by adding/subtracting 24

//10. convert UT value to local time zone of latitude/longitude
    
    $localT = $UT + $localOffset;

echo("LocalT: ".$localT."<br>");

?>


Zonsondergang is vandaag om 21:29, dus $LocalT moet rond de 9.5 liggen (denk ik).

[ Voor 5% gewijzigd door Johnny op 03-08-2003 11:24 ]

Aan de inhoud van de bovenstaande tekst kunnen geen rechten worden ontleend, tenzij dit expliciet in dit bericht is verwoord.


Acties:
  • 0 Henk 'm!

  • Lancer
  • Registratie: Januari 2002
  • Laatst online: 02-07 11:42

Lancer

What the......

UTC is Universal time, ook wel Greenwich time genoemd, naar de Sterrewacht in Londen waar de 0-meridiaan loopt. Zomertijd is UTC+2, wintertijd is UTC+1.

Zenit is het hoogste punt wat de zon aan de hemel berijkt. Verder kennen we een aantal soorten schemering:
Astronomische schemering: Absoluut donker komt in Nederland in de zomer nauwelijks voor
Nautische schemering: Zolang de horizon zichtbaar is
Burgerlijke schemering: Zolang je buiten de krant kunt lezen
Official in dit script is de tijd wanneer de zon onder gaat. 90 50 staat voor zon onder de horizon, die 50 slaat op de diameter van de zon schijf.
96 staat voor de zon 6 graden onder de horizon etc.

Je kunt niet in een systeem meten zonder het systeem te beinvloeden.... (gevolg van de Heisenberg onzekerheidsrelatie)


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01-07 14:32
Johnny schreef op 03 August 2003 @ 11:22:
Ook weet ik niet wat er met afkortingen zoals UTC en UT wordt bedoeld of wat er met "potentially needs to be adjusted into the range" wordt bedoeld.
Daarmee wordt bedoelt dat de waarde voor het "uur" na het optellen van een compensatie voor de huidige tijdzone onder de 0 of boven de 24 kan komen. Je moet daar op een of andere manier voor compenseren; het makkelijkst is met:
PHP:
1
$hour = ($hour + 24) % 24;

Dat gaat goed zolang $hour niet lager wordt dan -24 (wat normaalgesproken acceptabel is).

Acties:
  • 0 Henk 'm!

  • CAP-Team
  • Registratie: April 2000
  • Laatst online: 15:38

CAP-Team

XBL: CAPTeam

Toch klopt er iets niet in het script, hij zegt nl. dat de zon hier niet onder gaat :+

Microsoft Surface Pro 6 | Samsung Galaxy S21FE | XBOX Series X


Acties:
  • 0 Henk 'm!

  • Lancer
  • Registratie: Januari 2002
  • Laatst online: 02-07 11:42

Lancer

What the......

Wat is je waarde voor Zenit (overigens is Zenit hier een zeer foute benaming)? Zoals ik eerder zij, b.v. de astronomische schemering vind nu niet plaats. Als je zenit op 90 of 91 hebt staan moet de zon onder gaan. Let ook ff op je coordinaten. Wat staat er achter de komma? Conversie van b.v. boogseconden naar graden kan nodig zijn.

Je kunt niet in een systeem meten zonder het systeem te beinvloeden.... (gevolg van de Heisenberg onzekerheidsrelatie)


Acties:
  • 0 Henk 'm!

  • Johnny
  • Registratie: December 2001
  • Laatst online: 03-07 13:19

Johnny

ondergewaardeerde internetguru

Topicstarter
Lancer schreef op 03 August 2003 @ 13:44:
Wat is je waarde voor Zenit (overigens is Zenit hier een zeer foute benaming)? Zoals ik eerder zij, b.v. de astronomische schemering vind nu niet plaats. Als je zenit op 90 of 91 hebt staan moet de zon onder gaan. Let ook ff op je coordinaten. Wat staat er achter de komma? Conversie van b.v. boogseconden naar graden kan nodig zijn.
De invier van de coordinaten weet ik ook niet zeker. Ik heb het graden teken vervangen door een punt zodat het een numerieke waarde is. Ik zou niet weten in welk formaat ik het ander zou moeten doen.

Aan de inhoud van de bovenstaande tekst kunnen geen rechten worden ontleend, tenzij dit expliciet in dit bericht is verwoord.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01-07 14:32
De geometrische functies in PHP werken op radialen en niet op graden (zoals ook in de meeste andere programmeertalen het geval is). Je moet dus sowieso je graden converteren naar radialen (met bijvoorbeeld deg2rad). Verder geloof ik niet dat er 100 van die ' dingen (zijn dat nou minuten of seconden?) in 1 graad gaan, maar dat zou slechts een kleine afwijking moeten veroorzaken.

Acties:
  • 0 Henk 'm!

  • windancer
  • Registratie: Maart 2000
  • Laatst online: 15:12
Soultaker schreef op 03 August 2003 @ 11:44:
Je moet daar op een of andere manier voor compenseren; het makkelijkst is met:
PHP:
1
$hour = ($hour + 24) % 24;

acceptabel is).
Ik ken PHP niet maar wiskundig gezien is dit compleet equivalent met het veel simpelere
PHP:
1
$hour = $hour % 24;
Als dit in PHP niet zo werkt is het tijd voor een bug-report ;)

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01-07 14:32
windancer schreef op 03 August 2003 @ 18:29:
Ik ken PHP niet maar wiskundig gezien is dit compleet equivalent met het veel simpelere
PHP:
1
$hour = $hour % 24;
Als dit in PHP niet zo werkt is het tijd voor een bug-report ;)
Ik heb geen idee hoe de restdeling in de wiskunde gedefinieerd wordt, maar in programmeertalen is het gebruikelijk dat de restdeling op negatieve getallen werkt zoals die op de corresponderende absolute waarde (met een minteken voor het resultaat).

Dat betekent dus dat (-1)%24 gewoon -1 is, net als (-25)%24, terwijl hier 23 gewenst is. Ik compenseer hiervoor door het getal sowieso positief te maken (aangenomen dat het oorspronkelijke tijdstip noot lager dan -24 werd): (-1 + 24) % 24 is wel 23.

Acties:
  • 0 Henk 'm!

  • windancer
  • Registratie: Maart 2000
  • Laatst online: 15:12
Bizar. Blijkbaar zit er dus een verschil tussen de wiskundige modulus operator en de modulus operator zoals gedefinieerd in een groot aantal programmeertalen.

In de wiskunde is het resultaat van een modulus n operatie altijd een getal van 0 tot en met n-1.

Wel cool, weer wat geleerd :

BTW, blijkbaar vond iemand anders al eerder dat het een bug in PHP is : http://bugs.php.net/?id=22527
Soultaker schreef op 03 August 2003 @ 18:41:
[...]

Ik heb geen idee hoe de restdeling in de wiskunde gedefinieerd wordt, maar in programmeertalen is het gebruikelijk dat de restdeling op negatieve getallen werkt zoals die op de corresponderende absolute waarde (met een minteken voor het resultaat).

Dat betekent dus dat (-1)%24 gewoon -1 is, net als (-25)%24, terwijl hier 23 gewenst is. Ik compenseer hiervoor door het getal sowieso positief te maken (aangenomen dat het oorspronkelijke tijdstip noot lager dan -24 werd): (-1 + 24) % 24 is wel 23.

Acties:
  • 0 Henk 'm!

  • Johnny
  • Registratie: December 2001
  • Laatst online: 03-07 13:19

Johnny

ondergewaardeerde internetguru

Topicstarter
Als ik restdeling gebruik om te compenseren wordt alles afgerond naar hele integers. Ikheb daarom gewoon een if else contructie gebruikt.

Er zit inmiddels wel wat voortgang in, met de deg2rad() functie komen er getallen uit die binnen het bereik liggen, maar helemala perfect is het nog niet.

De uitkomst is steeds belachelijk laag, heeft iemand nog een goede tip?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    //tijdzone GMT +1.00
    $localOffset = 1;

    //zon's hoogste punt
    $zenith = deg2rad(90);

    //Locatie Rotterdam 51,55 N - 4,29 E
    $latitude = deg2rad(51.55);
    $longitude = deg2rad(4.29);

echo("latitude: ".$latitude."<br>");
echo("logintude: ".$longitude."<br>");

//1. first calculate the day of the year

    //daar hebben we in PHP al een functie voor
    //$N = date("z");
    $N = 350;

echo("N: ".$N."<br>");

//2. convert the longitude to hour value and calculate an approximate time

    $lngHour = $longitude / 15;

echo("lngHour: ".$lngHour."<br>");
    
    //if rising time is desired:
     // $t = $N + ((6 - $lngHour) / 24);
    //if setting time is desired:
      $t = $N + ((18 - $lngHour) / 24);

echo("t: ".$t."<br>");

//3. calculate the Sun's mean anomaly
    
    $M = (0.9856 * $t) - 3.289;

echo("M: ".$M."<br>");

//4. calculate the Sun's true longitude
    
    $L = $M + (1.916 * sin($M)) + (0.020 * sin(2 * $M)) + 282.634;
    //NOTE: L potentially needs to be adjusted into the range [0,360) 
by adding/subtracting 360

    if($L < 0)
        {$L = $L + 360;}
    elseif($L > 360)
        {$L = $L - 360;}

echo("L: ".$L."<br>");

//5a. calculate the Sun's right ascension
    
    $RA = atan(0.91764 * tan($L));
    //NOTE: RA potentially needs to be adjusted into the range [0,360) 
by adding/subtracting 360

    if($RA < 0)
        {$RA = $RA + 360;}
    elseif($RA > 360)
        {$RA = $RA - 360;}

echo("RA: ".$RA."<br>");

//5b. right ascension value needs to be in the same quadrant as L

    $Lquadrant  = (floor($L / 90)) * 90;
    $RAquadrant = (floor($RA / 90)) * 90;
    $RA = $RA + ($Lquadrant - $RAquadrant);

//5c. right ascension value needs to be converted into hours

    $RA = $RA / 15;

echo("RA: ".$RA."<br>");

//6. calculate the Sun's declination

    $sinDec = 0.39782 * sin($L);
    $cosDec = cos(asin($sinDec));

//7a. calculate the Sun's local hour angle
    
    $cosH = (cos($zenith) - ($sinDec * sin($latitude))) / ($cosDec * cos($latitude));

echo("cosH: ".$cosH."<br>");
    
    if($cosH >  1)
        {echo("De zon komt hier niet op<br>");}
      //the sun never rises on this location (on the specified date)
    if($cosH < -1)
        {echo("De zon gaat hier niet onder<br>");}
      //the sun never sets on this location (on the specified date)

//7b. finish calculating H and convert into hours
    
    //if if rising time is desired:
    //  $H = 360 - acos(cosH)
    //if setting time is desired:
     $H = acos($cosH);
    
    $H = $H / 15;

echo("H: ".$H."<br>");

//8. calculate local mean time of rising/setting
    
    $T = $H + $RA - (0.06571 * $t) - 6.622;

echo("T: ".$T."<br>");

//9. adjust back to UTC
    
    $UT = $T - $lngHour;
    //NOTE: UT potentially needs to be adjusted into the range [0,24) 
by adding/subtracting 24

    if($UT < 0)
        {$UT = $UT + 24;}
    elseif($UT > 24)
        {$UT = $UT - 24;}

echo("UT: ".$UT."<br>");

//10. convert UT value to local time zone of latitude/longitude
    
    $localT = $UT + $localOffset;

echo("LocalT: ".$localT."<br>");

Aan de inhoud van de bovenstaande tekst kunnen geen rechten worden ontleend, tenzij dit expliciet in dit bericht is verwoord.


Acties:
  • 0 Henk 'm!

  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Alleen die 3 variabelen naar radialen converteren helpt niet denk ik, het hele algoritme werkt in graden, range 0-360 bijvoorbeeld, delen door 90 zal ook wel 90 graden zijn enz. Dus volgens mij kan je beter die 3 variabelen in graden laten en van alle sin/cos/tan(x) een sin/cos/tan(deg2rad(x)) maken en van alle asin/acos/atan(x) een rad2deg(asin/acos/atan(x)) (als ik het goed heb :? ).

www.madwizard.org


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
<flauw>

Ist niet makkelijker om een zonne-sensor op je dak te zetten, en aan te sluiten op je computer? :P

</flauw>

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info

Pagina: 1