==============================================================================
COMPUTING THE SIGNED JULIAN DAY NUMBER
In astronomy, we often refer to extremely ancient dates when performing the
computations for eclipses or other ancient events. The usual algorithms
stop at BC 4713 or BC 4714, depending on which calendar is being used.
Suppose you wanted the JD number (Julian Day Number) for a calendar date
such as 'BC 8856-Apr-23' for a theoretical computation.
The native PHP Julian Day number functions cannot handle dates that ancient
because they cannot handle negative Julian Day numbers.
The only solution is to develop a custom function to handle dates prior to
BC 4713 and return negative Julian Day number values as well.
Below is a PHP function designed to return the long-term signed Julian Day
number for any date on the Julian or Gregorian calendar system over a long
40000-year span and it handles negative JD number values as well.
However, it does NOT specifically check for erroneous date arguments.
/*
###########################################################################
This PHP function computes the signed Julian Day Number
on the old Julian or the modern Gregorian calendar system.
It also handles proleptic dates prior to the mathematical
origin of either calendar system and can handle negative
Julian Day numbers.
A date string argument has the format: 'SignYyyyy/mm/dd'
Examples: '-01949/05/20' or '-00009/5/20' or '19987/12/01'
ARGUMENTS:
SignYyyyy = Signed calendar year number <> 0
-Negative = BC and +Positive = AD
There is no calendar year 0 (zero).
mm = Month number (1 to 12).
dd = Day number (1 to 31).
JorG = Calendar mode switch.
'J' = Julian calendar
or 'G' = Gregorian calendar = Default
ERRORS:
Returns FALSE if any of the (Y,m,d) arguments are non-numeric.
NO EXTERNAL DEPENDENCIES
###########################################################################
*/
function JD_Number ($YmdString, $JorG='G')
{
$YmdString = trim($YmdString);
list($Y,$m,$d) = PReg_Split("[\/]", $YmdString);
$Y = trim($Y); $m = trim($m); $d = trim($d);
$JorG = substr(StrToUpper(trim($JorG)),0,1);
$JorG = ($JorG == 'J')? 'J' : 'G';
// -------------------------------------------------------
// Error if any of the (Y, m, d) elements are non-numeric.
if (
!Is_Numeric($Y)
or !Is_Numeric($m)
or !Is_Numeric($d)
)
{return FALSE;}
// ---------------------------------------------------
// Compute JD number according to the Julian calendar.
$A = floor((14-$m) / 12);
$B = (($Y < 0)? $Y+1 : $Y) - $A;
$C = floor($B/100);
$JDNum = floor(30.6001*(12*$A + $m+1))+floor(365.25*($B+4716))-1524 + $d;
// If the computation is for the Julian calendar, then we
// are done. Return the JD number for the Julian calendar.
if ($JorG == 'J') {return $JDNum;}
/* Otherwise, apply this correction to convert the JD number on the
old Julian calendar into the JD number for our Gregorian calendar.
This correction may equate to a negative or positive value and is
the difference in days between the two calendar systems on the same
given date in the context: Diff_Days = (Greg_JDNum − Julian_JDNum).
*/
$w = floor(((($Y < 0)? $Y+1 : $Y) - floor((14-$m)/12)) / 100);
$JDNum += (floor($w/4) - $w + 2);
return $JDNum;
}
******************************************************************************
******************************************************************************
THE ABOVE PHP FUNCTION WITHOUT THE COMMENTS:
function JD_Num ($YmdString, $JorG='G')
{
$YmdString = trim($YmdString);
list($Y,$m,$d) = PReg_Split("[\/]", $YmdString);
$Y = trim($Y); $m = trim($m); $d = trim($d);
$JorG = substr(StrToUpper(trim($JorG)),0,1);
$JorG = ($JorG == 'J')? 'J' : 'G';
if (
!Is_Numeric($Y)
or !Is_Numeric($m)
or !Is_Numeric($d)
)
{return FALSE;}
$A = floor((14-$m) / 12);
$B = (($Y < 0)? $Y+1 : $Y) - $A;
$C = floor($B/100);
$JDNum = floor(30.6001*(12*$A + $m+1))+floor(365.25*($B+4716))-1524 + $d;
if ($JorG == 'J') {return $JDNum;}
$w = floor(((($Y < 0)? $Y+1 : $Y) - floor((14-$m)/12)) / 100);
$JDNum += (floor($w/4) - $w + 2);
return $JDNum;
} // END OF JD_Num (...)