<?php
/* EARTH PERIHELION CALCULATOR
LANGUAGE : PHP V8.2.12
AUTHOR : Jay Tanner - 2026
LICENSE : Public Domain
*/
// --------------------
// Check submit button.
$w = Filter_Input(INPUT_POST, 'SubmitButton');
if (IsSet($w))
{
$Year = trim(Filter_Input(INPUT_POST, 'Year'));
if ($Year == '') {$Year = date('Y');}
$TimeZone = trim(Filter_Input(INPUT_POST, 'TimeZone'));
if ($TimeZone == '') {$TimeZone = '+00:00';}
}
else
{
$Year = date('Y');
$TimeZone = '+00:00';
}
$ObjID = '10';
$StartDate = SPrintF("%04d", $Year-1) . '-Dec-01';
$StopDate = SPrintF("%04d", $Year+0) . '-Dec-31';
$Ephemeris = Earth_Perihelion ($ObjID, $StartDate, $StopDate, $TimeZone);
print <<< _HTML
<!DOCTYPE HTML>
<HTML lang="en-us">
<head>
<title>Earth Perihelion Calculator</title>
</head>
<body>
<!-- Top yellow source code view link. --->
<br>
<table width="420" align="bottom" cellspacing="1" cellpadding="3">
<tr>
<td colspan="1" style='font-size:10pt; color:black; background:white;
text-align:left;' title=' Tries to Open in a New Tab. '>
<b><a href="View-Source-Code.php" target="_blank"
style='font-family:Verdana; color:black; background:yellow;
text-decoration:none; border:1px solid black; padding:4px;
border-radius:4px; box-shadow:2px 2px 5px #444444;
font-weight:normal;'>
View/Copy Source Code </a></b>
</td>
</tr>
</table>
<form name="Form1" method="post" action="">
<table align="top" bgcolor="white" width="550" border="1" cellspacing="1">
<tr><td style='font-family:Verdana; padding:8px; text-align:center;'><div align="center"><b>EARTH PERIHELION CALCULATOR</b><br><span style='font-size:9pt;'>via The NASA/JPL Horizons API<br>PHP Program by Jay Tanner</span></div>
<br>
Enter Year <input name="Year" type="text" size="5" value="$Year"
style='font-family:monospace; font-size:11pt; text-align:center;'>
Time Zone
<input name="TimeZone" type="text" size="7" value="$TimeZone"
style='font-family:monospace; font-size:11pt; text-align:center;'>
<input name="SubmitButton" type="submit" value="S U B M I T">
<br><br>
<b><pre style='font-size:11pt; text-align:left;'>
Earth Perihelion $Year
In Time Zone UT$TimeZone
PERIHELION_DISTANCE
===========================================
Calendar_Date Time AU Km Mi
============= ===== ============== ============= ============
$Ephemeris
</pre></b>
</td></tr>
</table>
</form>
</body>
</HTML>
_HTML;
function Earth_Perihelion ($ObjID, $StartDate, $StopDate, $TimeZone)
{
$Command = URLEncode($ObjID);
$StartDate = trim($StartDate);
$StopDate = trim($StopDate);
$TimeZone = trim($TimeZone);
$xStartDate = $StartDate;
$From_Horizons_API =
"https://ssd.jpl.nasa.gov/api/horizons.api?format=text" .
"&MAKE_EPHEM='YES'" .
"&EPHEM_TYPE='OBSERVER'" .
"&CENTER='500@399'" .
"&COMMAND='$Command'" .
"&TIME_ZONE='$TimeZone'" .
"&START_TIME='$StartDate'" .
"&STOP_TIME='$StopDate'" .
"&STEP_SIZE='1 DAY'" .
"&QUANTITIES='20'" .
"&CSV_FORMAT='YES'" .
"&OBJ_DATA='NO'" ;
$w = trim(File_Get_Contents($From_Horizons_API));
$w = Str_Replace(",\n","\n", $w);
/* -----------------------------------------------------
Set pointers to start and end of CSV ephemeris table.
A value of FALSE means no ephemeris was found within
the given source text.
*/
$i = StrPos($w, '$$SOE');
$j = StrPos($w, '$$EOE');
/* ----------------------------------------------
Extract and fetch ONLY the existing ephemeris
data line from between the pointers.
*/
$w = trim(substr($w, $i+5, $j-$i-5));
// Cycle through days to find where the (deldot) value
// changes from negative to positive (perihelion point).
$wArray = PReg_Split("[\n]", $w);
$wCount = count($wArray);
$output = $wLine = '';
for ($i=1; $i < $wCount; $i++)
{
$PrevLine = $wArray[$i-1];
list($PrevDateTime, $u, $u, $u, $u) = PReg_Split("[,]", $PrevLine);
$CurrLine = $wArray[$i+0];
list($CurrDateTime, $u, $u, $DistAU, $deldot) = PReg_Split("[,]", $CurrLine);
if (trim($deldot) > 0)
{
$StartDateTime = substr(trim($PrevDateTime),0,17) . '';
$StopDateTime = substr(trim($CurrDateTime),0,17) . '';
$From_Horizons_API =
"https://ssd.jpl.nasa.gov/api/horizons.api?format=text" .
"&MAKE_EPHEM='YES'" .
"&EPHEM_TYPE='OBSERVER'" .
"&CENTER='500@399'" .
"&COMMAND='$Command'" .
"&TIME_ZONE='$TimeZone'" .
"&START_TIME='$StartDateTime'" .
"&STOP_TIME='$StopDateTime'" .
"&STEP_SIZE='1 MINUTE'" .
"&QUANTITIES='20'" .
"&CSV_FORMAT='YES'" .
"&OBJ_DATA='NO'" ;
$w = trim(File_Get_Contents($From_Horizons_API));
$w = Str_Replace(",\n","\n", $w);
/* -----------------------------------------------------
Set pointers to start and end of CSV ephemeris table.
A value of FALSE means no ephemeris was found within
the given source text.
*/
$i = StrPos($w, '$$SOE');
$j = StrPos($w, '$$EOE');
/* ----------------------------------------------
Extract and return ONLY the existing ephemeris
data line from between the pointers.
*/
$w = trim(substr($w, $i+5, $j-$i-5));
// Cycle through minutes to find where the (deldot) value
// changes from negative to positive (perihelion point).
$wArray = PReg_Split("[\n]", $w);
$wCount = count($wArray);
$output = $wLine = '';
for($i=0; $i < $wCount; $i++)
{
$CurrLine = trim($wArray[$i]);
if (trim(substr($CurrLine, -10)) > 0)
{
$output = substr($CurrLine, 0,39);
$output = Str_Replace(',', '', $output);
$DistAU = SPrintF("%1.12f", trim(substr($output, -17)));
$output = substr($CurrLine, 0,17) . " $DistAU";
$output = Str_Replace(' ', ' ', $output);
$DistKm = $DistAU * 149597870.7;
$DistMi = $DistKm / 1.609344;
$DistMi = Number_Format(SPrintF("%11.1f", $DistMi), 1);
$DistKm = Number_Format(SPrintF("%11.1f", $DistKm), 1);
$output .= " $DistKm $DistMi";
// return " $output ";
return ' ' . Str_Replace(' ', ' ', $output);
}
}
return "No Earth perigees found within search span.";
}
}
}
?>