* kumar mcmillan * * description: * do moon phase calculation stuff * You will see a slight drift in the cycle if you compare the results to other phase calculations... * this is probably because of different degrees of precision among phase periods used, as well as * float precision from computer to computer. It is more or less accurate and seems to always report the * correct phase name. Please let us know if you have any improvements, suggestions * or questions. Do not make modifications to this class in case the source changes (see moon-phase.php * for an example of usage). */ function rang($x) { $b= $x / 360; $A= 360 * ($b - (int)$b); If ($A < 0) $A=$A+360; return ($A); } Function faza($Rok, $Miesiac, $Dzien, $godzina,$min, $sec) { If ($Miesiac > 2){ $Miesiac= $Miesiac; $Rok= $Rok; } If ($Miesiac <= 2) { $Miesiac= $Miesiac + 12; $Rok= $Rok - 1; } $A = (int)($Rok / 100); $b= 2 - $A + (int)($A / 4); $jdp = (int)(365.25 * ($Rok + 4716)) + (int)(30.6001 * ($Miesiac + 1)) + $Dzien + $b + (($godzina + $min / 60 + $sec / 3600) / 24) - 1524.5; $jdp= $jdp; $tzd = ($jdp - 2451545) / 36525; $elm= rang(297.8502042 + 445267.1115168 * $tzd - (0.00163 * $tzd * $tzd) + $tzd*$tzd*$tzd / 545868 - $tzd*$tzd*$tzd*$tzd / 113065000); $ams= rang(357.5291092 + 35999.0502909 * $tzd - 0.0001536 * $tzd * $tzd + $tzd*$tzd*$tzd / 24490000); $aml= rang(134.9634114 + 477198.8676313 * $tzd - 0.008997 * $tzd * $tzd + $tzd*$tzd*$tzd / 69699 - $tzd*$tzd*$tzd*$tzd / 14712000); $asd= 180 - $elm - (6.289 * sin((3.1415926535 / 180) * (($aml)))) + (2.1 * sin((3.1415926535 / 180) * (($ams)))) - (1.274 * sin((3.1415926535 / 180) * (((2 * $elm) - $aml)))) - (0.658 * sin((3.1415926535 / 180) * ((2 * $elm)))) - (0.214 * sin((3.1415926535 / 180) * ((2 * $aml)))) - (0.11 * sin((3.1415926535 / 180) * (($elm)))); $phi1= (1 + cos((3.1415926535 / 180) * ($asd))) / 2; $tzd= ($jdp + (0.5 / 24) - 2451545) / 36525; $elm= rang(297.8502042 + 445267.1115168 * $tzd - (0.00163 * $tzd * $tzd) + $tzd*$tzd*$tzd / 545868 - $tzd*$tzd*$tzd*$tzd / 113065000); $ams= rang(357.5291092 + 35999.0502909 * $tzd - 0.0001536 * $tzd * $tzd + $tzd*$tzd*$tzd / 24490000); $aml= rang(134.9634114 + 477198.8676313 * tzd - 0.008997 * $tzd * $tzd + $tzd*$tzd*$tzd / 69699 - $tzd*$tzd*$tzd*$tzd / 14712000); $asd= 180 - $elm - (6.289 * sin((3.1415926535 / 180) * (($aml)))) + (2.1 * sin((3.1415926535 / 180) * (($ams)))) - (1.274 * sin((3.1415926535 / 180) * (((2 * $elm) - $aml)))) - (0.658 * sin((3.1415926535 / 180) * ((2 * $elm)))) - (0.214 * sin((3.1415926535 / 180) * ((2 * $aml)))) - (0.11 * sin((3.1415926535 / 180) * (($elm)))); $phi2= (1 + cos((3.1415926535 / 180) * ($asd))) / 2; if (($phi2-$phi1)<0) $phi1=-1*$phi1; return ($phi1); } define('MP_NEW_MOON_NAME','Nów'); define('MP_NEW_MOON_ID',0); define('MP_WAXING_CRESCENT_NAME','Dąży do pierwszej kwadry'); define('MP_WAXING_CRESCENT_ID',1); define('MP_FIRST_QUARTER_NAME','Pierwsza kwadra'); define('MP_FIRST_QUARTER_ID',2); define('MP_WAXING_GIBBOUS_NAME','Dąży do pełni'); define('MP_WAXING_GIBBOUS_ID',3); define('MP_FULL_MOON_NAME','Pełnia'); define('MP_FULL_MOON_ID',4); define('MP_WANING_GIBBOUS_NAME','Dąży do trzeciej kwadry'); define('MP_WANING_GIBBOUS_ID',5); define('MP_THIRD_QUARTER_MOON_NAME','Trzecia kwadra'); define('MP_THIRD_QUARTER_MOON_ID',6); define('MP_WANING_CRESCENT_NAME','Dąży do nowiu'); define('MP_WANING_CRESCENT_ID',7); define('MP_DAY_IN_SECONDS', 60 * 60 * 24); class moonPhase { var $allMoonPhases = array(); var $dateAsTimeStamp; var $moonPhaseIDforDate; var $moonPhaseNameForDate; var $periodInDays = 29.53058867; // == complete moon cycle var $periodInSeconds = -1; // gets set when you ask for it var $someFullMoonDate; /* * CONSTRUCTOR * $timestamp (int) date of which to calculate a moon phase and relative phases for */ function moonPhase($timeStamp = -1) { $this->allMoonPhases = array( MP_NEW_MOON_NAME, MP_WAXING_CRESCENT_NAME, MP_FIRST_QUARTER_NAME, MP_WAXING_GIBBOUS_NAME, MP_FULL_MOON_NAME, MP_WANING_GIBBOUS_NAME, MP_THIRD_QUARTER_MOON_NAME, MP_WANING_CRESCENT_NAME); // set base date, that we know was a full moon: // (http://aa.usno.navy.mil/data/docs/MoonPhase.html) $this->someFullMoonDate = strtotime("2002-08-22 22:29:25Z"); if($timeStamp == '' or $timeStamp == -1) $timeStamp = time(); $this->setDate($timeStamp); } // END function moonPhase($timeStamp = -1) { /* * PRIVATE * sets the moon phase ID and moon phase name internally */ function calcMoonPhase() { $position = $this->getPositionInCycle(); if($position >= 0.474 && $position <= 0.53) $phaseInfoForCurrentDate = array(MP_NEW_MOON_ID, MP_NEW_MOON_NAME); else if ($position >= 0.53 && $position <= 0.724) $phaseInfoForCurrentDate = array(MP_WAXING_CRESCENT_ID, MP_WAXING_CRESCENT_NAME); else if ($position >= 0.724 && $position <= 0.776) $phaseInfoForCurrentDate = array(MP_FIRST_QUARTER_ID, MP_FIRST_QUARTER_NAME); else if ($position >= 0.776 && $position <= 0.974) $phaseInfoForCurrentDate = array(MP_WAXING_GIBBOUS_ID, MP_WAXING_GIBBOUS_NAME); else if ($position >= 0.974 || $position <= 0.026) $phaseInfoForCurrentDate = array(MP_FULL_MOON_ID, MP_FULL_MOON_NAME); else if ($position >= 0.026 && $position <= 0.234) $phaseInfoForCurrentDate = array(MP_WANING_GIBBOUS_ID, MP_WANING_GIBBOUS_NAME); else if ($position >= 0.234 && $position <= 0.295) $phaseInfoForCurrentDate = array(MP_THIRD_QUARTER_MOON_ID, MP_THIRD_QUARTER_MOON_NAME); else if ($position >= 0.295 && $position <= 0.4739) $phaseInfoForCurrentDate = array(MP_WANING_CRESCENT_ID, MP_WANING_CRESCENT_NAME); list($this->moonPhaseIDforDate,$this->moonPhaseNameForDate) = $phaseInfoForCurrentDate; } // END function calcMoonPhase() { /* * PUBLIC * return (array) all moon phases as ID => Name */ function getAllMoonPhases() { return $this->allMoonPhases; } // END function getAllMoonPhases() { /* * PUBLIC */ function getBaseFullMoonDate() { return $this->someFullMoonDate; } // END function getBaseFullMoonDate() { /* * PUBLIC * return (int) timestamp of the current date being calculated */ function getDateAsTimeStamp() { return $this->dateAsTimeStamp; } // END function getDateAsTimeStamp() { /* * PUBLIC */ function getDaysUntilNextFullMoon() { $position = $this->getPositionInCycle(); return round((1 - $position) * $this->getPeriodInDays(), 2); } // ENDfunction getDaysUntilNextFullMoon() { /* * PUBLIC */ function getDaysUntilNextLastQuarterMoon() { $days = 0; $position = $this->getPositionInCycle(); if ($position < 0.25) $days = (0.25 - $position) * $this->getPeriodInDays(); else if ($position >= 0.25) $days = (1.25 - $position) * $this->getPeriodInDays(); return round($days, 1); } // END function getDaysUntilNextLastQuarterMoon() { /* * PUBLIC */ function getDaysUntilNextFirstQuarterMoon() { $days = 0; $position = $this->getPositionInCycle(); if ($position < 0.75) $days = (0.75 - $position) * $this->getPeriodInDays(); else if ($position >= 0.75) $days = (1.75 - $position) * $this->getPeriodInDays(); return round($days,1); } // END function getDaysUntilNextFirstQuarterMoon() { /* * PUBLIC */ function getDaysUntilNextNewMoon() { $days = 0; $position = $this->getPositionInCycle(); if ($position < 0.5) $days = (0.5 - $position) * $this->getPeriodInDays(); else if ($position >= 0.5) $days = (1.5 - $position) * $this->getPeriodInDays(); return round($days, 1); } // END function getDaysUntilNextNewMoon() { /* * PUBLIC * returns the percentage of how much lunar face is visible */ function getPercentOfIllumination() { // from http://www.lunaroutreach.org/cgi-src/qpom/qpom.c // C version: // return (1.0 - cos((2.0 * M_PI * phase) / (LPERIOD/ 86400.0))) / 2.0; $percentage = (1.0 + cos(2.0 * M_PI * $this->getPositionInCycle())) / 2.0; $percentage *= 100; $percentage = round($percentage,1) . '%'; return $percentage; } // END function getPercentOfIllumination() /* * PUBLIC */ function getPeriodInDays() { return $this->periodInDays; } // END function getPeriodInDays() { /* * PUBLIC */ function getPeriodInSeconds() { if($this->periodInSeconds > -1) return $this->periodInSeconds; // in case it was cached $this->periodInSeconds = $this->getPeriodInDays() * MP_DAY_IN_SECONDS; return $this->periodInSeconds; } // END function getPeriodInSeconds() { /* * PUBLIC */ function getPhaseID() { return $this->moonPhaseIDforDate; } // EMD function getPhaseID() { /* * PUBLIC * $ID (int) ID of phase, default is to get the phase for the current date passed in constructor */ function getPhaseName($ID = -1) { if($ID <= -1) return $this->moonPhaseNameForDate; // get name for this current date return $this->allMoonPhases[$ID]; // or.. get name for a specific ID } // END function getPhaseName() { /* * PUBLIC * return (float) number between 0 and 1. 0 or 1 is the beginning of a cycle (full moon) * and 0.5 is the middle of a cycle (new moon). */ function getPositionInCycle() { $diff = $this->getDateAsTimeStamp() - $this->getBaseFullMoonDate(); $periodInSeconds = $this->getPeriodInSeconds(); $position = ($diff % $periodInSeconds) / $periodInSeconds; if ($position < 0) $position = 1 + $position; return $position; } // END function getPositionInCycle() { /* * PUBLIC * sets the internal date for calculation and calulates the moon phase for that date. * called from the constructor. * $timeStamp (int) date to set as unix timestamp */ function setDate($timeStamp = -1) { if($timeStamp == '' or $timeStamp == -1) $timeStamp = time(); $this->dateAsTimeStamp = $timeStamp; $this->calcMoonPhase(); } // END function setDate($timeStamp) { } // END class moonPhase { ?>