<?php

/*
   ###########################################################################
   Decimal Days to Standard Years, Weeks, Days, Hour, Minutes and Seconds
   WITH 30-DAY COOKIE

   AUTHOR   : Jay Tanner - 2026
   LANGUAGE : PHP v8.2.12
   LICENSE  : Public Domain

  ###########################################################################
*/

   
ob_start(); // Yes, Virginia, there is an obituary.

   
$cYear date('Y');

// ---------------------------------------------------------------
// Define the program cookie name and set it to expire in 30 days.

   
$CookieName 'Days-to-YWDHMS';
   
$ExpiresIn30Days time() + 30*86400;


// ---------------------------------
// Define PHP program and HTML info.

   
$_AUTHOR_           'Jay Tanner';
   
$_PROGRAM_VERSION_  'v1.00 - '$at "&#97;&#116;&#32;&#76;&#111;&#99;&#97;&#108;&#32;&#84;&#105;&#109;&#101;&#32;"$LTC "&#85;&#84;&#67;";
   
$_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_))."&minus;05:00)";
   
$_BROWSER_TAB_TEXT_ "Convert Decimal Days to WDHMS";
   
$_INTERFACE_TITLE_  "<span style='font-size:14pt;'>Convert&nbsp;Decimal&nbsp;Days&nbsp;Into&nbsp;Equivalent<br>Years,&nbsp;Weeks,&nbsp;Days,&nbsp;Hours,&nbsp;Minutes&nbsp;and&nbsp;Seconds</span><br><br><span style='font-size:10pt;'>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(
$Days) = 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.
*/

 
{
   
$Days '1.0'// Set default to 1 day if empty input.

// -------------------------------------------
// Store current interface settings in cookie.

   
$CookieDataString "$Days";

   
SetCookie ($CookieName$CookieDataString$ExpiresIn30Days);

  } 
// END OF  else {...}

  
// END OF  if (!IsSet(...))


// ------------------------------------------
// Read values of all interface arguments and
// set any empty arguments to default values.

   
$w Filter_Input(INPUT_POST'SubmitButton');

   if (isset(
$w))
{
   
$Days trim(Filter_Input(INPUT_POST'Days'));

// ------------------------------------------
// If empty, set default Days value to 1 day.

   
if ($Days == '') {$Days '1.0';}

// -------------------------------------
// Store interface argument in a cookie.

   
$CookieDataString "$Days";
   
SetCookie ($CookieName$CookieDataString$ExpiresIn30Days);
}


/* --------------------------------------------
   Check ($Days) value for validity.  If error,
   then set error flag and message values.
*/
   
$ErrFlag FALSE;
   
$ErrMssg '';

   if (!
Is_Numeric($Days))
      {
       
$ErrFlag TRUE;
       
$ErrMssg "The Decimal Days input value is invalid.\n'$Days'\n\nThe decimal days value must equate to a simple number value string.";
      }


// *******************************************************************
// START MAIN FUNCTION CALL CODE HERE.



/* -----------------------------
   Set initial uniform width for
   tables alignment in pixels.
*/
   
$TableWidth '780';


/* ==========================================
   If error was reported (TRUE), then display
   the error message on a red background.
*/
   
if ($ErrFlag === TRUE)
  {
   
$TxColor 'white';
   
$BgColor '#CC0000';
   
$TextArea2Text '';

   
$TextArea1Text =
"=== ERROR ===

$ErrMssg";
  }

else


  {

// *********************************************************
// BEGIN MAIN COMPUTATIONS HERE IF NO ERRORS DETECTED ABOVE.
// *********************************************************


// ---------------------
// Compute WDHMS string.

   
$WDHMS_String Days_to_WDHMS ($Days);


// ---------------------------
// Compute full YWDHMS string.

   
$Q 64;

   if (
$Days 0)
      {
       
$NumSign '-';
       
$days bcMul('-1'$Days$Q);
      }
   else
      {
       
$NumSign '';
       
$days $Days;
      }

   
$years  bcDiv($days'365.25'$Q);
   
$Iyears Number_Format(bcAdd($years'0'), 0'.'',');
   
$Fyears StrRChr($years'.');

   
$Y      "$Iyears$Fyears";
   
$Iyears Number_Format(bcAdd($years'0'), 0'.'',');
   
$Fyears StrRChr($years'.');
   
$Rdays  bcMul('365.25'$Fyears$Q);
   
$Rwdhms Days_to_WDHMS ($Rdays);

// -----------------------------
// Construct full YWDHMS string.

   
$YWDHMS_String "$NumSign$Iyears"yr " .  $Rwdhms;

// Reformat output years to 32 decimals.
   
$years bcAdd($years'0'32);
   
$years RTrim(RTrim($years'0'), '.');


// *******************************************
// DROP THROUGH HERE AFTER COMPUTATIONS ABOVE
// TO PRINT OUT THE RESULTS OF THE OPERATIONS.
// *******************************************

   
$TextArea1Text =
"                    TIME ELEMENTS EQUIVALENT TO DECIMAL DAYS

        Given the Decimal Days Value =
        
$Days d

        The Equivalent in Weeks, Days, Hours, Minutes and Seconds   =
        
$WDHMS_String

        The Equivalent in Standard Years, Weeks, Days, Hr, Min, Sec =
        
$NumSign$years yr =
        
$YWDHMS_String

        NOTE:  1 Standard Year = 365.25 days = 52wk 1d  06h 00m 00s"
;
  }


