This is a php implementation of Josh r code to calculate the position of the sun for a given date and time :
这是用于计算给定日期和时间的太阳位置的Josh r代码的php实现:
This is the corrected code after MvG help :
这是MvG帮助后的更正代码:
function getSunPosition($lat, $long, $year, $month, $day, $hour, $min) {
// From https://*.com/questions/8708048/position-of-the-sun-given-time-of-day-latitude-and-longitude?rq=1
// Get Julian date for date at noon
$jd = gregoriantojd($month,$day,$year);
//correct for half-day offset
$dayfrac = $hour / 24 - .5;
//now set the fraction of a day
$frac = $dayfrac + $min / 60 / 24;
$jd = $jd + $frac;
// The input to the Atronomer's almanach is the difference between
// the Julian date and JD 2451545.0 (noon, 1 January 2000)
$time = ($jd - 2451545);
// Ecliptic coordinates
// Mean longitude
$mnlong = (280.460 + 0.9856474 * $time);
$mnlong = fmod($mnlong,360);
if ($mnlong < 0) $mnlong = ($mnlong + 360);
// Mean anomaly
$mnanom = (357.528 + 0.9856003 * $time);
$mnanom = fmod($mnanom,360);
if ($mnanom < 0) $mnanom = ($mnanom + 360);
$mnanom = deg2rad($mnanom);
// Ecliptic longitude and obliquity of ecliptic
$eclong = ($mnlong + 1.915 * sin($mnanom) + 0.020 * sin(2 * $mnanom));
$eclong = fmod($eclong,360);
if ($eclong < 0) $eclong = ($eclong + 360);
$oblqec = (23.439 - 0.0000004 * $time);
$eclong = deg2rad($eclong);
$oblqec = deg2rad($oblqec);
// Celestial coordinates
// Right ascension and declination
$num = (cos($oblqec) * sin($eclong));
$den = (cos($eclong));
$ra = (atan($num / $den));
if ($den < 0) $ra = ($ra + pi());
if ($den >= 0 && $num <0) $ra = ($ra + 2*pi());
$dec = (asin(sin($oblqec) * sin($eclong)));
// Local coordinates
// Greenwich mean sidereal time
//$h = $hour + $min / 60 + $sec / 3600;
$h = $hour + $min / 60;
$gmst = (6.697375 + .0657098242 * $time + $h);
$gmst = fmod($gmst,24);
if ($gmst < 0) $gmst = ($gmst + 24);
// Local mean sidereal time
$lmst = ($gmst + $long / 15);
$lmst = fmod($lmst,24);
if ($lmst < 0) $lmst = ($lmst + 24);
$lmst = deg2rad($lmst * 15);
// Hour angle
$ha = ($lmst - $ra);
if ($ha < pi()) $ha = ($ha + 2*pi());
if ($ha > pi()) $ha = ($ha - 2*pi());
// Latitude to radians
$lat = deg2rad($lat);
// Azimuth and elevation
$el = (asin(sin($dec) * sin($lat) + cos($dec) * cos($lat) * cos($ha)));
$az = (asin(-cos($dec) * sin($ha) / cos($el)));
// For logic and names, see Spencer, J.W. 1989. Solar Energy. 42(4):353
if ((sin($dec) - sin($el) * sin($lat)) >00) {
if(sin($az) < 0) $az = ($az + 2*pi());
} else {
$az = (pi() - $az);
}
$el = rad2deg($el);
$az = rad2deg($az);
$lat = rad2deg($lat);
return array(number_format($el,2),number_format($az,2));
}
This has been tested with Congo (near Equateur) lat/long : -4.77867 / 11.86364 for date Sept 1st 2013 at 10h00. In this case, the correct answer is : elevation = 67.77503 azimuth = 54.51532
这已经与刚果(靠近Equateur)纬度/长度进行了测试:日期为2013年9月1日10点的-4.77867 / 11.86364。在这种情况下,正确答案是:海拔= 67.77503方位角= 54.51532
Thanks for your help debuging this php code !
感谢您帮助debuging这个PHP代码!
Greg Fabre.
格雷格法布尔。
1 个解决方案
#1
2
I believe the line
我相信这一行
if ($dayfrac < 0) $dayfrac += 1;
is in error. If you are before noon, you don't want to refer to the same time one day later, but instead you want to specify a time before noon, i.e. subtract from the julian date which represents noon.
是错误的。如果你在中午之前,你不想在一天后的同一时间参考,而是你想在中午之前指定一个时间,即从代表中午的朱利安日期中减去。
Removing that line, your example date corresponds to the one computed using http://www.imcce.fr/en/grandpublic/temps/jour_julien.php, namely 2456536.9166666665. The resulting
删除该行,您的示例日期对应于使用http://www.imcce.fr/en/grandpublic/temps/jour_julien.php计算的日期,即2456536.9166666665。所结果的
$el = 67.775028608168
$az = 54.515316112281
looks pretty good to me. In particular, it agrees with the R run
看起来对我很好。特别是,它同意R run
elevation = 67.77503
azimuth = 54.51532
and also with what Stellarium says (although I quoted this incorrectly in a comment above):
以及Stellarium所说的内容(虽然我在上面的评论中错误地引用了这个):
Alt = 67°46'30" = 67.775
Az = 54°30'60" = 45.5167
It also (almost) agrees with sunearthtools.com, so I guess you made a mistake when first entering the data there:
它(几乎)也同意sunearthtools.com,所以我猜你在第一次输入数据时犯了一个错误:
So I'd say that solves the problem.
所以我会说解决了这个问题。
#1
2
I believe the line
我相信这一行
if ($dayfrac < 0) $dayfrac += 1;
is in error. If you are before noon, you don't want to refer to the same time one day later, but instead you want to specify a time before noon, i.e. subtract from the julian date which represents noon.
是错误的。如果你在中午之前,你不想在一天后的同一时间参考,而是你想在中午之前指定一个时间,即从代表中午的朱利安日期中减去。
Removing that line, your example date corresponds to the one computed using http://www.imcce.fr/en/grandpublic/temps/jour_julien.php, namely 2456536.9166666665. The resulting
删除该行,您的示例日期对应于使用http://www.imcce.fr/en/grandpublic/temps/jour_julien.php计算的日期,即2456536.9166666665。所结果的
$el = 67.775028608168
$az = 54.515316112281
looks pretty good to me. In particular, it agrees with the R run
看起来对我很好。特别是,它同意R run
elevation = 67.77503
azimuth = 54.51532
and also with what Stellarium says (although I quoted this incorrectly in a comment above):
以及Stellarium所说的内容(虽然我在上面的评论中错误地引用了这个):
Alt = 67°46'30" = 67.775
Az = 54°30'60" = 45.5167
It also (almost) agrees with sunearthtools.com, so I guess you made a mistake when first entering the data there:
它(几乎)也同意sunearthtools.com,所以我猜你在第一次输入数据时犯了一个错误:
So I'd say that solves the problem.
所以我会说解决了这个问题。