Ejemplo n.º 1
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;
 }
Ejemplo n.º 2
0
 /**
  * Compares the start time, end time, or duration of two Calends objects
  *
  * @api
  *
  * @param Calends $a One of the two Calends objects to compare times from
  * @param Calends $b One of the two Calends objects to compare times from
  * @param string $mode One of start, end, start-end, end-start, or duration
  * @return integer Values are -1 if a < b; 0 if a == b; +1 if a > b
  **/
 public static function compare(Calends $a, Calends $b, $mode = 'start')
 {
     $times = static::getTimesByMode($a, $b, $mode);
     return BC::comp($times[0], $times[1], 18);
 }
Ejemplo n.º 3
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;
 }