4
$\begingroup$

As detailed in https://physics.stackexchange.com/questions/41450/is-there-a-simple-accurate-formula-for-calculating-transit-times-from-rise-and, the sunrise, and set times can accurately be used to compute the sun's transit. Yet, in some cases, these do not exist, e.g. in Finland in the summer.

Is there an easier and/or more general way to compute the transit time (and only the transit time) given the UTC and observer position (latitude, longitude, height).

The library at http://www.jstott.me.uk/jsuntimes gives sunrise and sunset, but not the transit time. find_transit at riset_cir.c in https://github.com/brandon-rhodes/pyephem/tree/master/libastro-3.7.7 might do this, but seems too general and complicated.

$\endgroup$
  • 1
    $\begingroup$ A celestial object transits when the local sidereal time is equal to its right ascension, but that doesn't really answer your question. $\endgroup$ – barrycarter Jul 3 '18 at 21:33
  • $\begingroup$ How close do you want it? The transit time can be approximated as the arithmetic mean of the rise and set times. And what does not exist? Sunrise and -set times? You already linked to a site for obtaining those. $\endgroup$ – Mick Jul 4 '18 at 7:44
  • 1
    $\begingroup$ Do you mean near the poles? Then you will need to take a non-trivial approach and calculate it from the RA of the Sun as mentioned by barrycarter. $\endgroup$ – Mick Jul 4 '18 at 8:29
  • 1
    $\begingroup$ I did some work some years ago where I made a page on the web where I calculated the (geocentric) RA & Dec of the Sun for a given date using the algorithms in Jean Meeus' book Astronomical Algorithms. I can't remember the accuracy of the calculations and I didn't make the corrections for observer lat & long. The web page is still on my server at sionnagh.com/mtdistcalc.php, and I am happy to share the BASIC-to-php converted code behind it if that would help. $\endgroup$ – Mick Jul 4 '18 at 8:51
  • 1
    $\begingroup$ Another unhelpful comment: the sun transits at UTC 12-lon/15 hours (longitude is negative west of Greenwich). This formula is for the fictitious "mean sun" and is accurate to within 15 minutes. To correct for those extra 15 minutes, see Equation of Time. $\endgroup$ – barrycarter Jul 9 '18 at 16:15
1
$\begingroup$

Here is the page code for my BASIC-to-php implementation of the algorithms to calculate the (geocentric) RA & Dec of the Sun for a given date from Jean Meeus' book Astronomical Algorithms as well as calculating the angular distance between two celestial objects. I can't remember the accuracy of the calculations and I didn't make the corrections for observer lat & long.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1" />
 <base href="sionnagh.com" />
<title>Mick Todd Distance Calculator</title>
<STYLE TYPE="text/css">
<!--
BODY
   {
   font-family:sans-serif;
   }
A:link{color:white}
A:visited{color:yellow}
-->
</STYLE>
</head>
<body>
<?php include("mtheader.php"); ?>
<h1>Mick Todd Distance Calculator</h1>
<?php 
$earthincl=23.44;	//Earth's axial tilt
$sollat=0;