// ****************************
// Define TextArea2 text block.

   
$TextArea2Text =
"TEXT AREA 2 = OPTIONAL SECOND TEXT AREA

For optional program info or other use or it can be removed entirely or more
text areas could be added as needed.    This text area is independent of the
text area above.
"
;



/* **************************************************************************
   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.
*/

// TextArea1 SETTINGS REMOVED FROM HERE

// --------------------------------------------
// Text Area 2 - Default = At least 80 columns.

   
$Text2Cols Max(Array_Map('StrLen'PReg_Split("[\n]"trim($TextArea2Text))));
   if (
$Text2Cols 80) {$Text2Cols 80;} // Default
   
$Text2Rows 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='Convert decimal days to weeks, days, hours, minutes and seconds.'>
<meta name='keywords' content='NeoProgrammics.com'>
<meta name='author' content='Jay Tanner - https://www.NeoProgrammics.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 (Days) text box  --->
<table width="
$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr><td style="line-height:175%;"><b>Decimal Days Value</b><br><input name="Days"  type="text" value="
$Days"  size="25" maxlength="24">
</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>
</table>



<!-- Top yellow source code view link. --->
<br>
<table width="420" align="center" cellspacing="1" cellpadding="3">
<tr>
<td colspan="1" style='font-size:10pt; color:black; background:black;
                       text-align:center;' 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; font-weight:normal;'>
&nbsp;View/Copy Source Code&nbsp;</a></b>
</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="78" rows="15" ReadOnly OnDblClick="this.select();" OnMouseUp="return true;">
$TextArea1Text
</textarea>
</td>
</tr>
</table>

<!-- HIDE TEXTAREA 2

<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 decimal days into a weeks, days, hours, minutes and
   seconds string in the format 'wk dd hh mm ss.sss'

   ARGUMENT:
   Days = Decimal days value as a numerical string, like '123.456789'

   EXAMPLE:
   Argument ('184.3657209')      returns '26wk 2d  08h 46m 38.28576s'

   ERRORS:
   FALSE is returned as error if days argument is non-numeric.

   NO DEPENDENCIES
   ===========================================================================
*/

   
function Days_to_WDHMS ($DaysStr)
{
   
$Days trim($DaysStr);

// ------------------------------
// Error if non-numeric argument.

   
if (!Is_Numeric($Days)) {return FALSE;}

// ----------------------------------------
// Set number of internal working decimals.

   
$Q 64;

   
$Days bcAdd($Days'0'$Q);


/* Remove, but remember any negative sign.  It
   will be restored in the final returned result.
   Negative IN, Negative OUT.
*/
   
$NumSign '';

   if (
$Days 0)
      {
       
$NumSign '-';
       
$Days bcMul('-1'$Days$Q);
      }

/* ---------------------------------------------
   Compute weeks, days, hours, minutes, seconds
   equivalent to the given days argument string.
*/
   
$weeks   bcDiv($Days'7'$Q);
   
$wk      bcDiv($Days'7');

   
$days    bcMul('7'bcSub($weeks$wk$Q), $Q);
   
$dd      bcAdd($days'0');

   
$hours   bcMul('24'bcSub($days$dd$Q), $Q);
   
$hh      bcAdd($hours'0');
   
$hh      = ($hh 10)? "0$hh$hh;

   
$minutes bcMul('60'bcSub($hours$hh$Q),$Q);
   
$mm      bcAdd($minutes'0');
   
$mm      = ($mm 10)? "0$mm$mm;


// Try to round the seconds value to 6 decimals.
   
$seconds bcMul('60'bcSub($minutes$mm$Q),$Q);
   
$ss      bcAdd($seconds'0.' Str_Repeat('0'20) . '5'20);
   
$ss      RTrim(RTrim($ss'0'), '.');
   
$ss      = ($ss 10)? "0$ss$ss;

// ---------------------------------------------
// PATCH TO TRY AND FIX THAT BLASTED 60S GLITCH.

   
if (IntVal($ss) == 60)
   {
    
$ss '00';
    
$mm IntVal($mm) + 1;
    
$mm = ($mm 10)? "0$mm$mm;
   }

   if (
IntVal($mm) == 60)
   {
    
$mm '00';
    
$hh IntVal($hh) + 1;
    
$hh = ($hh 10)? "0$hh$hh;
   }

   if (
IntVal($hh) == 24)
   {
    
$hh '00';
    
$dd IntVal($dd) + 1;
//    $dd = ($dd < 10)? "0$dd" : $dd;
   
}

   if (
IntVal($dd) == 7)
   {
    
$dd '0';
    
$wk IntVal($wk) + 1;
   }

   
$wk Number_Format($wk0'.'',');

// -----------------------------------------------
// Output intended for fixed-width monospace font.

   
return
   
"$NumSign$wk&#119;&#107; $dd&#100;  $hh&#104; $mm&#109 $ss&#115;";

// END OF  Days_to_WDHMS (...)







// END OF PROGRAM




?>