用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转换为弧度。不幸的是没有成功。