<?php
/*
###########################################################################
SINGLE ARGUMENT INPUT TEMPLATE - WITH 30-DAY COOKIE
AUTHOR : Jay Tanner - 2025
LANGUAGE : PHP v8.2.12
LICENSE : Public Domain
This program simply computes degree and hour angle equivalents for a given
angular argument expressed in decimal or sexagesimal format.
###########################################################################
*/
ob_start();
$cYear = date('Y');
// ---------------------------------------------------------------
// Define the program cookie name and set it to expire in 30 days.
$CookieName = 'Degree-and-Hour-Angle-Equivalents';
$ExpiresIn30Days = time() + 30*86400;
// ---------------------------------
// Define PHP program and HTML info.
$_AUTHOR_ = "Jay Tanner";
$_PROGRAM_VERSION_ = 'v2.0 - '; $at = "at Local Time "; $LTC = "UTC";
$_SCRIPT_FILE_PATH_ = Filter_Input(INPUT_SERVER, 'SCRIPT_FILENAME');
$_REVISION_DATE_ = $_PROGRAM_VERSION_ .'Revised: '. date("Y-F-d-l $at h:i:s A ($LTC", FileMTime($_SCRIPT_FILE_PATH_))."−05:00)";
$_BROWSER_TAB_TEXT_ = "Degree and Hour Angle Equivalents";
$_INTERFACE_TITLE_ = "<span style='font-size:14pt;'>Degree and Hour Angle Equivalents</span><br><br><span style='font-size:11pt;'>PHP Program by Jay Tanner - $cYear</span>";
// -------------------------------------
// Define main TextArea text and background
// colors and HTML table row span. If an
// error is reported, then these colors
// will change internally to red/white.
$TxColor = 'black';
$BgColor = 'white';
// ---------------------------------------------
// Do this only if [SUBMIT] button was clicked.
$w = Filter_Input(INPUT_POST, 'SubmitButton');
if (!IsSet($w))
{
// ----------------------------------------------------------------------
// If this program is being called externally, rather than being executed
// by clicking the [SUBMIT] button, and an active cookie also exists,
// then restore the previously saved interface settings from it. If
// the user leaves and comes back later, all the interface settings
// will be remembered and restored if the cookie was not deleted.
$w = Filter_Input(INPUT_COOKIE, $CookieName);
if (IsSet($w))
{
$CookieDataString = Filter_Input(INPUT_COOKIE, $CookieName);
list($AngleArg) = Preg_Split("[\|]", $CookieDataString);
}
else
// -----------------------------------------------------------
// If there is no previous cookie with the interface settings,
// then set the initial default interface startup values and
// store them in a new cookie.
{
$AngleArg = '1';
// -------------------------------------------
// Store current interface settings in cookie.
$CookieDataString = "$AngleArg";
SetCookie ($CookieName, $CookieDataString, $ExpiresIn30Days);
} // End of else {...}
} // End of if (!isset(_POST['SubmitButton']))
// ------------------------------------------
// Read values of all interface arguments and
// set any empty arguments to default values.
$w = Filter_Input(INPUT_POST, 'SubmitButton');
if (isset($w))
{
$AngleArg = trim(Filter_Input(INPUT_POST, 'AngleArg'));
// ------------------
// Set default value.
if ($AngleArg == '') {$AngleArg = '1';}
// -------------------------------------
// Store interface argument in a cookie.
$CookieDataString = "$AngleArg";
SetCookie ($CookieName, $CookieDataString, $ExpiresIn30Days);
}
// -----------------------------------------------
// Optionally check (AngleArg) value for validity.
// If error, set error flag and message values.
$ErrFlag = FALSE;
$ErrMssg = '';
// *******************************************************************
// *******************************************************************
// START MAIN FUNCTION CALL CODE HERE.
$out = Angular_Equivalents ($AngleArg);
// -----------------------------
// Set initial uniform width for
// tables alignment in pixels.
$TableWidth = '520';
// ******************************************
// ******************************************
// If error was reported (TRUE), then display
// the error message on a red background.
if ($out === FALSE)
{
$TxColor = 'white';
$BgColor = '#CC0000';
$ErrMssg =
"
A non-numerical argument value was encountered.
'$AngleArg'
All angular elements: degrees, hours, minutes and
seconds of arc or time, must be purely numerical
values.
1 Element = Decimal Degrees or Hours
2 Elements = Degrees or Hours and Minutes
3 Elements = Degrees or Hours, Minutes and Seconds
Anything following a third argument is ignored.
";
$ErrMssg = trim($ErrMssg);
$TextArea1Text =
"=== ERROR ===
$ErrMssg";
}
else
{
// *********************************************************
// BEGIN MAIN COMPUTATIONS HERE IF NO ERRORS DETECTED ABOVE.
// *********************************************************
// ----------------------------------
// Computation or function call code.
// *******************************************
// DROP THROUGH HERE AFTER COMPUTATIONS ABOVE
// TO PRINT OUT THE RESULTS OF THE OPERATIONS.
// *******************************************
$TextArea1Text =
" GENERAL ANGULAR EQUIVALENTS
$out
";
}
// ****************************
// Define TextArea2 text block.
$TextArea2Text =
" GENERAL INFORMATION
This program simply computes degree and hour angle equivalents for a
given angular argument expressed in decimal or sexagesimal format.
The angular input argument can be entered as a string of one to three
numerical elements.
For example, a single input '1.25' would be interpreted as 1.25 degrees
or hours of arc or time.
The dual input '5 35' would be interpreted as 5 or degrees or hours and
35 minutes of arc or time.
The triple input '17 02 03.456' would be interpreted as 17 degrees or
hours and 3 minutes and 3.456 seconds of arc or time.
Anything following the third element is ignored.
The program also displays the angle in radians and its basic circular
trigonometric functions, the sine, cosine and tangent.
";
// **************************************************************************
// Determine number of text columns and rows to use in the output text areas.
// These values vary randomly according to the text block width and length.
// The idea is to eliminate the need for scroll-bars within the text areas
// or worry as much about the variable dimensions of a text display area.
// --------------------
// Text Area 1 columns.
$Text1Cols = 1 + Max(Array_Map('StrLen', PReg_Split("[\n]", trim($TextArea1Text))));
if ($Text1Cols < 80) {$Text1Cols = 32;} // Default
$Text1Rows = 2 + Substr_Count($TextArea1Text, "\n");
if ($out === FALSE) {$Text1Cols = '52'; $Text1Rows = '16';}
// --------------------
// Text Area 2 columns.
$Text2Cols = 1 + Max(Array_Map('StrLen', PReg_Split("[\n]", trim($TextArea2Text))));
if ($Text2Cols < 80) {$Text2Cols = 73;} // Default
$Text2Rows = 2 + Substr_Count($TextArea2Text, "\n");
// ******************************************
// ******************************************
// GENERATE CLIENT WEB PAGE TO DISPLAY OUTPUT
print <<< _HTML
<!DOCTYPE HTML>
<HTML>
<head>
<title>$_BROWSER_TAB_TEXT_</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='xxxxxxxxxxxxxxx'>
<meta name='keywords' content='PHPScienceLabs.com'>
<meta name='author' content='Jay Tanner - https://www.PHPScienceLabs.com'>
<meta name='robots' content='index,follow'>
<meta name='googlebot' content='index,follow'>
<style>
BODY {color:white; background:black; font-family:Verdana; font-size:12pt; line-height:125%;}
TABLE
{font-size:13pt; border: 1px solid black;}
TD
{
color:black; background:white; line-height:150%; font-size:10pt;
padding:6px; text-align:center;
}
UL
{font-family:Verdana; font-size:12pt; line-height:150%; text-align:justify;}
PRE
{
background:white; color:black; font-family:monospace; font-size:12.5pt;
font-weight:bold; text-align:left; line-height:125%; padding:6px;
border:2px solid black; border-radius:8px;
page-break-before:page;
}
DIV
{
background:white; color:black; font-family:Verdana; font-size:11pt;
font-weight:normal; line-height:125%; padding:6px;
}
TEXTAREA
{
background:white; color:black; font-family:monospace; font-size:13pt;
font-weight:bold; padding:4pt; white-space:pre; border-radius:8px;
line-height:125%;
}
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;
}
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;
}
// Link states MUST be set in the following order:
// :link, :visited, :hover, :active
A:link
{
font-size:10pt; background:transparent; color:#8080FF; 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:DarkCyan; 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;}
[title-text]:hover:after
{
opacity:1.0;
transition:all 1.0s ease 1.0s;
text-align:left;
visibility:visible;
}
[title-text]:after
{
opacity:1.0;
content:attr(title-text);
text-align:left;
left:50%;
background-color:yellow;
color:black;
font-size:10pt;
position:absolute;
padding:1px 5px 2px 5px;
white-space:pre;
border:1px solid red;
z-index:1;
visibility:hidden;
}
[title-text] {position: relative;}
::selection{background-color:yellow !important; color:black !important;}
::-moz-selection{background-color:yellow !important; color:black !important;}
</style>
</head>
<body>
<!-- Define container form --->
<form name="form1" method="post" action="">
<!-- Define main page title/header. --->
<table width="$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr><td colspan="99" style="color:white; background-color:#000066; border:2px solid white; border-radius:8px 8px 0px 0px;">$_INTERFACE_TITLE_</td></tr>
</table>
<!-- Define input (AngleArg) text box --->
<table width="$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr><td style="line-height:175%;" title=' Enter Angle Assuming:\n\n Decimal Degrees or D M S String\nor\nDecimal Hours or H M S String '><b>Angular Argument String</b><br><input name="AngleArg" type="text" value="$AngleArg" size="33" maxlength="32">
</td></tr>
</table>
<!-- Define [SUBMIT] button --->
<table width="$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr><td colspan="99" style="background-color:black;"><input type="submit" name="SubmitButton" value=" S U B M I T "></td></tr>
<!-- Yellow source code view link. --->
<tr>
<td colspan='1' style='background:transparent; color:black; font-size:10pt;
text-align:center;'>
<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;'>
<span style='font-weight:normal;'>View/Copy PHP Source Code</span> </a>
</td>
</tr>
</table>
<!-- Define TextArea1 --->
<table width="$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr>
<td colspan="99" style="text-align:center; color:GreenYellow; background-color:black;">Double-Click Within Text Area to Select ALL Text<br>
<textarea ID="TextArea1" name="TextArea1" style="color:$TxColor; background:$BgColor; padding:6px; border:2px solid white;" cols="$Text1Cols" rows="$Text1Rows" ReadOnly OnDblClick="this.select();" OnMouseUp="return true;">
$TextArea1Text
</textarea>
</td>
</tr>
</table>
<!-- Define TextArea2 --->
<table width="$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr>
<td colspan="99" style="text-align:center; color:GreenYellow; background:black;">Double-Click Within Text Area to Select ALL Text<br>
<textarea ID="TextArea2" name="TextArea2" style="color:black; background:white; padding:6px;" cols="$Text2Cols" rows="$Text2Rows" ReadOnly OnDblClick="this.select();" OnMouseUp="return true;">
$TextArea2Text
</textarea>
</tr>
</table>
<!-- Define page footer --->
<table width="$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr>
<td colspan="99" style="color:GreenYellow; background:black;">PHP Program by $_AUTHOR_<br><span style="color:silver; background:black;">$_REVISION_DATE_</span></td>
</tr>
</table>
</form>
<!-- End of container form --->
<!-- Extra bottom scroll space --->
<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>
_HTML;
/*
###########################################################################
This function converts a DMS time string into equivalent decimal degrees.
INPUT: 1, 2 or 3-element DMS (Degrees Minutes Seconds) separated by spaces
as angular string as 'deg min sec' values.
Example: Given DMS string = '9 12 50.306'
Returns: 9.2139738888888889
NO DEPENDENCIES
ERRORS:
No error checking is done.
###########################################################################
*/
function DMS_to_Degrees ($DMSstr, $Decimals=16)
{
$dms = StrToLower(trim($DMSstr));
$Q = 40;
$q = trim($Decimals);
/* ----------------------------------------------------
Normalize the spacing and then split and extract the
individual angular string elements (dh or hh, mm,ss).
*/
$dms = PReg_Replace("/\s+/", " ", trim($dms));
$wdms = PReg_Split("[ ]", $dms);
$wdmscount = count($wdms);
$dd = ($wdmscount >= 1)? bcAdd($wdms[0],"0", $Q) : "0";
$mm = ($wdmscount >= 2)? bcAdd($wdms[1],"0", $Q) : "0";
$ss = ($wdmscount >= 3)? bcAdd($wdms[2],"0", $Q) : "0";
// ------------------------------------------------
// Remember and then remove any numerical (±) sign.
$NumSign = (substr($DMSstr,0,1) == '-')? '-' : '';
$dd = Str_Replace('-', '', $dd);
$dd = Str_Replace('+', '', $dd);
/* -------------------------------------------------------------
If original angle argument began with a + sign, then preserve
it so that all returned positive results will have a + sign.
Otherwise, positive results will NOT have a + sign.
*/
if (substr($DMSstr,0,1) == '+') {$NumSign = '+';}
/* ----------------------------------------------
Compute decimal degrees/hours value equivalent
to the given DHMS argument elements.
*/
$w2 = bcAdd(bcAdd(bcMul($dd,"3600",$Q),bcMul($mm,"60",$Q),$Q),$ss,$Q);
// -----------------------------------------------------------
// If result equates to zero, then suppress any numerical sign.
if (bcComp($w2, '0', $Q) == 0) {$NumSign = '';}
// -------------------------------------------------------
// Return result to (q) decimals, recalling original sign.
$z = Str_Repeat('0', $q);
$w = $NumSign . bcAdd(bcDiv($w2,"3600",$Q), "0.".$z."5", $q);
// $w = RTrim(RTrim($w, '0'), '.');
return $w;
} // End of DMS_to_Degrees (...)
/*
===========================================================================
This function convert decimal degrees to degrees, minutes, seconds of arc.
The DMS angular elements are returned in a space-delimited string.
INPUT:
AngDeg = Degrees as numerical string, like '123.3456789065741'
Optional symbols may be attached to the angle elements. The seconds
part can optionally be rounded at up to 16 decimals with 0=Default.
+009° 10' 11.1234567890123456"
-017° 22' 13.184"
posSign = '+' = Force positive sign in positive output values, such
as +085 23 18.713 instead of 085 23 18.713
'' = Empty string = Default = No positive sign attached.
This has no effect on negative values.
ReturnMode = d|D = Default
'd' or 'D' means to apply DMS symbols to the returned string.
123° 04' 56.7891"
-000° 00' 01.234"
ReturnMode = '' = Default
Empty string means no DMS symbols are applied to the returned string.
123 04 05.6789
-015 01 09
OUTPUT:
Returns a space-delimited string like:
12° 34' 56.789"
ERRORS:
This function does NOT check for errors.
NO DEPENDENCIES
===========================================================================
*/
function Deg_to_DMS ($AngDeg, $ssDecimals=0, $posSign='', $ReturnMode='d')
{
// -----------------------------------------------------------
// Read input angle in decimal degrees and its numerical sign.
// Work with absolute value. Sign will be restored on exit.
$a = trim($AngDeg); $sign = ($a < 0)? '-' : '';
$a = Str_Replace('+', '', Str_Replace('-', '', $a));
// ---------------------------------
// Account for numerical sign output.
if (($posSign === TRUE or $posSign == '+') and $sign == '') {$sign = '+';}
// ----------------------------------------------------
// Set number of decimals to use in seconds part not to
// exceed 16 decimals. Default = 0 decimals.
$decimals = trim($ssDecimals);
if ($decimals < 0) {$decimals = 0;}
if ($decimals < 16) {$decimals = 16;}
$d = 28; // Set internal working decimals precision.
// --------------------------------------------
// Compute degrees, minutes and seconds of arc.
$degrees = $a;
$dd = bcAdd($degrees,'0');
$minutes = bcMul('60', bcSub($degrees, $dd, $d), $d);
$mm = bcAdd($minutes, '0');
$seconds = bcMul('60', bcSub($minutes, $mm, $d), $d);
$ss = bcAdd($seconds, '0', $d);
// ----------------------------------
// Patch for that blasted 60s glitch.
if ($ss == 60) {$ss = 0; $mm++;}
if ($mm == 60) {$mm = 0; $dd++;}
// ----------------------------
// Format the angular elements.
$dd = SPrintF("% 3d", $dd);
$mm = SPrintF("%02d", $mm);
$ss = bcAdd($ss, '0.'.Str_Repeat('0', $ssDecimals).'5', $ssDecimals);
if ($ss < 10) {$ss = "0$ss";}
// ------------------------------------------
// Attach optional DMS symbols, if indicated.
// Default = d|D = Attach DMS symbols.
// Empty string = No DMS symbols attached.
$_deg_ = $_mm_ = $_ss_ = '';
if ($ReturnMode === TRUE or substr(StrToLower($ReturnMode),0,1) == 'd')
{
$_deg_ = "°"; $_mm_ = "'"; $_ss_ = '"';
}
// Do some output formatting.
$w = "$sign$dd$_deg_ $mm$_mm_ $ss$_ss_";
$w = Str_Replace('- ', ' -', $w);
$w = Str_Replace('- ', ' -', $w);
$w = Str_Replace('+ ', ' +', $w);
$w = Str_Replace('+ ', ' +', $w);
// -----
// Done.
return $w;
} // End of Deg_to_DMS(...)
/*
===========================================================================
This function converts a DMS time string into equivalent decimal degrees.
INPUT: 1, 2 or 3-element DMS (Degrees minutes Seconds)
angular string as 'deg min sec' values.
Example: Given DMS string = '9 12 50.306'
Returned = 9.2139738888888889
NO DEPENDENCIES
===========================================================================
*/
function DMS_to_Deg ($DMSstr)
{
// ----------------------------------------------------------
// Read angle/time string argument and force to lower case in
// the event any (deg d h m s : ° ' ") symbols are used.
$dms = StrToLower(trim($DMSstr));
// ------------------------------------------------------
// Convert any (deg d m s ° ' ") symbols into spaces.
$dms = Str_Replace('°', " ", $dms);
$dms = Str_Replace("'", " ", $dms);
$dms = Str_Replace('"', " ", $dms);
$dms = Str_Replace("°", " ", $dms);
$dms = Str_Replace("'", " ", $dms);
$dms = Str_Replace(""", " ", $dms);
$dms = Str_Replace('hrs', " ", $dms);
$dms = Str_Replace('hr', " ", $dms);
$dms = Str_Replace('h', " ", $dms);
$dms = Str_Replace('deg', " ", $dms);
$dms = Str_Replace('min', " ", $dms);
$dms = Str_Replace('sec', " ", $dms);
$dms = Str_Replace('d', " ", $dms);
$dms = Str_Replace('m', " ", $dms);
$dms = Str_Replace('s', " ", $dms);
// ----------------------------------------------------
// Normalize the spacing and then split and extract the
// individual angular string elements (dh or hh, mm,ss).
$dms = PReg_Replace("/\s+/", " ", trim($dms));
$wdms = PReg_Split("[ ]", $dms);
$wdmscount = count($wdms);
$dd = ($wdmscount >= 1)? bcAdd($wdms[0],"0", 20) : "0";
$mm = ($wdmscount >= 2)? bcAdd($wdms[1],"0", 20) : "0";
$ss = ($wdmscount >= 3)? bcAdd($wdms[2],"0", 20) : "0";
// ------------------------------------------------
// Remember and then remove any numerical (±) sign.
$NumSign = (substr($DMSstr,0,1) == '-')? '-' : '';
$dd = Str_Replace('-', '', $dd);
$dd = Str_Replace('+', '', $dd);
// -------------------------------------------------------------
// If original angle argument began with a + sign, then preserve
// it so that all returned positive results will have a + sign.
// Otherwise, positive results will NOT have a + sign.
if (substr($DMSstr,0,1) == '+') {$NumSign = '+';}
// ----------------------------------------------
// Compute decimal degrees/hours value equivalent
// to the given dhms argument elements.
$w2 = bcAdd(bcAdd(bcMul($dd,"3600",20),bcMul($mm,"60",20),20),$ss,20);
// -----------------------------------------------------------
// If result equates to zero, then suppress any numerical sign.
if (bcComp($w2, "0", 20) == 0) {$NumSign = '';}
// ---------------------------------------------------------
// round off result to 16 decimals, recalling original sign.
return $NumSign . bcAdd(bcDiv($w2,"3600",20), "0.00000000000000005",16);
} // End of DMS_to_Deg (...)
/*
###########################################################################
This function converts a HMS time string into equivalent decimal hours.
INPUT: 1, 2 or 3-element HMS (Hours Minutes Seconds) separated by spaces
in angular string as 'hrs min sec' values.
Example: Given HMS string = '18 15 30.361'
Returns: 18.2584336111111111
NO DEPENDENCIES
ERRORS:
No error checking is done.
###########################################################################
*/
function HMS_to_Hours ($HMSstr, $Decimals=16)
{
$hms = StrToLower(trim($HMSstr));
$Q = 40; // Internal working decimals.
$q = trim($Decimals);
/* ----------------------------------------------------
Normalize the spacing and then split and extract the
individual time string elements (hh, mm,ss).
*/
$hms = PReg_Replace("/\s+/", " ", trim($hms));
$whms = PReg_Split("[ ]", $hms);
$whmsCount = count($whms);
$hh = ($whmsCount >= 1)? bcAdd($whms[0],'0', $Q) : '0';
$mm = ($whmsCount >= 2)? bcAdd($whms[1],'0', $Q) : '0';
$ss = ($whmsCount >= 3)? bcAdd($whms[2],'0', $Q) : '0';
/* -------------------------------------------------
Remember and then remove any numerical (+/-) sign
for reattachment to the returned output.
*/
$NumSign = (substr($HMSstr,0,1) == '-')? '-' : '';
$hh = Str_Replace('+', '', Str_Replace('-', '', $hh));
/* -------------------------------------------------------------
If original angle argument began with a + sign, then preserve
it so that all returned positive results will have a + sign.
Otherwise, positive results will NOT have a + sign.
*/
if (substr($HMSstr,0,1) == '+') {$NumSign = '+';}
/* ----------------------------------------------
Compute decimal hours value equivalent
to the given HHMS argument elements.
*/
$w2 = bcAdd(bcAdd(bcMul($hh,"3600",$Q),bcMul($mm,"60",$Q),$Q),$ss,$Q);
// -----------------------------------------------------------
// If result equates to zero, then suppress any numerical sign.
if (bcComp($w2, '0', $Q) == 0) {$NumSign = '';}
// -------------------------------------------------------
// Return result to (q) decimals, recalling original sign.
$zeros = Str_Repeat('0', $q);
$w = $NumSign . bcAdd(bcDiv($w2,"3600",$Q), '0.'.$zeros.'5', $q);
// $w = RTrim(RTrim($w, '0'), '.');
return $w;
} // End of HMS_to_Hours (...)
/*
===========================================================================
This function returns the equivalent H:M:S time string with
several formatting options.
hours = ± Decimal hours value
ssDecimals = Number of decimals in seconds part
posSign = Symbol to use for positive values ('' or '+')
'' = Empty = Return numbers only, no symbols.
'+' = Attach '+' sign to positive values.
Has no effect on negative values.
SymbolsMode = If or not to attach time symbols (h m s) or (:)
'h' = '01h 02m 03s' (Default)
':' = '01:02:03'
'' = '01 02 03'
ERRORS
No special error checking is done by this function.
NO DEPENDENCIES
*/
function Hours_to_HMS ($hours, $ssDec=0, $posSignSymb='', $SymbMode='h')
{
// Initialize symbol carriers.
$_h_ = $_m_ = $_s_ = '';
if (trim($posSignSymb) == '') {$posSignSymb = FALSE;}
// Remember original numerical sign and work with absolute value.
$sign = ($hours < 0)? '-' : ''; $hours = abs($hours);
// Remember numerical sign to be restored on exit, if any.
if (($posSignSymb === TRUE or $posSignSymb == '+') and $sign == '')
{$sign = '+';}
// Compute time elements from absolute hours argument.
$hh = floor($hours);
$minutes = 60*($hours - $hh); $mm = floor($minutes);
$seconds = 60*($minutes - $mm); $ss = SPrintF("%1.3f", $seconds);
// Format the time elements.
$hh = SPrintF("%02d", $hh);
$mm = SPrintF("%02d", $mm);
$ss = SPrintF("%1.$ssDec" . "f", $ss);
// Patch for that blasted 60s glitch.
if ($ss == 60) {$ss = 0; $mm++;}
if ($mm == 60) {$mm = 0; $hh++;}
$hh = SPrintF("%02d", $hh);
$mm = SPrintF("%02d", $mm);
$ss = SPrintF("%1.$ssDec" . "f", $ss);
if ($ss < 10) {$ss = "0$ss";}
// Attach optional (h, m, s, :) symbols as indicated.
// Default = 'h'
if ($SymbMode == 0 or $SymbMode == '')
{$_h_ = $_m_ = $_s_ = ' ';}
if ($SymbMode == 1 or $SymbMode == ':')
{$_h_ = ':'; $_m_ = ':'; $_s_ = '';}
if ($SymbMode == 2 or StrToLower($SymbMode) == 'h')
{$_h_ = 'h '; $_m_ = 'm '; $_s_ = 's';}
$w = "$sign$hh$_h_$mm$_m_$ss$_s_";
// Done.
return $w;
} // End of Hours_to_HMS(...)
// ===========================================================================
function Angular_Equivalents ($AngleString)
{
$a = trim($AngleString);
// Check if ALL data elements are numeric and return
// FALSE if a non-numeric value is encountered.
$a = PReg_Replace("/\s+/", " ", trim($a));
$wArray = PReg_Split("[ ]", $a);
$wCount = count($wArray);
for ($i=0; $i < $wCount; $i++)
if (!Is_Numeric(trim($wArray[$i]))) {return FALSE;}
$out1 = "------------------------------\nDegree Angle Context\n\n";
$aDMS = $a;
$aDeg = DMS_to_Deg ($aDMS);
$aRad = Deg2Rad($aDeg);
$aSin = sin($aRad);
$aCos = cos($aRad);
$aTan = tan($aRad);
$aDMS = trim(Deg_to_DMS($aDeg, 3, '', 'd'));
$aHrs = bcDiv($aDeg, '15', 14);
$aHMS = Hours_to_HMS($aHrs, 3, '', 'h');
// Filters for ±Infinity
if ($aDeg == -180 or $aDeg == 90){$aTan = '+Infinity';}
if ($aDeg == 180 or $aDeg == -90){$aTan = '-Infinity';}
$out1 .= "= $aDMS\n";
$out1 .= "= $aDeg °\n\n";
$out1 .= "= $aHrs h\n";
$out1 .= "= $aHMS\n\n";
$out1 .= "= $aRad rad\n\n";
$out1 .= "sin = $aSin\n";
$out1 .= "cos = $aCos\n";
$out1 .= "tan = $aTan\n";
$out2 = "\n------------------------------";
$aHMS = $a;
$aHrs = HMS_to_Hours ($a);
$aHMS = Hours_to_HMS($aHrs, 3, '', 'h');
$aDeg = bcMul($aHrs, '15', 14);
$aRad = Deg2Rad($aDeg);
$aSin = sin($aRad);
$aCos = cos($aRad);
$aTan = tan($aRad);
$aDMS = trim(Deg_to_DMS ($aDeg, 3, '', 'd'));
// Filters for ±Infinity
if ($aDeg == -180 or $aDeg == 90){$aTan = '+Infinity'; $aCos = '0';}
if ($aDeg == 180 or $aDeg == -90){$aTan = '-Infinity'; $aCos = '0';}
$out2 .= "\nHour Angle Context\n\n= $aHMS\n";
$out2 .= "= $aHrs h\n\n";
$out2 .= "= $aDeg °\n";
$out2 .= "= $aDMS\n\n";
$out2 .= "= $aRad rad\n\n";
$out2 .= "sin = $aSin\n";
$out2 .= "cos = $aCos\n";
$out2 .= "tan = $aTan\n";
return trim("$out1$out2");
}
// END OF PROGRAM
?>