Markus, Fabian, and all:

This patch, the ninth patch in my development program, installs support for the Biblical calendar, according to the model described in full by Floyd Nolen Jones (/The Chronology of the Old Testament/), based in part on earlier work by James Ussher, Archbishop of Armagh (fl. 1656).

This calendar is an astronomically observed calendar, and for that reason it relies on a function to predict the equinox at the Jerusalem meridian, and other functions of my own devising to find Julian Days for synodic months. However, you will be pleased to note that none of these functions is in any way recursive. Furthermore, the back-conversion function does /not/ need to call the forward-conversion function for any reason whatsoever. So, if anything, these functions should perform somewhat faster than even the Hillel II functions.

I also introduced support for a "hashtag." A user can specify [[Date::#CREATION]] and immediately obtain a caption and a wikivalue spelling out the date and time of creation, estimated as the Julian Day of local Jerusalem sundown on the evening before the calculated date of creation according to Ussher and Jones. This would primarily be of interest to users and administrators who believe the Hebrew/Christian Bible. I intend to internationalize this hashtag in the language file.

Earlier today, I attempted to include support for the direct input of a Julian Day. The problem was that simply testing for a numeric value is not sufficient; such a test would take an ordinary year and store /that/ as the Julian Day, which is definitely not what I intended. I then tried to use a regex to force the value to be a floating-point value, but the code produced a "hang" and I had to abandon the attempt. If I can find a recognizable symbol for a Julian Day, then I can always insist on that symbol to distinguish it from an actual year. Otherwise I'll have to keep experimenting, but I don't intend to spend very much time on it.

This patch will also do one other thing: in parsing for the am/pm annotation, I have to insist on finding a space before the am or pm value. The reason: the simple regex "[ap]m" was taking out two letters in the month named Tammuz in the Hillel and Ussher/Jones calendars, with the result that dates in the month of Tammuz were giving error conditions.

Internationalization will probably come next.

Temlakos
--- ../SemanticMediaWiki-lng/SMW_DV_Time.php    2009-08-12 19:03:31.000000000 
-0400
+++ ./SMW_DV_Time.php   2009-08-13 17:55:44.000000000 -0400
@@ -88,7 +88,8 @@
        protected $m_xsdvalue = false; // cache for XSD value
        protected $m_gregvalue = false; // cache for (proleptic) Gregorian value
        protected $m_julvalue = false; // cache for (proleptic) Julian value
-       protected $m_hvalue = false; // cache for HIllel II value
+       protected $m_hvalue = false; // cache for Hillel II value
+       protected $m_amvalue = false; // cache for Biblical calendar value
        protected $m_pref = false; // holds a symbol for the calendar model
        protected $m_day = false; //Gregorian day, remains false if unspecified
        protected $m_month = false; //Gregorian month, remains false if 
unspecified
@@ -104,14 +105,21 @@
        protected $m_dayh = false; // Hillel II day, remains false if 
unspecified
        protected $m_monthh = false; // Hillel II month, remains false if 
unspecified
        protected $m_yearh = false; // Hillel II year, remains false if 
unspecified
+       protected $m_dayam = false; // Biblical day, remains false if 
unspecified
+       protected $m_montham = false; // Biblical month, remains false if 
unspecified
+       protected $m_yearam = false; // Biblical year, remains false if 
unspecified
        // The following are constant (array-valued constants are not 
supported, hence the declaration as private static variable):
        private static $m_months = array("January", "February", "March", 
"April" , "May" , "June" , "July" , "August" , "September" , "October" , 
"November" , "December");
        private static $m_monthsshort = array("Jan", "Feb", "Mar", "Apr", 
"May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
        private static $m_monthsh = array(1 => "Nisan", "Iyar", "Sivan", 
"Tammuz", "Av", "Elul",
                                                                        
"Tishrei", "Cheshvan", "Kislev", "Teveth", "Shevat", "Adar", "Veadar");
        private static $m_monthsshorth = array(1 => "Nis", "Iya", "Siv", "Tam", 
"Av", "Elu", "Tis", "Che", "Kis", "Tev", "She", "Ada", "Vea");
+       private static $m_monthsam = array(1 => "Abib", "Zif", "Sivan", 
"Tammuz", "Av", "Elul",
+                                                                               
        "Ethanim","Bul","Kislev","Teveth","Shevat","Adar");
+       private static $m_monthsshortam = array(1 => "Abi", "Zif", "Siv", 
"Tam", "Av", "Elu", "Eth","Bul","Kis","Tev","She","Ada");
        private static $m_formats = array( SMW_Y => array('year'), SMW_YM => 
array('year','month'), SMW_MY => array('month','year'), SMW_YDM => 
array('year','day','month'), SMW_YMD => array('year','month','day'), SMW_DMY => 
array('day','month','year'), SMW_MDY => array('month','day','year'));
        private static $m_daysofmonths = array ( 1 => 31, 2 => 29, 3 => 31, 4 
=> 30, 5 => 31, 6 => 30, 7 => 31, 8 => 31, 9 => 30, 10 => 31, 11 => 30, 12 => 
31 );
+       private static $m_daysofmonthsam = array ( 1 => 30, 2 => 30, 3 => 30, 4 
=> 30, 5 => 30, 6 => 30, 7 => 30, 8 => 30, 9 => 30, 10 => 30, 11 => 30, 12 => 
60 );
        // Time zone monikers and their associated offsets in hours and 
fractions of hours
        private static $m_tz = array("A" => 1, "ACDT" => 10.5, "ACST" => 9.5, 
"ADT" => -3, "AEDT" => 11,
                "AEST" => 10, "AKDT" => -8, "AKST" => -9, "AST" => -4, "AWDT" 
=> 9, "AWST" => 8,
@@ -131,6 +139,14 @@
 // constant epochal values
        const J1582 = 2299160.5;        // Date of switchover to Gregorian 
calendar
        const HEBREW_EPOCH = 347995.5; // The Julian day start of the 19-cycle 
Hebrew calendar
+       const CREATION = 259257.2138888889; // The JD of creation, per Ussher, 
"Annals of the World," and
+                                                                               
                        // Jones, "The Chronology of the Old Testament."
+       const MOON_EPOCH = 259259.09722222222; //The first-ever new moon, and 
the anchor
+                                                                               
                                // of the lunar cycle.
+       const SYNODIC_MONTH = 29.530588; // Interval between new moons.
+       const TROPICAL_YEAR = 365.24219878; // Mean tropical year; for guesses 
only.
+       const VE_TROPICAL_YEAR = 365.2424; // The vernal-equinoctial tropical 
year
+       const VE2000 = 2451623.81625; // The vernal equinox that fell in AD 
2000 Gregorian.
 
        protected function parseUserValue($value) {
                global $smwgContLang;
@@ -151,13 +167,30 @@
                $this->m_dayh = false;
                $this->m_monthh = false;
                $this->m_yearh = false;
+               $this->m_dayam = false;
+               $this->m_montham = false;
+               $this->m_yearam = false;
 
                $value = trim($value); // ignore whitespace
+               // If the editor specifies the date of creation by '#CREATION', 
process that at once.
+               if($value == '#CREATION') {
+                       $this->m_jd = self::CREATION;
+                       $this->m_pref = "AM";
+                       $this->m_format = 3; // Specify all three parts of the 
date (see below)
+                       $this->JD2Date();
+                       $this->fracToTime();
+                       $this->m_amvalue = false;
+                       $this->makeAMValue();
+                       $this->m_caption = $this->m_amvalue;
+                       $this->m_wikivalue = $this->m_amvalue;
+                       return true;
+               }
+
                $this->m_wikivalue = $value;
                $filteredvalue = $value; //value without time definition and 
further abbreviations like PM or BC
 
                //browse string for special abbreviations referring to time 
like am, pm
-               if(preg_match("/([Aa]|[Pp])[Mm]/u", $filteredvalue, $match)){
+               if(preg_match("/\040[ap]m/u", $filteredvalue, $match)){
                  $this->m_timeannotation = strtolower($match[0]);
                  $regexp = "/(\040|T){0,1}".str_replace("+", "\+", 
$match[0])."(\040){0,1}/u"; //delete pm/am, preceding and following chars
                  $filteredvalue = preg_replace($regexp,'', $filteredvalue); 
//value without am/pm
@@ -165,7 +198,7 @@
 
                //browse string for special abbreviations referring to year 
like AD, BC, and OS
                $is_yearbc = false;
-               if(preg_match("/(AD|BC|Gr|Jl|OS|He)/u", $filteredvalue, 
$match)){
+               if(preg_match("/(AD|BC|Gr|Jl|OS|AM|He)/u", $filteredvalue, 
$match)){
                        $this->m_pref = $match[0];
                        if ($this->m_pref == 'BC') {
                                $is_yearbc = true;
@@ -267,6 +300,8 @@
                                        $globalvar = 'm_'.$globalvar; // (for 
searching this file) this is one of: m_year, m_month, m_day
                                        if($prelimModel == 'Jl') {
                                                $globalvar = $globalvar . 'j';
+                                       } elseif($prelimModel == 'AM') {
+                                               $globalvar = $globalvar . 'am';
                                        } elseif($prelimModel == 'He') {
                                                $globalvar = $globalvar . 'h';
                                        }
@@ -291,6 +326,10 @@
                        wfLoadExtensionMessages('SemanticMediaWiki');
                        
$this->addError(wfMsgForContent('smw_nodatetime',$value));
                        return true;
+               } elseif ( ($this->m_dayam > 0) && ($this->m_dayam > 
self::$m_daysofmonthsam[$this->m_montham]) ) { //date does not exist in 
Biblical calendar
+                       wfLoadExtensionMessages('SemanticMediaWiki');
+                       
$this->addError(wfMsgForContent('smw_nodatetime',$value));
+                       return true;
                } elseif ( ($this->m_dayh > 0) && ($this->m_dayh > 
SMWTimeValue::hebrew_month_days($this->m_yearh,$this->m_monthh)) ) { //date 
does not exist in Hillel calendar
                        wfLoadExtensionMessages('SemanticMediaWiki');
                        
$this->addError(wfMsgForContent('smw_nodatetime',$value));
@@ -299,6 +338,14 @@
                        wfLoadExtensionMessages('SemanticMediaWiki');
                        
$this->addError(wfMsgForContent('smw_nodatetime',$value));
                        return true;
+               } elseif ( ($this->m_yearam != false) && ($this->m_yearam < 0)) 
{ //no support for negative Biblical years
+                       wfLoadExtensionMessages('SemanticMediaWiki');
+                       
$this->addError(wfMsgForContent('smw_nodatetime',$value));
+                       return true;
+               } elseif ( ($this->m_yearh != false) && ($this->m_yearh < 0)) { 
//no support for negative Hillel years
+                       wfLoadExtensionMessages('SemanticMediaWiki');
+                       
$this->addError(wfMsgForContent('smw_nodatetime',$value));
+                       return true;
                } elseif ( ($this->m_yearj != false) && ($this->m_yearj < 
-4713) && ($this->m_timeoffset != 0) ) { //no support for time offsets if year 
< -4713
                        wfLoadExtensionMessages('SemanticMediaWiki');
                        
$this->addError(wfMsgForContent('smw_nodatetime',$value));
@@ -370,11 +417,28 @@
                return false;
        }
 
+       protected static function findMonthAM($label) {
+               global $smwgContLang;
+               $retVal = $smwgContLang->findMonthAM($label);
+               if ( $retVal !== false ) {
+                       return $retVal;
+               }
+               $retVal = array_search($label, self::$m_monthsam);
+               if ( $retVal !== false ) {
+                       return $retVal + 1;
+               }
+               $retVal = array_search($label, self::$m_monthsshortam);
+               if ( $retVal !== false ) {
+                       return $retVal + 1;
+               }
+               return false;
+       }
+
        protected function findPrelimModel() {
                if(($this->m_pref == 'BC') || ($this->m_pref == 'Jl') || 
($this->m_pref == 'OS')) {
                        return 'Jl'; // Assume Julian model if specified in any 
way, shape or form.
                }
-               if($this->m_pref == 'He') { // He model specified directly
+               if(($this->m_pref == 'He') || ($this->m_pref == 'AM')) { // AM 
or He model specified directly
                        return $this->m_pref;
                }
                return 'Gr';
@@ -387,6 +451,8 @@
                                $dayVal = 
intval(substr($digit,0,strlen($digit)-2)); //remove st/nd/th
                                if($prelimModel == 'Jl') {
                                        $this->m_dayj = $dayVal;
+                               } elseif($prelimModel == 'AM') {
+                                       $this->m_dayam = $dayVal;
                                } elseif($prelimModel == 'He') {
                                        $this->m_dayh = $dayVal;
                                } else {
@@ -394,10 +460,12 @@
                                }
                                return SMW_DAY;
                        }
-                       $monthnumber = ($prelimModel == 'He') ? 
SMWTimeValue::findMonthH($digit) : SMWTimeValue::findMonth($digit);
+                       $monthnumber = ($prelimModel == 'AM') ? 
SMWTimeValue::findMonthAM($digit) : (($prelimModel == 'He') ? 
SMWTimeValue::findMonthH($digit) : SMWTimeValue::findMonth($digit));
                        if ( $monthnumber !== false ) {
                                if($prelimModel == 'Jl') {
                                        $this->m_monthj = $monthnumber;
+                               } elseif($prelimModel == 'AM') {
+                                       $this->m_montham = $monthnumber;
                                } elseif($prelimModel == 'He') {
                                        $this->m_monthh = $monthnumber;
                                } else {
@@ -412,7 +480,9 @@
                        return SMW_DAY_MONTH_YEAR;
                } elseif (intval($digit) >= 1 && intval($digit) <= 30) { 
//number can be a day or a year up to 30 if Hillel II (011)
                        return SMW_DAY_YEAR;
-               } elseif (intval($digit) >= 1 && intval($digit) <= 31 && 
$prelimModel != 'He') { // number can be day or year if Julian or Gregorian
+               } elseif (intval($digit) >= 1 && intval($digit) <= 31 && 
$prelimModel != 'He') { // number can be day or year if Hillel II
+                       return SMW_DAY_YEAR;
+               } elseif (intval($digit) >= 1 && intval($digit) <= 59 && 
$prelimModel == 'AM') { // number can be day or year if Biblical
                        return SMW_DAY_YEAR;
                } elseif (is_numeric($digit)) { //number can just be a year 
(011)
                        return SMW_YEAR;
@@ -430,7 +500,7 @@
                        $this->m_pref = ''; // Erase the OS marker; it will not 
be needed after this.
                        return 'Jl'; // Old Style dates are converted per 
Julian rules.
                }
-               if (($this->m_pref == 'Gr') || ($this->m_pref == 'Jl') || 
($this->m_pref == 'He')) {//Specified calendar models
+               if (($this->m_pref == 'Gr') || ($this->m_pref == 'Jl') || 
($this->m_pref == 'AM') || ($this->m_pref == 'He')) {//Specified calendar models
                        return $this->m_pref;
                }
                // Model unspecified: must be determined by examination of the 
date parts.
@@ -473,14 +543,12 @@
 
        public function getShortWikiText($linked = NULL) {
                if ($this->isValid() && ($linked !== NULL) && ($linked !== 
false)) {
-                       $this->makeGregorianValue();
-                       $this->makeJulianValue();
-                       $this->makeHillelValue();
+                       $this->makePrintoutValue();
                        SMWOutputs::requireHeadItem(SMW_HEADER_TOOLTIP);
                        return '<span class="smwttinline">' . $this->m_caption 
. '<span class="smwttcontent">' .
-                               $this->m_gregvalue . ' <br />' .
-                               $this->m_julvalue . ' <br />' .
-                               $this->m_hvalue . '</span></span>';
+                               (($this->m_jd < self::J1582) ? 
$this->m_julvalue : $this->m_gregvalue)  . ' <br />' .
+                               (($this->m_jd >= self::HEBREW_EPOCH) ? 
($this->m_hvalue . ' <br />') : '') .
+                               (($this->m_jd >= self::CREATION) ? 
($this->m_amvalue) : '') . '</span></span>';
                } else {
                        return $this->m_caption;
                }
@@ -547,6 +615,8 @@
                switch ($model) {
                        case 'Jl':
                                return $this->m_yearj;
+                       case 'AM':
+                               return $this->m_yearam;
                        case 'He':
                                return $this->m_yearh;
                        default:
@@ -565,6 +635,8 @@
                switch ($model) {
                        case 'Jl':
                                return ($this->m_monthj != 
false)?$this->m_monthj:$default;
+                       case 'AM':
+                               return ($this->m_montham != 
false)?$this->m_montham:$default;
                        case 'He':
                                return ($this->m_monthh != 
false)?$this->m_monthh:$default;
                        default:
@@ -582,6 +654,8 @@
                switch ($model) {
                        case 'Jl':
                                return ($this->m_dayj != 
false)?$this->m_dayj:$default;
+                       case 'AM':
+                               return ($this->m_dayam != 
false)?$this->m_dayam:$default;
                        case 'He':
                                return ($this->m_dayh != 
false)?$this->m_dayh:$default;
                        default:
@@ -628,12 +702,21 @@
 
        /**
         * Build preferred values for printout, to be used as captions when 
setting up values
-        * from the store.
+        * from the store. Note: Proleptic Hillel II and Biblical values are 
not permitted.
         */
        protected function makePrintoutValue() {
                $this->makeGregorianValue();
                $this->makeJulianValue();
-               $this->makeHillelValue();
+               if($this->m_jd >= self::HEBREW_EPOCH) {
+                       $this->makeHillelValue();
+               } else {
+                       $this->m_hvalue = false;
+               }
+               if($this->m_jd >= self::CREATION) {
+                       $this->makeAMValue();
+               } else {
+                       $this->m_amvalue = false;
+               }
        }
 
        protected function makeGregorianValue() {
@@ -695,6 +778,22 @@
                }
        }
 
+       protected function makeAMValue() {
+               global $smwgContLang;
+               if ($this->m_amvalue === false) {
+                       $this->m_amvalue = number_format($this->m_yearam, 0, 
'.', '') . ' AM'; // note: there should be no digits after the comma anyway
+                       if ($this->m_montham) {
+                               $this->m_amvalue =  
$smwgContLang->getMonthLabelAM($this->m_montham) . " " . $this->m_amvalue;
+                       }
+                       if ($this->m_dayam) {
+                               $this->m_amvalue =  $this->m_dayam . " " . 
$this->m_amvalue;
+                       }
+                       if ($this->m_time) {
+                               $this->m_amvalue .= " " . $this->m_time;
+                       }
+               }
+       }
+
        protected static function normalizeValue($value){
                if(strlen($value) == 1) {
                        $value = "0".$value;
@@ -744,6 +843,9 @@
                        case "Jl":
                                $this->julian2JD();
                                break;
+                       case "AM":
+                               $this->am2JD();
+                               break;
                        case "He":
                                $this->hebrew2JD();
                }
@@ -789,10 +891,16 @@
        }
 
        /// Convert Julian Day to m_year, m_month, and m_day according to the 
proper model.
+       /// Do NOT invoke AM or Hillel conversion functions if the JD is less 
than their respective epochs.
        protected function JD2Date() {
                $this->JD2Julian();
                $this->JD2Gregorian();
-               $this->JD2Hebrew();
+               if($this->m_jd >= self::CREATION) {
+                       $this->JD2AM();
+               }
+               if($this->m_jd >= self::HEBREW_EPOCH) {
+                       $this->JD2Hebrew();
+               }
                if($this->m_time != false) { // Do not fill this in if it was 
not filled in to begin with
                        $this->fracToTime();
                }
@@ -817,6 +925,22 @@
                $this->m_day = ($this->m_format == 3) ? ($d + 1) : false;
        }
 
+// Function to produce a (proleptic) Gregorian year only--used by the AM model
+       protected static function jd_greg_year($jd) {
+               $j = intval($jd + 0.5) + 32044;
+               $g = intval($j / 146097);
+               $dg = $j % 146097;
+               $c = intval(((intval($dg / 36524) + 1) * 3) / 4);
+               $dc = $dg - $c * 36524;
+               $b = intval($dc / 1461);
+               $db = $dc % 1461;
+               $a = intval(  ( (intval($db / 365) + 1) * 3) / 4);
+               $da = $db - ($a * 365);
+               $y = $g * 400 + $c * 100 + $b * 4 + $a;
+               $m = intval(($da * 5 + 308) / 153) - 2;
+               return ($y - 4800 + intval(($m + 2) / 12));
+       }
+
        /// Convert Julian Day back to a Julian date.
        protected function JD2Julian() {
                $b = intval($this->m_jd + 0.5) + 1524;
@@ -953,4 +1077,164 @@
 // Now set the day to count from the start of the current month.
                $this->m_dayh = ($this->m_format < 3) ? false : (($jd - 
SMWTimeValue::hebrew_jd($this->m_yearh, $this->m_monthh, 1)) + 1);
        }
+// Determine Julian day and fraction of the vernal equinox at the Jerusalem 
meridian in a
+// given Gregorian year
+       protected static function equinox_jerusalem($year) {
+               $equJED = self::VE2000 - (2000 - $year) * 
self::VE_TROPICAL_YEAR;
+               $dtJerusalem = (35 + (13 / 60.0) + (48 / (60 * 60.0))) / 360;
+               $equJerusalem = $equJED + $dtJerusalem;
+               return $equJerusalem;
+       }
+
+/*  JERUSALEM_EQUINOX_JD  --  Calculate Julian day during which a given
+                           equinox, reckoned from the Jerusalem
+                           meridian, occurred for a given Gregorian
+                           year.  */
+       protected static function jerusalem_equinox_jd($year) {
+           $ep = SMWTimeValue::equinox_jerusalem($year);
+           $epg = intval($ep - 0.5) + 0.5;
+           return $epg;
+       }
+
+// Where "jd" is a given Julian date and "which" is one of the following:
+// 0 = Previous
+// 1 = Nearest
+// 2 = Next
+// returns the Julian date of the specified new moon
+       protected static function newmoon($jd,$which = 1) {
+               $offset = $jd - self::MOON_EPOCH;
+               $prevmoon = (floor($offset / self::SYNODIC_MONTH) * 
self::SYNODIC_MONTH)
+                       + self::MOON_EPOCH;
+               if($which == 0) {
+                       return $prevmoon;
+               }
+               $nextmoon = (ceil($offset / self::SYNODIC_MONTH) * 
self::SYNODIC_MONTH)
+                       + self::MOON_EPOCH;
+               if($nextmoon == $prevmoon) {
+                       $nextmoon += self::SYNODIC_MONTH;
+               }
+               if($which == 2) {
+                       return $nextmoon;
+               }
+               return (($jd-$prevmoon) <= ($nextmoon-$jd)) ? $prevmoon : 
$nextmoon;
+       }
+
+// Returns a new moon day occurring after a specified number of lunar cycles
+// Where $jd is a Julian day of an actual new moon.
+       protected static function nextmoon($jd,$count) {
+               $countmoon = $jd + ($count * self::SYNODIC_MONTH);
+               return intval($countmoon - 0.5) + 1.5;
+       }
+
+// Returns the first day of Abib/Aviv/Nisan, which is on the new moon nearest 
the equinox
+// at the longitude and the latitude of Jerusalem. This is probably five and a 
half days
+// after the equinox at the equator and at the longitude of Jerusalem. It is 
the best
+// estimated substitute for the time when the barley was likely to be ripe.
+       protected static function abib($year) {
+               $verneq = SMWTimeValue::jerusalem_equinox_jd($year); // Vernal 
equinox at Jerusalem
+               return SMWTimeValue::newmoon(($verneq),1); // New moon nearest 
the equinox
+               }
+
+// Where "year" is a Gregorian year during which a given Rosh Hashanah falls
+       protected static function rosh_hashanah($year) {
+               $verneq = SMWTimeValue::jerusalem_equinox_jd($year); // Vernal 
equinox at Jerusalem
+               $springmoon = SMWTimeValue::newmoon(($verneq),1); // New moon 
nearest the equinox
+               return $springmoon + (6 * self::SYNODIC_MONTH); // Six 
lunations forward
+               }
+
+// Where "jd" is a Julian date, this function returns the AM wherein it falls 
and also the
+// jd of Rosh Hashanah (i.e. 1 Ethanim) of that year
+       protected static function anno_mundi($jd) {
+               $guess = SMWTimeValue::jd_greg_year($jd) - 2; // Back off two 
years, just to be sure.
+               $lastrosh = SMWTimeValue::rosh_hashanah($guess);
+               while($lastrosh > $jd) {
+                       $guess--;
+                       $lastrosh = SMWTimeValue::rosh_hashanah($guess);
+               } // Move it back further, if you must, until you have a "rosh" 
earlier than the jd
+               $nextrosh = $lastrosh - 1; // Start one day earlier than this 
"rosh"
+               while (!(($lastrosh <= $jd) && ($jd < $nextrosh))) {
+                       $lastrosh = $nextrosh;
+                       $guess++;
+                       $nextrosh = SMWTimeValue::rosh_hashanah($guess);
+               } // Build a bracket that is one AM year apart and move it up 
until it brackets the jd.
+               $am = intval(($lastrosh + self::SYNODIC_MONTH - 
self::MOON_EPOCH) / self::TROPICAL_YEAR) + 1;
+               return array($am,$lastrosh);
+       }
+
+// The conversion function: converts an AM date to a JD.
+       protected function am2JD() {
+               $y = $this->getYear('AM');
+               $m = $this->getMonth('AM');
+               $d = $this->getDay('AM');
+               if($y == 0) {
+                       if($m != 6) {
+                               $this->m_jd = 0;
+                       } else {
+                               $this->m_jd = intval(self::CREATION - 0.5) + 
($d - 26.5);
+                       }
+               } elseif($y == 1) {
+                       $synmon = $m + (($m > 6) ? -7 : 5);
+                       $this->m_jd = intval(self::MOON_EPOCH + ($synmon * 
self::SYNODIC_MONTH) - 0.5)
+                               + 0.5 + $d;
+               } else {
+                       $guess = intval(self::MOON_EPOCH + (self::TROPICAL_YEAR 
* ($y - 1) - 0.5))
+                               + 20.5;
+                       $am = SMWTimeValue::anno_mundi($guess);
+
+                       while($am[0] < $y) {
+                               $guess = $am[1] + 385;
+                               $am = SMWTimeValue::anno_mundi($guess);
+                       } //Cycle up until your guess falls within the 
specified Anno Mundi.
+
+                       $startrosh = $am[1];
+
+                       if($m > 6) { // From Eithanim to Adar
+                               $this->m_jd = 
SMWTimeValue::nextmoon($startrosh,($m - 7)) + $d - 1;
+                       } else {
+                               $barley = SMWTimeValue::abib($am[0]-4003);
+                               $this->m_jd = 
SMWTimeValue::nextmoon($barley,($m - 1)) + $d - 1;
+                       }
+               }
+               $this->m_format = ($this->m_dayam != false) ? 3 : 
(($this->m_montham != false) ? 2 : 1 );
+       }
+
+       protected function JD2AM() {
+               if($this->m_jd < self::MOON_EPOCH) {
+                       $this->m_yearam = 0;
+                       $this->m_montham = 6;
+                       $this->m_dayam = intval($this->m_jd - 
(intval(self::CREATION - 0.5) + 0.5)) + 27;
+                       return;
+               }
+// Otherwise:
+               $jd = intval($this->m_jd - 0.5) + 0.5; // Convert to the 
nearest midnight.
+               $am = SMWTimeValue::anno_mundi($jd);
+               $this->m_yearam = $am[0]; // Get the am year.
+               if($this->m_format == 1) {
+                       $this->m_montham = false;
+                       $this->m_dayam = false;
+                       return;
+               }
+               $barley = SMWTimeValue::abib($am[0]-4003); // New moon for Abib.
+// Set the month at Abib if it is in the past, else at Eitanim.
+               $first = ($jd < $barley) ? 7 : 1;
+               $startmoon = ($jd < $barley) ? $am[1] : $barley;
+// Advance the month until the next new moon would pass the present day.
+               $moons = floor(($jd + 1.0 - $startmoon) / self::SYNODIC_MONTH);
+               if($moons > 5) $moons = 5;
+               $this->m_montham = $first + $moons;
+               $this->m_dayam = ($this->m_format < 3) ? false : ($jd - 
SMWTimeValue::nextmoon($startmoon,$moons) + 1);
+               if(($this->m_format == 3) && ($this->m_dayam == 0)) { // 
Rollback month and, if needed, year
+                       $this->m_montham--;
+                       if($this->m_montham == 0) { // Back into Adar.
+                               $this->m_montham = 12;
+                               $this->m_dayam = $jd - 
SMWTimeValue::nextmoon($am[1],5) + 1;
+                               return;
+                       }
+                       if($this->m_montham ==6) { // Back into Elul: Roll the 
year back by one.
+                               $this->m_yearam--;
+                       }
+                       $this->m_dayam = $jd - 
SMWTimeValue::nextmoon($startmoon,($moons - 1)) + 1;
+               }
+       }
+
 }
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Semediawiki-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/semediawiki-devel

Reply via email to