Index: src/__phutil_library_map__.php =================================================================== --- src/__phutil_library_map__.php +++ src/__phutil_library_map__.php @@ -191,6 +191,8 @@ 'PhutilLipsumContextFreeGrammar' => 'grammar/PhutilLipsumContextFreeGrammar.php', 'PhutilLock' => 'filesystem/PhutilLock.php', 'PhutilLockException' => 'filesystem/PhutilLockException.php', + 'PhutilLunarPhase' => 'utils/PhutilLunarPhase.php', + 'PhutilLunarPhaseTestCase' => 'utils/__tests__/PhutilLunarPhaseTestCase.php', 'PhutilMarkupEngine' => 'markup/PhutilMarkupEngine.php', 'PhutilMarkupTestCase' => 'markup/__tests__/PhutilMarkupTestCase.php', 'PhutilMetricsChannel' => 'channel/PhutilMetricsChannel.php', @@ -548,6 +550,7 @@ 'PhutilLexerSyntaxHighlighter' => 'PhutilSyntaxHighlighter', 'PhutilLipsumContextFreeGrammar' => 'PhutilContextFreeGrammar', 'PhutilLockException' => 'Exception', + 'PhutilLunarPhaseTestCase' => 'PhutilTestCase', 'PhutilMarkupTestCase' => 'PhutilTestCase', 'PhutilMetricsChannel' => 'PhutilChannelChannel', 'PhutilMissingSymbolException' => 'Exception', Index: src/utils/PhutilLunarPhase.php =================================================================== --- /dev/null +++ src/utils/PhutilLunarPhase.php @@ -0,0 +1,43 @@ +isFull(); + */ +final class PhutilLunarPhase { + + private $epoch; + + public function __construct($epoch) { + $this->epoch = $epoch; + } + + private function getPhase() { + // (Aug 11, 1999) A new moon. + $new_moon_epoch = 934354800; + + // Number of seconds in the lunar phase. + $phase_length = 2551442.8768992; + + return fmod($this->epoch - $new_moon_epoch, $phase_length) / $phase_length; + } + + public function isFull() { + return abs($this->getPhase() - 0.5) < 0.02; + } + + public function isNew() { + return $this->getPhase() < 0.02 || $this->getPhase() > 0.98; + } + + public function isWaxing() { + return $this->getPhase() < 0.5; + } + + public function isWaning() { + return $this->getPhase() > 0.5; + } + +} Index: src/utils/__tests__/PhutilLunarPhaseTestCase.php =================================================================== --- /dev/null +++ src/utils/__tests__/PhutilLunarPhaseTestCase.php @@ -0,0 +1,59 @@ +assertEqual(false, $moon->isFull()); + $this->assertEqual(true, $moon->isNew()); + $this->assertEqual(true, $moon->isWaxing()); + $this->assertEqual(false, $moon->isWaning()); + + // May 22, 2005 + $moon = new PhutilLunarPhase(1116745200); + $this->assertEqual(true, $moon->isFull()); + $this->assertEqual(false, $moon->isNew()); + $this->assertEqual(true, $moon->isWaxing()); + $this->assertEqual(false, $moon->isWaning()); + + // May 23, 2005 + $moon = new PhutilLunarPhase(1116831600); + $this->assertEqual(true, $moon->isFull()); + $this->assertEqual(false, $moon->isNew()); + $this->assertEqual(false, $moon->isWaxing()); + $this->assertEqual(true, $moon->isWaning()); + + // May 30, 2005 + $moon = new PhutilLunarPhase(1117436400); + $this->assertEqual(false, $moon->isFull()); + $this->assertEqual(false, $moon->isNew()); + $this->assertEqual(false, $moon->isWaxing()); + $this->assertEqual(true, $moon->isWaning()); + + // June 05, 2005 + $moon = new PhutilLunarPhase(1117954800); + $this->assertEqual(false, $moon->isFull()); + $this->assertEqual(false, $moon->isNew()); + $this->assertEqual(false, $moon->isWaxing()); + $this->assertEqual(true, $moon->isWaning()); + + // June 06, 2005 + $moon = new PhutilLunarPhase(1118041200); + $this->assertEqual(false, $moon->isFull()); + $this->assertEqual(true, $moon->isNew()); + $this->assertEqual(false, $moon->isWaxing()); + $this->assertEqual(true, $moon->isWaning()); + + // Oct 4, 2013 + $moon = new PhutilLunarPhase(1380897327); + $this->assertEqual(false, $moon->isFull()); + $this->assertEqual(true, $moon->isNew()); + $this->assertEqual(true, $moon->isWaxing()); + $this->assertEqual(false, $moon->isWaning()); + + } + + +}