Example #1
0
 /**
  * @param LocalDateTime|null $dt
  * @return null|ZoneOffsetTransition|ZoneOffset
  * @throws IllegalArgumentException
  */
 private function getOffsetInfo($dt)
 {
     if (empty($this->savingsInstantTransitions)) {
         return $this->standardOffsets[0];
     }
     // check if using last rules
     if (!empty($this->lastRules) && $dt->isAfter($this->savingsLocalTransitions[count($this->savingsLocalTransitions) - 1])) {
         /** @var ZoneOffsetTransition[] $transArray */
         $transArray = $this->findTransitionArray($dt->getYear());
         $info = null;
         foreach ($transArray as $trans) {
             $info = $this->findOffsetInfo($dt, $trans);
             if ($info instanceof ZoneOffsetTransition || $info->equals($trans->getOffsetBefore())) {
                 return $info;
             }
         }
         return $info;
     }
     // using historic rules
     $index = Math::binarySearch($this->savingsLocalTransitions, $dt);
     if ($index === -1) {
         // before first transition
         return $this->wallOffsets[0];
     }
     if ($index < 0) {
         // switch negative insert position to start of matched range
         $index = -$index - 2;
     } else {
         if ($index < count($this->savingsLocalTransitions) - 1 && $this->savingsLocalTransitions[$index]->equals($this->savingsLocalTransitions[$index + 1])) {
             // handle overlap immediately following gap
             $index++;
         }
     }
     if (($index & 1) === 0) {
         // gap or overlap
         $dtBefore = $this->savingsLocalTransitions[$index];
         $dtAfter = $this->savingsLocalTransitions[$index + 1];
         $offsetBefore = $this->wallOffsets[(int) ($index / 2)];
         $offsetAfter = $this->wallOffsets[(int) ($index / 2) + 1];
         if ($offsetAfter->getTotalSeconds() > $offsetBefore->getTotalSeconds()) {
             // gap
             return ZoneOffsetTransition::of($dtBefore, $offsetBefore, $offsetAfter);
         } else {
             // overlap
             return ZoneOffsetTransition::of($dtAfter, $offsetBefore, $offsetAfter);
         }
     } else {
         // normal (neither gap or overlap)
         return $this->wallOffsets[(int) ($index / 2) + 1];
     }
 }