예제 #1
0
 /**
  * {@inheritdoc}
  */
 public static function fromInternal($stamp, $format = null)
 {
     if (!in_array(strtolower($format), ['jd', 'gjd', 'geo', 'geo-centric', 'rjd', 'reduced', 'mjd', 'modified', 'tjd', 'truncated', 'djd', 'dublin', 'j1900', 'j2000', 'lilian', 'rata-die', 'mars-sol'])) {
         $format = 'gjd';
     }
     $jdc = BC::add(BC::div(Calends::fromInternalToUnix($stamp), 86400, 18), 2440587.5, 18);
     if (in_array(strtolower($format), ['jd', 'gjd', 'geo', 'geo-centric'])) {
         $output = $jdc;
     } elseif (in_array(strtolower($format), ['rjd', 'reduced'])) {
         $output = BC::sub($jdc, '2400000', 18);
     } elseif (in_array(strtolower($format), ['mjd', 'modified'])) {
         $output = BC::sub($jdc, '2400000.5', 18);
     } elseif (in_array(strtolower($format), ['tjd', 'truncated'])) {
         $output = BC::intval(BC::sub($jdc, '2440000.5', 18), 0);
     } elseif (in_array(strtolower($format), ['djd', 'dublin', 'j1900'])) {
         $output = BC::sub($jdc, '2415020', 18);
     } elseif (in_array(strtolower($format), ['j2000'])) {
         $output = BC::sub($jdc, '2451545', 18);
     } elseif (in_array(strtolower($format), ['lilian'])) {
         $output = BC::intval(BC::sub($jdc, '2299159.5', 18), 0);
     } elseif (in_array(strtolower($format), ['rata-die'])) {
         $output = BC::intval(BC::sub($jdc, '1721424.5', 18), 0);
     } elseif (in_array(strtolower($format), ['mars-sol'])) {
         $output = BC::div(BC::sub($jdc, '2405522', 18), '1.02749', 18);
     }
     return $output;
 }
예제 #2
0
 /**
  * @covers ::toInternal
  */
 public function testToInternal()
 {
     $this->assertEquals(['seconds' => 0, 'nano' => 0, 'atto' => 0], TAI64::toInternal('00000000000000000000000000000000'));
     $this->assertEquals(['seconds' => BC::pow(2, 62), 'nano' => 0, 'atto' => 0], TAI64::toInternal('40000000000000000000000000000000'));
     $this->assertEquals(['seconds' => BC::sub(BC::pow(2, 63), 1, 0), 'nano' => 999999999, 'atto' => 999999999], TAI64::toInternal('80000000000000000000000000000000'));
     $this->assertEquals(['seconds' => BC::pow(2, 62), 'nano' => 0, 'atto' => 0], TAI64::toInternal('4000000000000000', 'tai64'));
     $this->assertEquals(['seconds' => BC::pow(2, 62), 'nano' => 0, 'atto' => 0], TAI64::toInternal('400000000000000000000000', 'tai64n'));
     $this->assertEquals(['seconds' => BC::pow(2, 62), 'nano' => 0, 'atto' => 0], TAI64::toInternal('40000000000000000000000000000000', 'tai64na'));
     $this->assertEquals(['seconds' => BC::pow(2, 62), 'nano' => 0, 'atto' => 0], TAI64::toInternal('4611686018427387904.000000000000000000', 'numeric'));
     $this->assertEquals(['seconds' => BC::pow(2, 62), 'nano' => 0, 'atto' => 0], TAI64::toInternal('4611686018427387904', 'numeric'));
     $this->assertEquals(['seconds' => BC::pow(2, 62), 'nano' => 0, 'atto' => 0], TAI64::toInternal('40000000000000000000000000000000', 'invalid'));
     $this->assertEquals(['seconds' => 0, 'nano' => 0, 'atto' => 0], TAI64::toInternal('-1', 'numeric'));
 }