$fdate = $_POST["fdate"];
if ($fdate=="") {
	$fdate=getdate(date("U")-date("Z"));
	$fday=$fdate[mday];
	if (strlen($fday)==1) {$fday="0".$fday;}
	$fmonth=$fdate[mon];
	if (strlen($fmonth)==1) {$fmonth="0".$fmonth;}
	$fyear=$fdate[year];
	//$fdate=$fdate[mday]."/".$fdate[mon]."/".$fdate[year];
	$fdate=$fday."/".$fmonth."/".$fyear;
}
else {
	$fday=substr($fdate,0,2);
	$fmonth=substr($fdate,3,2);
	$fyear=substr($fdate,6,4);
}
$fra1 = $_POST["fra1"];
$fra1 = strtolower($fra1);
if ($fra1<>"") {
  if (strpos($fra1,"h")==0) {
  $frad1=$fra1;
  $fra1=converttohms($fra1);
  }
  else {
    $frad1=converthtod($fra1);
  }
}
$fdec1 = $_POST["fdec1"];
$fdec1 = strtolower($fdec1);
if ($fdec1<>"") {
  if (strpos($fdec1,"d")==0) {
    $fdecd1=$fdec1;
    $fdec1=converttodms($fdec1);
  }
  else {
    $fdecd1=convertdtod($fdec1);
  }
}
$fra2 = $_POST["fra2"];
$fra2 = strtolower($fra2);
if ($fra2<>"") {
  if (strpos($fra2,"h")==0) {
    $frad2=$fra2;
    $fra2=converttohms($fra2);
  }
  else {
    $frad2=converthtod($fra2);
  }
}
$fdec2 = $_POST["fdec2"];
$fdec2 = strtolower($fdec2);
if ($fdec2<>"") {
  if (strpos($fdec2,"d")==0) {
    $fdecd2=$fdec2;
    $fdec2=converttodms($fdec2);
  }
  else {
    $fdecd2=convertdtod($fdec2);
  }
}

function JulianDay ($fday, $fmonth, $fyear, $fUT) {
    $JDpartsign=(100*$fyear+$fmonth-190002.5)/abs(100*$fyear+$fmonth-190002.5);
	$JD = 367*$fyear - floor((7*($fyear+floor(($fmonth+9)/12)))/4) + floor((275*$fmonth)/9) + $fday + 1721013.5 + $fUT/24 - 0.5*$JDpartsign + 0.5;
	return $JD;
}
function converttodms($inval) {
	if ($inval==0) {
	  $fdsign=1;
	}
	else {
	  $fdsign=$inval/abs($inval);
	}
	$inval=abs($inval);
	$fddeg=floor($inval);
	$remain=($inval-$fddeg)*60;
	$fdmin=floor($remain);
	if (strlen($fdmin)==1) { $fdmin="0".$fdmin; }
	$remain=($remain-$fdmin)*60;
	$fdsec=round($remain*100)/100;
	if (strpos($fdsec,".")==1) { $fdsec="0".$fdsec; }
	$fddeg=$fdsign*$fddeg;
	$fdms=$fddeg."d".$fdmin."m".$fdsec."s";

    return $fdms;
}
function converttohms($inval) {
    $inval=$inval/15;
    $fddeg=floor($inval);
    $remain=($inval-$fddeg)*60;
	$fdmin=floor($remain);
	if (strlen($fdmin)==1) { $fdmin="0".$fdmin; }
    $remain=($remain-$fdmin)*60;
	$fdsec=round($remain*100)/100;
	if (strpos($fdsec,".")==1) { $fdsec="0".$fdsec; }
    $fdms=$fddeg."h".$fdmin."m".$fdsec."s";

    return $fdms;
}
function converthtod($inval) {
  $posh=strpos($inval,"h");
  $posm=strpos($inval,"m");
  $poss=strpos($inval,"s");
  $temph=substr($inval,0,$posh);
  if ($posm) {
    $tempm=substr($inval,$posh+1,$posm-($posh+1));
  }
  if ($poss) {
    $temps=substr($inval,$posm+1,$poss-($posm+1));
  }

  $fdms=($temph+$tempm/60+$temps/3600)*15;

  return $fdms;
}
function convertdtod($inval) {
  $posd=strpos($inval,"d");
  $posm=strpos($inval,"m");
  $poss=strpos($inval,"s");
  $tempd=substr($inval,0,$posd);
  if ($posm) {
    $tempm=substr($inval,$posd+1,$posm-($posd+1));
  }
  if ($poss) {
    $temps=substr($inval,$posm+1,$poss-($posm+1));
  }
  $fdms=$tempd+$tempm/60+$temps/3600;

  return $fdms;
}

