<?php
/*
===============================================================
3-MONTH DELTA-T TABLE CENTERED ON THE CURRENT MONTH.
Built around the NASA/JPL Horizons API
This program will generate a table of Delta-T (TDB-UT) values
for the three-month period centered on the current month. The
three-month window should update automatically with the time.
AUTHOR : Jay Tanner - 2025
LANGUAGE : PHP v8.2.12
LICENSE : Public Domain
===============================================================
*/
// -------------------------------------------------------------
// Construct start/stop calling arguments. The table spans three
// months from 1 month into the past to 1 month into the future
// centered on the current month according to the system clock.
// P = Past x
// C = Current x
// F = Future x
// y = Year number
// m = Month number
// Mmm = 3-letter abbreviation of English month name.
// -------------
// Current year.
$cYear = date('Y');
// --------------------------
// Force to 'UTC' time scale.
$TimeScale = 'UTC';
// ---------------------------
// Get current year and month.
$Cym = GMDate("Y-F");
// ----------------------------------------------------
// Construct date time elements for 3-month table span.
$Py = $Cy = $Fy = date('Y');
$Cm = date('n');
$Pm = $Cm - 1;
$Fm = $Cm + 2;
if ($Pm == 0){$Py -= 1; $Pm = 12; $Cy -= 1;}
if ($Fm == 13 or $Fm == 14)
{
$Fy += 1; if ($Fm == 13) {$Fm = 1;} else {$Fm = 2;}
}
// -------------------------------------------------
// Define 3-letter English month name abbreviations.
$MONTHS = 'JanFebMarAprMayJunJulAugSepOctNovDec';
// -------------------------------------------------------
// Construct Past, Current and Future month abbreviations.
$PMmm = substr($MONTHS, 3*($Pm-1), 3);
$CMmm = substr($MONTHS, 3*($Cm-1), 3);
$FMmm = substr($MONTHS, 3*($Fm-1), 3);
// ------------------------------------------------
// Construct Horizons API calling argument strings.
// Either the UTC or the TT time scale can be used.
$StartDate = "$Py-$PMmm-01";
$StartTime = '00:00:00';
$TimeScale = 'UTC';
$StepSize = '1 day';
$StopDate = "$Fy-$FMmm-01";
$StopTime = '00:00:00';
// ----------------------------------------------------------
// Call the function to generate the Delta-T ephemeris table.
$DeltaTTable = Delta_T_Table ($StartDate, $StartTime, $TimeScale,
$StopDate, $StopTime, $StepSize);
// ------------------------------------------------------
// Special patch to reconstruct the table with the months
// separated by a blank line for easier readability.
$wArray = PReg_Split("[\n]", $DeltaTTable);
$wCount = count($wArray);
$DeltaTTable = '';
for($i=0; $i < $wCount; $i++)
{
$CurrLine = trim($wArray[$i]) . "\n";
$w = substr(trim($CurrLine),0,1);
$u = '';
if (Is_Numeric($w))
{
$A = substr(trim($wArray[$i+1]),5,3);
$B = substr(trim($wArray[$i+0]),5,3);
if ($A <> $B)
{
$u = "\n";
}
$DeltaTTable .= ($CurrLine . $u);
}
else
{
$DeltaTTable .= trim($CurrLine)."\n";
}
}
// --------------------------------
// Remove final asterisk line(***).
// $DeltaTTable = Str_Replace("***********************************************\n", "", $DeltaTTable);
$Text1Cols = 1 + Max(Array_Map('StrLen', PReg_Split("[\n]", trim($DeltaTTable))));
if ($Text1Cols < 80) {$Text1Cols = 47;}
$Text1Rows = 2 + Substr_Count($DeltaTTable, "\n");
// ---------------------------------
// Generate the client HTML page to
// display the table computed above.
print <<< _HTML
<!DOCTYPE HTML>
<HTML lang='en-us'>
<head>
<title>3-Month Delta T Table</title>
<meta name='viewport' content='width=device-width, initial-scale=0.8'>
<meta http-equiv='content-type' content='text/html; charset=UTF-8'>
<meta http-equiv='pragma' content='no-cache'>
<meta http-equiv='expires' content='-1'>
<meta name='description' content='3-Month Delta T table'>
<meta name='keywords' content='Delta T, Delta T table PHPScienceLabs.com'>
<meta name='author' content='Jay Tanner - https://www.PHPScienceLabs.com'>
<meta name='robots' content='noindex,nofollow'>
<meta name='googlebot' content='noindex,nofollow'>
<style>
BODY
{background:black;}
TD
{font-family:Verdana;}
INPUT[type='text']::-ms-clear {width:0; height:0;}
INPUT[type='text']
{
font-family:monospace; color:black; background:white; font-size:13pt;
font-weight:bold; text-align:center; box-shadow:2px 2px 3px #666666;
border:2px solid black; border-radius:4px;
}
INPUT[type='text']:focus
{
font-family:monospace; background:white; box-shadow:2px 2px 3px #666666;
font-size:13pt; border:2px solid blue; text-align:center; font-weight:bold;
border-radius:4px;
}
TEXTAREA
{
background:white; color:black; font-family:monospace; font-size:11pt;
font-weight:bold; line-height:130%; padding:8px;
}
INPUT[type='submit']
{
background:black; color:cyan; font-family:Verdana; font-size:10pt;
font-weight:bold; border-radius:4px; border:4px solid #777777;
padding:3pt;
}
INPUT[type='submit']:hover
{
background:black; color:white; font-family:Verdana; font-size:10pt;
font-weight:bold; border-radius:4px; border:4px solid red;
padding:3pt;
}
A:link
{
font-size:10pt; background:transparent; color:cyan; border-radius:4px;
font-family:Verdana; font-weight:bold; text-decoration:none;
line-height:175%; padding:3px; border:1px solid transparent;
}
A:visited
{
font-size:10pt; background:transparent; color:cyan; border-radius:4px;
}
A:hover
{
font-size:10pt; background:yellow; color:black; border:1px solid black;
box-shadow:1px 1px 3px #222222; border-radius:4px;
}
A:active
{
font-size:10pt; background:yellow; color:black; border-radius:4px;
}
HR {background:red; height:4px; border:0px;}
::selection{background-color:yellow !important; color:black !important;}
::-moz-selection{background-color:yellow !important; color:black !important;}
</style>
</head>
<body>
<br><br>
<form name='form1' method='POST' action=''>
<table>
<tr><td style='color:white; background:#000066; font-family:Verdana; text-align:center; border:2px solid white; border-radius:8px 8px 0px 0px; line-height:125%; padding:8px;'>
<span style='font-size:18pt;'>3-Month ΔT (TDB − UTC) Table<br></span><br><span style='color:white; font-size:14pt;'>Centered on the Current Month $Cym</span><br>
<span style='font-size:10.5pt; color:white;'>Built Around The NASA/JPL Horizons API</span>
<br><br>
<span style='font-size:10pt; color:silver;'>PHP Program by Jay Tanner - $cYear</span>
</td></tr>
<tr><td style='text-align:center;'>
</td></tr>
<tr><td style='text-align:center;'>
<span style='color:lime; font-size:10pt;'>Double-Click Within Text Area to Select ALL Text</span>
<br><br>
<textarea name='TextArea1' cols="$Text1Cols" rows="$Text1Rows" ReadOnly OnDblClick='this.select();' OnMouseUp='return true;'>
$DeltaTTable
</textarea></td></tr>
<tr>
<td colspan="1" style="background:transparent; color:black; font-size:10pt;
text-align:center;">
<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;'>
View/Copy PHP Source Code </a></b>
</td>
</tr>
</table>
</form>
<br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br>
</body>
</HTML>
<!-- End of client HTML page --->
_HTML;
/*
This function returns a table of Delta-T (TDB-UT) values
for any specified time span and tabular interval based
on the NASA/JPL Horizons API.
The tabulated as UTC vs Delta T
*/
function Delta_T_Table ($StartDate, $StartTime, $TimeScale,
$StopDate, $StopTime, $StepSize)
{
// =========================================================
// CONSTRUCT CALLING URL FOR JPL HORIZONS API.
// FORCED TO UT MODE FOR THIS PROGRAM.
$FROM_HORIZONS_API_QUERY =
"https://ssd.jpl.nasa.gov/api/horizons.api?format=text" .
"&COMMAND='0'" .
"&MAKE_EPHEM='YES'" .
"&OBJ_DATA='NO'" .
"&CENTER='500@399'" .
"&TIME_DIGITS='SECONDS'" .
"&START_TIME='$StartDate $StartTime UT'" .
"&STOP_TIME='$StopDate $StopTime'" .
"&STEP_SIZE='$StepSize'" .
"&QUANTITIES='30'" .
"&CAL_FORMAT='BOTH'";
// ==============================================================
// Send query to Horizons API to get the requested Delta-T table.
$w = trim(File_Get_Contents(Str_Replace(' ', '%20', $FROM_HORIZONS_API_QUERY)));
// -------------------------------------------------------------
// Extract contents of ephemeris table between the start '$$SOE'
// marker and the end of ephemeris '$$EOE' marker.
$i = StrPos($w, '$$SOE');
if ($i === FALSE)
{return "ERROR: Check API Calling Arguments.\n\n$w";}
$j = StrPos($w, '$$EOE');
$w = trim(substr($w, $i+5, $j-$i-5));
$cYear = GMDate('Y');
// -----------------------------------------------------------
// Store Delta T ephemeris table in working text string array.
$wTable = '';
$wArray = Preg_Split("[\n]", $w);
$wCount = count($wArray);
// --------------------------------------
// Extract individual ephemeris elements.
for ($i=0; $i < $wCount; $i++)
{
$CurrLine = PReg_Replace("/\s+/", " ", trim($wArray[$i]));
list
(
$DateString,
$TimeString,
$JDate,
$DeltaTSec
) = PReg_Split("[ ]", $CurrLine);
// ------------------------------------
// Remember numerical sign for Delta-T.
$NumSign = ($DeltaTSec < 0)? '-':'+'; $DeltaTSec = abs($DeltaTSec);
// -----------------------------------------
// Compute JD number from Julian date value.
$JDNum = floor($JDate + 0.5);
// ----------------------------------------------
// Determine DoW string to append to date string.
$DoW = JDDayofWeek($JDNum, 2);
// ----------------------------------------------
// Compute Delta-T as HMS string corresponding to
// the seconds value and do some re-formatting to
// display Delta T in three text output formats.
$h = 'h'; $m = 'm'; $s = 's';
$hours = $DeltaTSec/3600;
$hh = floor($hours);
$min = 60*($hours - $hh);
$mm = floor($min);
$sec = 60*($min - $mm);
$hh = SPrintF("%02d", $hh);
$mm = SPrintF("%02d", $mm);
$ss = SPrintF("%09.6f", $sec);
$DTHMS = "$NumSign$hh$h $mm$m $ss$s";
$DThms = "$NumSign$hh:$mm:$ss";
$DeltaTSec = SPrintF("% +12.6f", $NumSign.$DeltaTSec);
// Get current year and month.
$Cy = date('Y');
$CMmm = date('M');
$LCMmm = date('F'); // Full month name.
$TimeScale .= ($TimeScale == 'TT')? ' ':'';
// ---------------------------------------
// Construct and append output table line.
$wTable .= ((substr($DateString,0,1) == 'b')? '':' ') . trim("$DateString-$DoW") . "$DeltaTSec$s $DTHMS\n";
}
$xSpace = (substr(trim($wTable),0,1) == 'b')? '':' ';
$wTable = trim($wTable);
$wTable =
"**********************************************
Three-Month Delta T (TDB − UTC) Table Centered
on the Current Month ($Cy-$LCMmm).
From : $StartDate 00:00:00 $TimeScale
To : $StopDate $StopTime $TimeScale
At : 00:00:00 $TimeScale on each date
Where : TDB = UTC + Delta T
: UTC = TDB − Delta T
==============================================
Calendar Date Delta T = (TDB − UTC)
=============== =============================
$xSpace$wTable
***********************************************";
// --------------------------------------------------
// Do some reformatting for neatness and compactness.
$wTable = Str_Replace('+00h ', '+', $wTable);
$wTable = Str_Replace('+00:', '+', $wTable);
// Done.
return trim($wTable);
} // End of Delta_T_Table (...)
?>