/** * {@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; }
/** * @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')); }
/** * {@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; }
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()); }
/** * 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); }
/** * {@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)); }
/** * 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; }
/** * {@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)); }
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; }
/** * @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); }