function SolarCoords($fday, $fmonth, $fyear, $fUT) {
//Julian Day of 1991/ 5/19 at 13 UT         JD = 2448396.04167
//Julian day of 2000/01/01 at 12 UT         JD = 2451545.0
//number of Julian days since 2000/01/01 at 12 UT               -3148.95833
//number of Julian centuries since 2000/01/01 at 12 UT  T = - 3148.95833/36525
//used by the algorithm for L                                                           = 0.086213780

    $k = 2*pi()/360;
  $T = (JulianDay($fday, $fmonth, $fyear, $fUT)-2451545.0)/36525;
    //echo "\$T: ".$T."<br />";
	//mean anomaly, degree
	$M = 357.52910 + 35999.05030*$T - 0.0001559*$T*$T - 0.00000048*$T*$T*$T;
    //echo "\$M: ".$M."<br />";

    // mean longitude, degree
    $L0 = 280.46645 + 36000.76983*$T + 0.0003032*$T*$T;
    //echo "\$L0: ".$L0."<br />";

    $DL = (1.914600 - 0.004817*$T - 0.000014*$T*$T)*sin($k*$M) + (0.019993 - 0.000101*$T)*sin($k*2*$M) + 0.000290*sin($k*3*$M);
	//echo "\$DL: ".$DL."<br />";

    // true longitude, degree
    $L = $L0 + $DL;
	if (abs($L)>360) {
        $divsign=($L/360)/abs($L/360);
		$div=floor(abs($L/360));
		$L=$L-$divsign*$div*360;
		if ($L<0) { $L=$L+360; }
    }
    $L=round($L*10000)/10000;

    return $L;

}

?>
<script type="text/javascript">
    <!--
    function settoday() {
        var d=new Date();
        dday=d.getDate();
        if (dday<10) { dday="0" + dday; }
        dmonth=d.getMonth()+1;
        if (dmonth<10) { dmonth="0" + dmonth; }
        dyear=d.getFullYear();

        ddate= dday + "/" + dmonth + "/" + dyear;

        return ddate;

    }

    //-->
</script>
<form METHOD="POST" ACTION="mtdistcalc.php" name="mtdistcalc">