예제 #3
0
 /**
  * {@inheritdoc}
  */
 public static function toInternal($date, $format = null)
 {
     if (!in_array(strtolower($format), ['tai64', 'tai64n', 'tai64na', 'numeric'])) {
         $format = 'tai64na';
     }
     if (substr(strtolower($format), 0, 5) == 'tai64') {
         $date = str_pad(str_pad($date, 16, '0', STR_PAD_LEFT), 32, '0', STR_PAD_RIGHT);
         $time = ['seconds' => gmp_strval(gmp_init('0x' . substr($date, 0, 16), 16), 10), 'nano' => gmp_strval(gmp_init('0x' . substr($date, 16, 8), 16), 10), 'atto' => gmp_strval(gmp_init('0x' . substr($date, 24, 8), 16), 10)];
     } elseif (strtolower($format) == 'numeric') {
         list($time['seconds'], $frac) = explode('.', "{$date}.");
         $frac = str_pad($frac, 18, '0', STR_PAD_RIGHT);
         $time['nano'] = substr($frac, 0, 9);
         $time['atto'] = substr($frac, 9, 9);
     }
     if (BC::comp($time['seconds'], BC::pow(2, 63, 18), 18) >= 0) {
         $time = ['seconds' => BC::sub(BC::pow(2, 63, 18), 1, 0), 'nano' => '999999999', 'atto' => '999999999'];
     } elseif (BC::comp($time['seconds'], 0, 18) <= 0) {
         $time = ['seconds' => '0', 'nano' => '0', 'atto' => '0'];
     }
     return $time;
 }
예제 #4
0
 public function it_should_modify_dates()
 {
     BC::scale(18);
     $time = microtime(true);
     $start = BC::sub($time, BC::mod($time, 86400), 0);
     $end = BC::add($start, 86400);
     $this->beConstructedWith(['start' => $start, 'end' => $end]);
     $today = $this->getWrappedObject();
     $next24hrs = $today->setDate($time)->setEndDate(BC::add($time, 86400));
     $yesterday = $today->previous('1 day', 'gregorian');
     $subtracted = $this->subtractFromEnd('50', 'unix');
     $subtracted->shouldHaveType('Danhunsaker\\Calends\\Calends');
     $subtracted->getEndDate()->shouldBeLike(BC::sub($this->getWrappedObject()->getEndDate(), 50));
     $duration = $this->setDuration('50', 'unix');
     $duration->shouldHaveType('Danhunsaker\\Calends\\Calends');
     $duration->getEndDate()->shouldBeLike(BC::add($this->getWrappedObject()->getDate(), 50));
     $endDuration = $this->setDurationFromEnd('50', 'unix');
     $endDuration->shouldHaveType('Danhunsaker\\Calends\\Calends');
     $endDuration->getDate()->shouldBeLike(BC::sub($this->getWrappedObject()->getEndDate(), 50));
     $merged = $this->merge($yesterday);
     $merged->shouldHaveType('Danhunsaker\\Calends\\Calends');
     $merged->getDate()->shouldBeLike($yesterday->getDate());
     $merged->getEndDate()->shouldBeLike($this->getWrappedObject()->getEndDate());
     $this->shouldThrow('Danhunsaker\\Calends\\InvalidCompositeRangeException')->duringIntersect($yesterday);
     $intersection = $this->intersect($next24hrs);
     $intersection->shouldHaveType('Danhunsaker\\Calends\\Calends');
     $intersection->getDate()->shouldBeLike($next24hrs->getDate());
     $intersection->getEndDate()->shouldBeLike($this->getWrappedObject()->getEndDate());
     $this->shouldThrow('Danhunsaker\\Calends\\InvalidCompositeRangeException')->duringGap($next24hrs);
     $gap = $this->gap($yesterday);
     $gap->shouldHaveType('Danhunsaker\\Calends\\Calends');
     $gap->getDate()->shouldBeLike($yesterday->getEndDate());
     $gap->getEndDate()->shouldBeLike($this->getWrappedObject()->getDate());
 }
예제 #5
0
 /**
  * Retrieves the difference between the current Calends object and another
  *
  * @api
  *
  * @param Calends $compare The Calends object to calculate the difference of
  * @param string $mode One of start, end, start-end, end-start, or duration
  * @return string|float|integer
  **/
 public function difference(Calends $compare, $mode = 'start')
 {
     $times = static::getTimesByMode($this, $compare, $mode);
     return BC::sub($times[0], $times[1], 18);
 }
예제 #6
0
 /**
  * {@inheritdoc}
  */
 public static function toInternal($date, $format = null)
 {
     $greg = new DateTime($date);
     return Calends::toInternalFromUnix(BC::add(BC::mul(BC::sub(\JulianToJD($greg->format('n'), $greg->format('j'), $greg->format('Y')), 2440587, 18), 86400, 18), BC::mod($greg->getTimestamp(), 86400, 18), 18));
 }
예제 #7
0
 /**
  * Retrieve the calendar's date at the Unix Epoch
  *
  * @return array
  */
 protected function getEpochUnitArray($positive = true)
 {
     $unitArray = [];
     foreach ($this->units()->where('is_auxiliary', 0)->get() as $unit) {
         $unitArray[$unit->internal_name] = $positive ? $unit->unix_epoch : BC::mul(BC::sub($unit->unix_epoch, $unit->uses_zero ? 0 : 1, 18), -1, 18);
     }
     return $unitArray;
 }
