<?php
/*
############################################################################
This program computes temperature equivalents on eight scales, including
four obsolete scales for historical reference.
AUTHOR : Jay Tanner - 2025
LANGUAGE : PHP v8.2.12
LICENSE : Public Domain
############################################################################
-------------------
VALID SCALE SYMBOLS
SYMBOL SCALE
------ -----------
F Fahrenheit
C Celsius
K Kelvin
R Rankine
N Newton
Re Réaumur
Ro Rømer
De Delisle
-------------------
The N, Re, Ro and De scales are now
obsolete, but may be encountered in
very old scientific literature and
are included here as an historical
reference for researchers.
Includes:
SmoothScroll.js derived from the original Butter JavaScript.
https://www.cssscript.com/smooth-momentum-scrolling-butter/
*/
ob_start();
// Define the program cookie name and set it to expire in 30 days.
// This cookie can be shared by other programs in the same common
// home folder together.
$CookieName = 'Temperature_Scale_Equivalents';
$SetToExpireIn30Days = time() + 30*86400;
// Define script path and filename.
$_AUTHOR_ = 'Jay Tanner';
$_PROGRAM_VERSION_ = ''; $at = "at"; $UTC = "UTC";
$_SCRIPT_PATH_ = Filter_Input(INPUT_SERVER, 'SCRIPT_FILENAME');
$_RUN_ = Filter_Input(INPUT_POST, 'SCRIPT_NAME');
// Define internal document page title, HTML page heading text and revision date
$_INTERNAL_TITLE_ = "Temperature Scale Equivalents";
$_INTERFACE_TITLE_ = "<span style='font-size:15pt; line-height:150%;\'>Temperature Scale Equivalents Calculator</span>";
$_REVISION_DATE_ = $_PROGRAM_VERSION_ .'Revised: '. GMDate("l, F d, Y $at h:i:s A $UTC", FileMTime($_SCRIPT_PATH_));
// Define main TextArea text, background
// colors and HTML table row span.
$TxColor = 'black';
$BgColor = 'white';
$ColSpan = 7;
// Do this only if [COMPUTE] button was clicked.
$w = Filter_Input(INPUT_POST, 'ComputeButton');
if (!IsSet($w))
// ----------------------------------------------------
// If [COMPUTE] button was clicked and an active cookie
// exists, then restore the previous interface settings
// from it.
{
$w = Filter_Input(INPUT_COOKIE, $CookieName);
if (IsSet($w))
{
$CookieDataString = Filter_Input(INPUT_COOKIE, $CookieName);
list($Temperature) = Preg_Split("[\|]", $CookieDataString);
}
else
// Set the initial default interface startup values.
{
$Temperature = '0';
// Store interface settings in cookie.
$CookieDataString = $Temperature;
setcookie ($CookieName, $CookieDataString, $SetToExpireIn30Days);
}
} // End of if (!isset(_POST['ComputeButton']))
// =======================================
// Read values of all interface arguments.
// Empty value is set to zero by default.
$w = Filter_Input(INPUT_POST, 'ComputeButton');
if (isset($w))
{
$Temperature = trim(Filter_Input(INPUT_POST, 'Temperature'));
if ($Temperature == '') {$Temperature = '0';}
if (is_Numeric($Temperature)) {$Temperature .= ' F';}
// ------------------------------------
// Store interface arguments in cookie.
$CookieDataString = "$Temperature";
SetCookie ($CookieName, $CookieDataString, $SetToExpireIn30Days);
}
// ========================================
// Check for error. FALSE = Error detected.
// Change this code to detect errors.
//
// Valid scale symbols: F C K R Re Ro N De
$ErrFlag = TRUE;
// ================================
// Check if error (FALSE) detected.
if ($ErrFlag === FALSE)
{
$TxColor = 'white';
$BgColor = '#CC0000';
$TextArea2Text = '';
$TextArea1Text =
"=== ERROR ====================================================================
$ErrMssg";
}
else
// ===================================================
// Begin computations here if no error detected above.
{
$SubAbsZeroText = '';
// Fix spacing of argument, if necessary.
$Temperature = UCFirst(Separate_Num_and_Text($Temperature));
$TempValue = FloatVal($Temperature);
$TempScale = UCFirst(trim(substr(StrToLower($Temperature), -2)));
$Temperature = trim("$TempValue $TempScale");
if($Temperature == '0 0') {$Temperature = '0 F';}
// Compute equivalent on K scale and then convert
// the K value into all the other scales.
// F C K R Re Ro N De
$F = Temp_to_Temp ($Temperature, 'F');
$C = Temp_to_Temp ($Temperature, 'C');
$R = Temp_to_Temp ($Temperature, 'R');
$K = Temp_to_Temp ($Temperature, 'K');
$Re = Temp_to_Temp ($Temperature, 'Re');
$Ro = Temp_to_Temp ($Temperature, 'Ro');
$N = Temp_to_Temp ($Temperature, 'N');
$De = Temp_to_Temp ($Temperature, 'De');
if ($K < 0) {$TxColor = 'white'; $BgColor = '#CC0000'; $SubAbsZeroText = "\n WARNING:\n The given temperature is below absolute zero,\n but the computations were performed anyway.\n\n";
}
$Equivalents = '';
$TextArea1Text =
" TABLE OF TEMPERATURE SCALE EQUIVALENTS
$SubAbsZeroText
COMMON SCALES:
Celsius $C C
Fahrehneit $F F
ABSOLUTE SCALES:
Kelvin $K K
Rankine $R R
OBSOLETE SCALES:
Newton $N N
Réaumur $Re Re
Rømer $Ro Ro
Delisle $De De";
}
$i = StrPos($TextArea1Text, 'ERROR: Temp_to_Temp()');
if ($i !== FALSE)
{
$TextArea1Text =
" ERROR:
Unknown temperature scale symbol.
-------------------
VALID SCALE SYMBOLS
SYMBOL SCALE
------ -----------
F Fahrenheit
C Celsius
K Kelvin
R Rankine
N Newton
Re Réaumur
Ro Rømer
De Delisle
-------------------
";
$TxColor = 'white';
$BgColor = 'maroon';
}
// Get rid of signed zero value.
$TextArea1Text = Str_Replace(' +0 ', ' 0 ', $TextArea1Text);
// Get rid of all positive signs (+).
$TextArea1Text = Str_Replace('+', '', $TextArea1Text);
// Determine the number of text rows to use in the output TextAreas.
$TextArea1Rows = 3 + substr_count($TextArea1Text, "\n");
print <<< _HTML
<!DOCTYPE HTML>
<HTML lang='en-us'>
<head>
<title>Temperature Scale Equivalents Calculator</title>
<meta name='viewport' content='width=device-width, initial-scale=0.54'>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="description" content="Temperature Scale Equivalents Calculator">
<meta name="keywords" content="temperature converter, temperature scales, Fahrenheit, Celsius, converter, scale">
<meta name="author" content="Jay Tanner - NeoProgrammics PHPScienceLabs">
<meta http-equiv='pragma' content='no-cache'>
<meta http-equiv='expires' content='-1'>
<meta name='robots' content='index,follow'>
<meta name='googlebot' content='index,follow'>
<style type='text/css'>
BODY
{
background:black; color:white; font-family:Verdana; font-size:12pt;
line-height:125%;
}
TABLE
{font-family:Verdana;}
TD
{
color:black; background:white; line-height:150%; font-size:10pt;
padding:6px; text-align:center;
}
OL
{font-family:Verdana; font-size:12pt; line-height:150%; text-align:justify;}
UL
{font-family:Verdana; font-size:12pt; line-height:150%; text-align:justify;}
LI
{font-family:Verdana; line-height:150%;}
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:black; color:black; font-family:Verdana; font-size:11pt;
font-weight:normal; line-height:125%; padding:6px;
}
TEXTAREA
{
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']
{
background:white; color:black; font-family:monospace; font-size:15pt;
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:15pt; 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:13pt;
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:13pt;
font-weight:bold; border-radius:4px; border:4px solid red;
padding:3pt;
}
/* -------------------------------------------
Link states below MUST be defined in CSS in
the following sequence to work correctly:
: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;}
[data-title]:hover:after
{
opacity:1.0;
transition:all 1.0s ease 1.0s;
text-align:left;
visibility:visible;
}
[data-title]:after
{
opacity:1.0;
content:attr(data-title);
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;
}
[data-title] {position: relative;}
::selection{background-color:yellow !important; color:black !important;}
::-moz-selection{background-color:yellow !important; color:black !important;}
</style>
</head>
<body>
<div ID='SmoothScroll' style='background:black;'>
<form name='form1' method='post' action="$_RUN_">
<table width='460' border='0' cellspacing='1' cellpadding='3' align='left'>
<tr><td colspan="$ColSpan" style='color:white; background-color:#000066; border:2px solid white; border-radius:8px 8px 0px 0px;'>$_INTERFACE_TITLE_<br><span>PHP Program by Jay Tanner</span></td></tr>
<tr>
<td title='
VALID SCALE SYMBOLS
Symbol\tScale
F \t\tFahrenheit
C \t\tCelsius
K \t\tKelvin
R \t\tRankine
N \t\tNewton
Re\t\tRéaumur
Ro\t\tRømer
De\t\tDelisle'>
<br><b style='font-size:15pt; font-weight:normal;'>Enter Temperature Value and Scale Symbol</b><br><br><span style='font-size:14pt; line-height:175%;'>Scales: <b> F C K R N Re Ro De</b></span><br>
<input name='Temperature' type='text' value="$Temperature" size='24' maxlength='22' tit>
</td></tr>
<tr><td colspan="$ColSpan" style='background-color:black;'>
<input name='ComputeButton' type='submit' value=' C O M P U T E '>
<br><br>
<!-- Source Code View Link. --->
<span style="font-size:10pt; color:GreenYellow; background:black; text-align:center;">
<b><a href='View-Source-Code.php' target='_blank'>View Source Code</a></b>
</span>
</td></tr>
<tr>
<td colspan="$ColSpan" style='color:silver; background-color:black;'>
Double-Click Within Text Area to Select ALL Text<br>
<textarea name='TextArea1' ReadOnly cols="46" rows="$TextArea1Rows" OnDblClick='this.select();' OnMouseUp='return true;' style='background:$BgColor; color:$TxColor; font-size:13pt;'>
$TextArea1Text
</textarea></td>
</tr>
<tr>
<td colspan="$ColSpan" style='background:black;'>
Double-Click Within Text Area to Select ALL Text<br>
<textarea name='TextArea2' cols="51" rows="86" style='color:black; background:LightYellow; font-size:13pt; padding:6px; border:4px solid white;' ReadOnly>
FORMULAS USED WITHIN THE PROGRAM
Eight Temperature Scales Are Recognized
-------------------
SYMBOL SCALE
------ -----------
F Fahrenheit
C Celsius
R Rankine
K Kelvin
Re Réaumur
Ro Rømer
N Newton
De Delisle
-------------------------------------------------
HOW THE PROGRAM WORKS
STEP 1:
Compute K-scale equivalent to input temperature.
Given any temperature on one of the eight scales,
we first compute its equivalent on the K-scale:
The scale symbols below represent the numerical
values on those scales in the formulas.
K = C + 273.15
K = (F - 32)*5/9 + 273.15
K = K
K = (R - 491.67)*5/9 + 273.15
K = Re*5/4 + 273.15
K = (Ro - 7.5)*40/21 + 273.15
K = N*100/33 + 273.15
K = 373.15 - De*2/3
-------------------------------------------------
STEP 2:
Compute table of equivalents on all eight scales,
based on the K-scale value, using the formulas
given below to compute the tabulated values.
C = K - 273.15
F = (K - 273.15)*9/5 + 32
K = K
R = (K - 273.15)*9/5 + 491.67
Re = (K - 273.15)*4/5
Ro = (K - 273.15)*21/40 + 7.5
N = (K - 273.15)*33/100
De = (373.15 - K)*3/2
-------------------------------------------------
OBSOLETE TEMPERATURE SCALES
The old obsolete scales are included for anyone
who may be doing historical scientific research
and may wish to do conversions regarding older
temperature scales no longer in modern use to
better visualize the science of the period.
-------------------------------------------------
CAVEAT
A warning will be displayed on a RED background
if the input temperature equates to any value
below absolute zero (0.0 K or 0.0 R). There are
no negative temperatures on the absolute scales,
by definition, but the computations will still
be performed anyway.
</textarea>
</td>
</tr>
<tr><td style='background:black;'><a href='https://en.wikipedia.org/wiki/Conversion_of_scales_of_temperature' target='_blank' title=' Tries to Open in a New Tab '>Temperature Scale Conversions Wiki-Ref</a>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>
</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>
</div>
<script>
(function(root)
{
var SmoothScroll = function()
{
var self = this;
this.defaults =
{
wrapperId:'SmoothScroll', wrapperDamper:0.06, cancelOnTouch:false
}
this.validateOptions = function(ops)
{
for (var prop in ops)
{
if (self.defaults.hasOwnProperty(prop))
{
Object.defineProperty(self.defaults, prop, {value: Object.getOwnPropertyDescriptor(ops, prop).value})
}
}
}
this.wrapperDamper;
this.wrapperId;
this.cancelOnTouch;
this.wrapper;
this.wrapperOffset = 0;
this.animateId;
this.resizing = false;
this.active = false;
this.wrapperHeight;
this.bodyHeight;
};
SmoothScroll.prototype =
{
init: function(options)
{
if (options)
{
this.validateOptions(options);
}
this.active = true;
this.resizing = false;
this.wrapperDamper = this.defaults.wrapperDamper;
this.wrapperId = this.defaults.wrapperId;
this.cancelOnTouch = this.defaults.cancelOnTouch;
this.wrapper = document.getElementById(this.wrapperId);
this.wrapper.style.position = 'fixed';
this.wrapper.style.width = '100%';
this.wrapperHeight = this.wrapper.clientHeight;
document.body.style.height = this.wrapperHeight + 'px';
window.addEventListener('resize', this.resize.bind(this));
if (this.cancelOnTouch)
{
window.addEventListener('touchstart', this.cancel.bind(this));
}
this.wrapperOffset = 0.0;
this.animateId = window.requestAnimationFrame(this.animate.bind(this));
},
wrapperUpdate: function()
{
var scrollY = (document.scrollingElement != undefined) ? document.scrollingElement.scrollTop : (document.documentElement.scrollTop || 0.0);
this.wrapperOffset += (scrollY - this.wrapperOffset) * this.wrapperDamper;
this.wrapper.style.transform = 'translate3d(0,' + (-this.wrapperOffset.toFixed(2)) + 'px, 0)';
},
checkResize: function()
{
if (this.wrapperHeight != this.wrapper.clientHeight)
{
this.resize();
}
},
resize: function()
{
var self = this;
if (!self.resizing)
{
self.resizing = true;
window.cancelAnimationFrame(self.animateId);
window.setTimeout(function()
{
self.wrapperHeight = self.wrapper.clientHeight;
if (parseInt(document.body.style.height) != parseInt(self.wrapperHeight))
{
document.body.style.height = self.wrapperHeight + 'px';
}
self.animateId = window.requestAnimationFrame(self.animate.bind(self));
self.resizing = false;
}, 150)
}
},
animate: function()
{
this.checkResize();
this.wrapperUpdate();
this.animateId = window.requestAnimationFrame(this.animate.bind(this));
},
cancel: function()
{
if (this.active)
{
window.cancelAnimationFrame(this.animateId);
window.removeEventListener('resize', this.resize);
window.removeEventListener('touchstart', this.cancel);
this.wrapper.removeAttribute('style');
document.body.removeAttribute('style');
this.active = false;
this.wrapper = "";
this.wrapperOffset = 0;
this.resizing = true;
this.animateId = "";
}
},
};
root.SmoothScroll = new SmoothScroll();
})(this);
</script>
<script>SmoothScroll.init({cancelOnTouch: true});</script>
</body>
_HTML;
/*
===========================================================================
This function interconverts between 8 different temperature scales.
The R�aumur, R�mer, Newton and Delisle scales may be useful with older
historical scientific documents where those scales may be encountered.
------------------
SYMBOL SCALE
------ -----------
F Fahrenheit
C Celsius
R Rankine
K Kelvin
Re Réaumur
Ro Rømer
N Newton
De Delisle
ERRORS:
An error message is returned for invalid arguments and scale symbols.
===========================================================================
*/
function Temp_to_Temp ($FromTempAndScaleStr, $ToScaleStr)
{
$TScaleSymbols = ' F C K R Re Ro N De ';
$FTaS = StrToUpper(trim($FromTempAndScaleStr));
// -------------------------------
// Get and check FromScale symbol.
$FromScale = substr($FTaS, -2);
if ($FromScale == 'RE' or $FromScale == 'RO' or $FromScale == 'DE')
{
if ($FromScale == 'RE') {$FromScale = 'Re';}
if ($FromScale == 'RO') {$FromScale = 'Ro';}
if ($FromScale == 'DE') {$FromScale = 'De';}
}
else
{$FromScale = substr($FTaS, -1);}
if (StrPos($TScaleSymbols, " $FromScale ") === FALSE)
{
return "ERROR: Temp_to_Temp()\n\nInvalid or missing input scale. Valid scales: $TScaleSymbols";
}
// -----------------------------
// Get and check ToScale symbol.
$ToScale = UCFirst(StrToLower(substr($ToScaleStr, -2)));
if ($ToScale <> 'Re' or $ToScale <> 'Ro' or $ToScale <> 'De')
{$ToScale = substr($ToScale, -2);}
if (StrPos($TScaleSymbols, " $ToScale ") === FALSE)
{
return "ERROR: Temp_to_Temp()\n\nInvalid or missing output scale. Valid scales: $TScaleSymbols";
}
// -----------------------------------------
// Get numerical value of input temperature.
$T = FloatVal($FTaS);
// ------------------------------------------------
// Convert input temperature into K scale value for
// internal work, depending on FromScale symbol.
switch ($FromScale)
{
case 'F' : $K = ($T - 32)*5/9 + 273.15; break;
case 'C' : $K = $T + 273.15; break;
case 'K' : $K = $T; break;
case 'R' : $K = ($T - 491.67)*5/9 + 273.15; break;
case 'Re' : $K = $T*5/4 + 273.15; break;
case 'Ro' : $K = ($T - 7.5)*40/21 + 273.15; break;
case 'N' : $K = $T*100/33 + 273.15; break;
case 'De' : $K = 373.15 - $T*2/3; break;
default : break;
}
// ----------------------------------------------------
// Convert K scale value into ToScale value for output.
switch ($ToScale)
{
case 'F' : $T = ($K - 273.15)*9/5 + 32; break;
case 'C' : $T = $K - 273.15; break;
case 'K' : $T = $K; break;
case 'R' : $T = ($K - 273.15)*9/5 + 491.67; break;
case 'Re' : $T = ($K - 273.15)*4/5; break;
case 'Ro' : $T = ($K - 273.15)*21/40 + 7.5; break;
case 'N' : $T = ($K - 273.15)*33/100; break;
case 'De' : $T = (373.15 - $K)*3/2; break;
default : break;
}
// Format output value to up to 10 decimals.
$T = Rtrim(Rtrim(SPrintF("%+18.10f", $T),'0'), '.');
if ($ToScale == 'K' or $ToScale == 'R') {$T = Str_Replace('+', '', $T);}
return trim($T);
} // End of Temp_to_Temp(...)
/*
Valid scale symbols: F C K R Re Ro N De
Max = 2 characters (Case INsensitive).
Returns empty string if no valid symbol found.
function Check_Temp_Scale ($TempScaleStr)
{
$ValidSymbols = ' F C K R N RE RO DE ';
$w = trim($TempScaleStr);
$ScaleSymbol = StrToUpper(substr(trim($w), -2));
$i = StrPos(' '.$ScaleSymbol.' ', $ValidSymbols);
if ($i !== FALSE) {return $TempScale;}
}
*/
/*
===========================================================================
This function separates a numerical value followed by a text label by in-
serting a single space between them, if there is none already, in order to
facilitate subsequent parsing of the separate string elements.
Examples:
The argument ('12.345km')
would return '12.345 km'
The argument ('1.2345e-23m')
would return '1.2345e-23 m'
etc.
Any subsequent spaces within the text or label part remain unchanged.
Example: The argument ('3blackbirds in a cage')
would return '3 blackbirds in a cage'
with only 1 space inserted after the initial number (3) and all
subsequent spaces considered part of the text label or symbol
part of the string and preserved.
If the argument is a purely numerical value, then it is returned as-is.
If the argument is only a non-numerical string, then it is returned as-is.
NO DEPENDENCIES
===========================================================================
*/
function Separate_Num_and_Text ($NumAndTextStr)
{
$X = trim($NumAndTextStr);
$L = StrLen($X);
$num = $alp = '';
for($i=0; $i < $L; $i++)
{
$x = substr($X,$i,1);
if (
Is_Numeric($x)
or $x == '.'
or $x == '-'
or $x == '+'
or StrToUpper($x) == 'E'
)
{$num .= $x;}
else
{$alp = trim(substr($X,$i,$L)); break;}
}
return trim("$num $alp");
}
// ---------------------------------------------------------------------------
?>