<p>Date <input type="text" name="fdate" id="fdate" size=10 value="<?php echo $fdate; ?>"> <input type="button" value="Now" onclick="fdate.value=settoday();"></p>
<p>Object coordinates (#1) RA <input type="text" name="fra1" id="fra1" size=15 value="<?php echo $fra1; ?>">  Decl <input type="text" name="fdec1" id="fdec1" size=15 value="<?php echo $fdec1; ?>"></p>
<p>Object coordinates (#2) RA <input type="text" name="fra2" id="fra2" size=15 value="<?php echo $fra2; ?>">  Decl <input type="text" name="fdec2" id="fdec2" size=15 value="<?php echo $fdec2; ?>"></p>
  <p><input TYPE=SUBMIT VALUE="Calculate distances"></p>


</form>
<?php
echo "<table><tr><td>Date:</td><td>".$fday."/".$fmonth."/".$fyear." "."0000UT</td></tr>";
echo "<tr><td>Julian Day: </td><td>".JulianDay($fday,$fmonth,$fyear,"0")."</td></tr>";
echo "<tr><td>Ecliptic latitude of the Sun: </td><td>".$sollat."&deg; (assumed)</td></tr>";
$sollong = SolarCoords($fday,$fmonth,$fyear,"0");
echo "<tr><td>Ecliptic longitude of the Sun: </td><td>".$sollong."&deg; (".converttodms($sollong).")</td></tr>";
echo "<tr><td>Earth's axial inclination: </td><td>".$earthincl."&deg;</td></tr></table><br />";

//echo "\$feclong ".$feclong."<br /><br />";

$deltaSol = round(asin(sin($sollat*M_PI/180)*cos($earthincl*M_PI/180) + cos($sollat*M_PI/180)*sin($earthincl*M_PI/180)*sin($sollong*M_PI/180))*180/M_PI*10000)/10000;
$alphaSol = round(acos(cos($sollong*M_PI/180)*cos($sollat*M_PI/180) / cos($deltaSol*M_PI/180))*180/M_PI*10000)/10000;
if ($sollong>180) {
	$alphaSol = 360-$alphaSol;
}
echo "<table><tr><td colspan=2>Sol</td></tr><tr><td>RA: </td><td>".$alphaSol."&deg; (".converttohms($alphaSol).")</td></tr><tr><td>Dec:</td><td>".$deltaSol."&deg; (".converttodms($deltaSol).")</td></tr></table><br />";

//spherical angular distance
//cos(theta) = sin(delta_a) sin(delta_b) + cos(delta_a) cos(delta_b) cos(alpha_a-alpha_b)
if ($fra1<>"" AND $fdec1<>"") {
  $theta1 = round(acos(sin($deltaSol*M_PI/180)*sin($fdecd1*M_PI/180) + cos($deltaSol*M_PI/180)*cos($fdecd1*M_PI/180)*cos(($alphaSol-$frad1)*M_PI/180))*180/M_PI*1000)/1000;
}
if ($fra2<>"" AND $fdec2<>"") {
  $theta2 = round(acos(sin($deltaSol*M_PI/180)*sin($fdecd2*M_PI/180) + cos($deltaSol*M_PI/180)*cos($fdecd2*M_PI/180)*cos(($alphaSol-$frad2)*M_PI/180))*180/M_PI*1000)/1000;
}

if ($fra1<>"" AND $fdec1<>"" AND $fra2<>"" AND $fdec2<>"") {
  $theta3 = round(acos(sin($fdecd1*M_PI/180)*sin($fdecd2*M_PI/180) + cos($fdecd1*M_PI/180)*cos($fdecd2*M_PI/180)*cos(($frad1-$frad2)*M_PI/180))*180/M_PI*1000)/1000;
  echo "<p><font color=\"#0000FF\">Angular distance between Object #1 and Object #2 is: ".$theta3."&deg;</font></p>";
}

if (($fra1<>"" and $fdec1<>"") or ($fra2<>"" and $fdec2<>"")) {
  echo "<table><tr><td>&nbsp;</td><td align=center><b>RA</b></td><td align=center><b>Dec</b></td><td><b>Solar elong.</b></td></tr>";
}
if ($fra1<>"" AND $fdec1<>"") {
  echo "<tr><td>Object #1:</td><td><font color=Maroon>".$fra1."</font></td><td><font color=Maroon>".$fdec1."</font></td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=Maroon>".$theta1."&deg;</font></td></tr>";
}
if ($fra2<>"" AND $fdec2<>"") {
  echo "<tr><td>Object #2:</td><td>".$fra2."</td><td>".$fdec2."</td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".$theta2."&deg;</td></tr>";
}


?>
</body>
</html>
$\endgroup$
  • $\begingroup$ How would you compute the transit/solar noon from the RA and dec? $\endgroup$ – serv-inc Jul 4 '18 at 9:59
  • 1
    $\begingroup$ Local sidereal time is the RA of a star on your meridian and is offset from UT based on your longitude and the date. When your LST matches the Sun's RA then the Sun is on the meridian. (You don't need the Dec here.) $\endgroup$ – Mick Jul 4 '18 at 10:08
  • $\begingroup$ So the LST at longitude (and latitude?) needs to be computed and matched to the RA (of 103.0508°). That is the time of the solar noon? Sounds good. $\endgroup$ – serv-inc Jul 4 '18 at 10:18
  • $\begingroup$ The LST is just longitude-based (as is RA), so yes, when LST and RA of the Sun match then that is solar noon. The RA of the Sun will be slightly different at 8 am local time than at local noon (12 pm) and also at solar noon. $\endgroup$ – Mick Jul 4 '18 at 10:25
  • 1
    $\begingroup$ There are so many aspects besides "looking at stuff in the sky" that I hesitate to suggest anything, but Atlas of the Universe by Sir Patrick Moore is one of the first books that I read. And if that RA calculation works for you, then by all means use it. $\endgroup$ – Mick Jul 4 '18 at 11:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.