/*
   ###########################################################################
   This function is the inverse of the JD number function. Given any signed
   JD Number, it will return the corresponding calendar date string in
   the same format as:  'BC|AD Yyyyy-Mmm-dd-DoW'

   The year will be formatted to 5 digits padded with zeros as needed.
   EXAMPLE: 'BC 17191-May-12',  'AD 01949-June-02',  'BC 00107-Oct-13'

   CALENDAR YEAR RANGE:
   BC 19999 Jan-01  to  AD 19999-Dec-31
   There is no calendar year 0 (zero).

   Mathematical origins of the calendar systems:
   BC 4713-Jan-01-Mon   JDNum = 0   On old Julian calendar
   BC 4714-Nov-24-Mon   JDNum = 0   On modern Gregorian calendar

   ARGUMENT:
   JDNumber = Julian Day number for the calendar date to be computed.

   JGAMode = Calendar mode
             'G' = Gregorian
             'J' = Julian

   RETURNS:
   Calendar date string in  'BC|AD Yyyy-Mmm-dd-DoW'  format
   according to the selected calendar mode.

   ERRORS:
   FALSE is returned if JD number argument is non-numeric.

   NO DEPENDENCIES
   ###########################################################################
*/

   function Inv_JD_Num ($JDNumber, $JGMode='G', $DoWFlag=TRUE)
 {
   $JDNum = trim($JDNumber);

/* ----------------------------
   Read calendar mode argument.
   'G' = Gregorian = Default
   'J' = Julian
*/
   $JGMode = substr(StrToUpper(trim($JGMode)),0,1);
             if ($JGMode == '') {$JGMode = 'G';}

// ----------------------------------------------
// Set calendar mode according to JGMode setting.

   $CalMode = ($JGMode == 'J')? 0:1;

// -------------------
// Read DoWFlag state.
// LOGIC: If not TRUE, then FALSE.

   $DoWFlag = ($DoWFlag === TRUE)? TRUE : FALSE;

/* --------------------------------------------
   Compute mathematical date elements (y, m, d)
   according to the calendar mode selection.
   There IS a mathematical year zero but there
   is NOT a calendrical year zero.  The year
   BC 00001  is followed by  AD 00001
*/
  $A = floor($JDNum + 0.5);
  $B = $CalMode*floor(($A - 1867216.25) / 36524.25);
  $C = $A + $CalMode*($B - floor($B/4) + 1);
  $D = $C + 1524;
  $E = floor(($D - 122.1) / 365.25);
  $F = floor(365.25 * $E);
  $G = floor(($D - $F) / 30.6001);

// ------------------------------------------------
// Compute final numeric calendrical date elements.

  $d = $D - $F - floor(30.6001 * $G);     // Day num   (1 to 31)
  $m = $G - 12*floor($G/14) - 1;          // Month num (1 to 12)
  $y = $E - 4716 + floor((14 - $m) / 12); // Mathematical year (y)
  $Y = ($y > 0)? $y : $y-1;               // Calendrical  year (Y)  Negative = BC

/* --------------------------------------------------------------
   At this point we have the calendrical date elements (Y, m, d).
   The next step is to construct the full calendar date text
   string for output. EXAMPLE OUTPUT: 'BC 9998-May-20-Tue'
*/
   $i     = (7 + ($JDNum + 1) % 7) % 7;
   $DoW   = substr('SunMonTueWedThuFriSat', 3*$i, 3);
   $Y     = SPrintF("%+06d", $Y);
   $Y     = Str_Replace('-', 'BC ', $Y);
   $Y     = Str_Replace('+', 'AD ', $Y);
   $Mmm   = substr('JanFebMarAprMayJunJulAugSepOctNovDec', 3*($m-1), 3);
   $dd    = SPrintf("%02d", $d);
   $JDNum = SPrintF("% 8d", $JDNum);

/* -------------------------------------
   Set append day of week string option
   according to the (DoWFlag) setting.
   TRUE  = Append Day of Week abbreviation
   FALSE = Append No Day of Week abbreviation
   LOGIC : If not TRUE, then FALSE
*/
   $DoWStr = ($DoWFlag === TRUE)? "-$DoW" : '';

// DONE.
   return "$Y-$Mmm-$dd$DoWStr";

 } // End of  Inv_JD_Num(...)