用PHP计算日出日落时间
注意:这是出于我的好奇心而做的练习,现有的函数/代码可以解决这个问题(也请参见注释) 可以在用PHP计算日出日落时间,php,trigonometry,date-sunrise,Php,Trigonometry,Date Sunrise,注意:这是出于我的好奇心而做的练习,现有的函数/代码可以解决这个问题(也请参见注释) 可以在Tcl和javascript中找到日出和日落时间的计算算法和实现 我正在尝试将算法转换为PHP,但这有点让我不知所措,需要花费太多时间。这是我到目前为止的结果: <?php $sunrise = sunriseSunsetTimeTest(9, 4, 2015, 46.929512, 7.565272); $sunset = sunriseSunsetTimeTest(9, 4, 20, 46.92
Tcl
和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;
}
为什么不直接使用内置的和函数呢?这对我来说是个练习。。。想提高我的数学知识。试着指出代码中产生所描述输出的部分(示例用法)。然后将预期结果添加到问题中。这样你可能会更快地得到答案,因为读者不必阅读全部代码就可以更容易地理解你想要实现的目标;这会让你的生活轻松很多。我认为你的问题之一(不一定是唯一的一个)是360-acos($cosH)
似乎混合了度数和弧度(我对PHP不太了解,所以如果我在广播我的无知,请忽略我)。这是我的第一次尝试,在脚本开始时使用deg2rad()将lat、lng和zenith转换为弧度。不幸的是没有成功。