тригонометрия — расчет времени восхода и захода солнца в переполнении стека

Примечание: это упражнение для моего любопытства, и существуют существующие функции / код, которые решают эту проблему (см. Также комментарии)

Алгоритм для расчета времени восхода и захода солнца можно найти Вот и реализации в 1 в Tcl а также 2 в javascript,

Я пытаюсь преобразовать алгоритм в PHP, но он немного у меня над головой и занимает слишком много времени. Это мой результат до сих пор:

<?php
$sunrise = sunriseSunsetTimeTest(9, 4, 2015, 46.929512, 7.565272);
$sunset = sunriseSunsetTimeTest(9, 4, 20, 46.929512, 7.565272, 'sunset');

echo $sunrise . '/' . $sunset;
/* output is: 12.314714533758/12.612340511889 (?) */

function sunriseSunsetTimeTest($day, $month, $year, $latitude, $longitude,
$which='sunrise', $localTimeOffset=1, $zenith=96){
/*
* Output:
* sunrise or sunset time depending on parameter $which
*
* Input:
* (int) day
* (int) month
* (int) year
* (float) latitude_degree
* (float) longitude_degree
* (string) which -> "sunrise" or "sunset (resp. not 'sunrise')"* (int) localTimeOffset (0 for GMT, 1 for CET, etc.)
* (float) zenith_degree
*      offical = 90 degrees 50'
*      civil = 96 degrees
*      nautical = 102 degrees
*      astronomical = 108 degrees
*/
$dayOfYear = dayOfYear($day, $month, $year);
// convert the longitude to hour value and calculate an approximate time
$lngHour = $longitude / 15;
$approximateTime = ($which=='sunrise')
? $dayOfYear + ((6 - $lngHour) / 24)
: $dayOfYear + ((18 - $lngHour) / 24);
// calculate the Sun's mean anomaly
$sunMeanAnomaly = (0.9856 * $approximateTime) - 3.289;
// calculate the Sun's true longitude
$sunTrueLongitude = $sunMeanAnomaly + (1.916 * sin($sunMeanAnomaly)) + (0.020 * sin(2 * $sunMeanAnomaly)) + 282.634;
while ($sunTrueLongitude>360)
$sunTrueLongitude -= 360;
while ($sunTrueLongitude<0)
$sunTrueLongitude += 360;
// calculate the Sun's right ascension
$sunRightAscension = rad2deg(atan(0.91764 * tan(deg2rad($sunTrueLongitude))));
while ($sunRightAscension>360)
$sunRightAscension -= 360;
while ($sunRightAscension<0)
$sunRightAscension += 360;
// right ascension value needs to be in the same quadrant as true longitude
$sunTrueLongitudeQuadrant  = (floor($sunTrueLongitude/90)) * 90;
$sunRightAscensionQuadrant = (floor($sunRightAscension/90)) * 90;
$sunRightAscension = $sunRightAscension + ($sunTrueLongitudeQuadrant - $sunRightAscensionQuadrant);
// right ascension value needs to be converted into hours
$sunRightAscension = $sunRightAscension / 15;
// calculate the Sun's declination
$sunSinDec = 0.39782 * sin(deg2rad($sunTrueLongitude));
$sunCosDec = cos(asin($sunSinDec));
// calculate the Sun's local hour angle
$cosH = (cos(deg2rad($zenith)) - ($sunSinDec * sin(deg2rad($latitude)))) / ($sunCosDec * cos(deg2rad($latitude)));
// finish calculating H and convert into hours
if ($which=='sunrise'){
if ($cosH > 1) //sun never rises on this location (on the specified date)
return false;
$H = 360 - acos($cosH);
}
else{
if ($cosH < -1) // sun never sets on this location (on the specified date)
return false;
$H = acos($cosH);
}
$H = $H / 15;
// calculate local mean time of rising/setting
$T = $H + $sunRightAscension - (0.06571 * $approximateTime) - 6.622;
// adjust back to UTC
$UT = $T - $lngHour;
while ($UT>24)
$UT -= 24;
while ($UT<0)
$UT += 24;
// convert UT value to local time zone of latitude/longitude
$localT = $UT + $localTimeOffset;
return $localT;
}

function dayOfYear($day,$month,$year){
$N1 = floor(275 * $month / 9);
$N2 = floor(($month + 9) / 12);
$N3 = (1 + floor(($year - 4 * floor($year / 4) + 2) / 3));
return $N1 - ($N2 * $N3) + $day - 30;
}

…Ввод date 09-04-2015, latitude 46.929512, longitude 7.565272 результаты в выходных 12.314714533758 для восхода солнца и 12.612340511889 на закат.

Я хотел бы понять, что не так в коде, может быть, кто-то может помочь. Спасибо!

3

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]