예제 #8
0
 /**
  * {@inheritdoc}
  */
 public static function toInternal($date, $format = null)
 {
     $greg = new DateTime(str_replace(['6L', '7L'], ['06', '07'], str_ireplace(array_values(static::$months), array_keys(static::$months), $date)));
     return Calends::toInternalFromUnix(BC::add(BC::mul(BC::sub(\JewishToJD($greg->format('n'), $greg->format('j'), $greg->format('Y')), 2440587, 18), 86400, 18), BC::mod($greg->getTimestamp(), 86400, 18), 18));
 }
예제 #9
0
 public function carryOver(array $unitArray)
 {
     $myVal = $this->is_auxiliary ? 0 : BC::sub(Arr::get($unitArray, $this->internal_name, $this->uses_zero ? 0 : 1), $this->uses_zero ? 0 : 1, 18);
     $exprInverse = '({myVal} * {scale}) %% {scale}';
     $exprNormal = '({myVal} - ({myVal} %% {scale})) / {scale}';
     foreach ($this->scalesToMe()->get() as $unit) {
         $unitVal = BC::sub(Arr::get($unitArray, $unit->internal_name, $unit->uses_zero ? 0 : 1), $unit->uses_zero ? 0 : 1, 18);
         $unitAdjustment = 0;
         $myAdjustment = 0;
         if ($unit->scale_inverse) {
             $adjComp = 1;
             $unitExpr = $exprInverse;
             $myExpr = '{adjust} / {scale}';
         } else {
             $adjComp = $myVal;
             $unitExpr = $exprNormal;
             $myExpr = '{adjust} * {scale}';
         }
         if (!is_null($unit->scale_amount)) {
             $unitAdjustment = BC::parse($unitExpr, ['myVal' => $myVal, 'scale' => $unit->scale_amount], 18);
             $myAdjustment = BC::parse($myExpr, ['adjust' => $unitAdjustment, 'scale' => $unit->scale_amount], 18);
         } else {
             $lengths = $unit->lengths()->get();
             $lCount = $lengths->count();
             $lSum = $lengths->sum('scale_amount');
             if ($lCount > 0) {
                 $unitAdjustment = BC::add($unitAdjustment, BC::parse("({$unitExpr}) * {$lCount}", ['myVal' => $myVal, 'scale' => $lSum], 18), 18);
                 $myAdjustment = BC::add($myAdjustment, BC::parse($myExpr, ['adjust' => BC::div($unitAdjustment, $lCount, 18), 'scale' => $lSum], 18), 18);
                 for ($lNum = 0; BC::comp($adjComp, $myAdjustment) > 0 && BC::comp($myVal, $lengths[$lNum]->scale_amount) >= 0; $lNum = BC::parse("({$lNum} + 1) % {$lCount}", null, 0)) {
                     $unitAdjustment = BC::add($unitAdjustment, 1, 18);
                     $myAdjustment = BC::add($myAdjustment, $lengths[$lNum]->scale_amount, 18);
                 }
                 if (BC::comp($adjComp, $myAdjustment) < 0) {
                     $unitAdjustment = BC::sub($unitAdjustment, 1, 18);
                     $myAdjustment = BC::sub($myAdjustment, $lengths[BC::parse("({$lNum} - 1 + {$lCount}) % {$lCount}", null, 0)]->scale_amount, 18);
                 }
             }
         }
         $unitArray[$unit->internal_name] = BC::add(BC::add($unitVal, $unitAdjustment, 18), $unit->uses_zero ? 0 : 1, 18);
         if (!$unit->is_auxiliary) {
             $unitArray[$this->internal_name] = $myVal = BC::add(BC::sub($myVal, $myAdjustment, 18), $this->uses_zero ? 0 : 1, 18);
         }
         $unitArray = $unit->carryOver($unitArray);
     }
     return $unitArray;
 }
예제 #10
0
 /**
  * @covers ::setDurationFromEnd
  */
 public function testSetDurationFromEnd()
 {
     $test = Calends::create(0, 'unix')->setDurationFromEnd(86400, 'unix');
     $this->assertInstanceOf('Danhunsaker\\Calends\\Calends', $test);
     $this->assertAttributeEquals(['seconds' => BC::sub(BC::pow(2, 62), 86400), 'nano' => '0', 'atto' => '0'], 'internalTime', $test);
     $this->assertAttributeEquals(86400, 'duration', $test);
     $this->assertAttributeEquals(['seconds' => BC::pow(2, 62), 'nano' => '0', 'atto' => '0'], 'endTime', $test);
 }