コード例 #1
0
ファイル: MiscTest.php プロジェクト: celest-time/prototype
 public function testMinDateEpochSec()
 {
     $offset = ZoneOffset::ofTotalSeconds(0);
     $seconds = LocalDateTime::MIN()->toEpochSecond($offset);
     $new = LocalDateTime::ofEpochSecond($seconds, 0, $offset);
     $this->assertEquals(LocalDateTime::MIN(), $new);
 }
コード例 #2
0
 /**
  * Obtains an instance of {@code OffsetDateTime} from an {@code Instant} and zone ID.
  * <p>
  * This creates an offset date-time with the same instant as that specified.
  * Finding the offset from UTC/Greenwich is simple as there is only one valid
  * offset for each instant.
  *
  * @param Instant $instant the instant to create the date-time from, not null
  * @param ZoneId $zone the time-zone, which may be an offset, not null
  * @return OffsetDateTime the offset date-time, not null
  * @throws DateTimeException if the result exceeds the supported range
  */
 public static function ofInstant(Instant $instant, ZoneId $zone)
 {
     $rules = $zone->getRules();
     $offset = $rules->getOffset($instant);
     $ldt = LocalDateTime::ofEpochSecond($instant->getEpochSecond(), $instant->getNano(), $offset);
     return new OffsetDateTime($ldt, $offset);
 }
コード例 #3
0
 /**
  * Completes the build converting the builder to a set of time-zone rules.
  * <p>
  * Calling this method alters the state of the builder.
  * Further rules should not be added to this builder once this method is called.
  *
  * @param string $zoneId the time-zone ID, not null
  * @param array $deduplicateMap a map for deduplicating the values, not null
  * @return ZoneRules the zone rules, not null
  * @throws \LogicException if no windows have been added
  * @throws \LogicException if there is only one rule defined as being forever for any given window
  */
 public function _toRules($zoneId, &$deduplicateMap)
 {
     $this->deduplicateMap = $deduplicateMap;
     if (empty($this->windowList)) {
         throw new \LogicException("No windows have been added to the builder");
     }
     /** @var ZoneOffsetTransition[] $standardTransitionList */
     $standardTransitionList = [];
     /** @var ZoneOffsetTransition[] */
     $transitionList = [];
     /** @var ZoneOffsetTransitionRule[] */
     $lastTransitionRuleList = [];
     // initialize the standard offset calculation
     $firstWindow = $this->windowList[0];
     $loopStandardOffset = $firstWindow->standardOffset;
     $loopSavings = 0;
     if ($firstWindow->fixedSavingAmountSecs !== null) {
         $loopSavings = $firstWindow->fixedSavingAmountSecs;
     }
     /** @var ZoneOffset $firstWallOffset */
     $firstWallOffset = $this->deduplicate(ZoneOffset::ofTotalSeconds($loopStandardOffset->getTotalSeconds() + $loopSavings));
     /** @var LocalDateTime $loopWindowStart */
     $loopWindowStart = $this->deduplicate(LocalDateTime::of(Year::MIN_VALUE, 1, 1, 0, 0));
     $loopWindowOffset = $firstWallOffset;
     // build the windows and rules to interesting data
     foreach ($this->windowList as $window) {
         // tidy the state
         $window->tidy($loopWindowStart->getYear());
         // calculate effective savings at the start of the window
         $effectiveSavings = $window->fixedSavingAmountSecs;
         if ($effectiveSavings === null) {
             // apply rules from this window together with the standard offset and
             // savings from the last window to find the savings amount applicable
             // at start of this window
             $effectiveSavings = 0;
             foreach ($window->ruleList as $rule) {
                 $trans = $rule->toTransition($loopStandardOffset, $loopSavings);
                 if ($trans->toEpochSecond() > $loopWindowStart->toEpochSecond($loopWindowOffset)) {
                     // previous savings amount found, which could be the savings amount at
                     // the instant that the window starts (hence isAfter)
                     break;
                 }
                 $effectiveSavings = $rule->savingAmountSecs;
             }
         }
         // check if standard offset changed, and update it
         if ($loopStandardOffset->equals($window->standardOffset) === false) {
             $standardTransitionList[] = $this->deduplicate(ZoneOffsetTransition::of(LocalDateTime::ofEpochSecond($loopWindowStart->toEpochSecond($loopWindowOffset), 0, $loopStandardOffset), $loopStandardOffset, $window->standardOffset));
             $loopStandardOffset = $this->deduplicate($window->standardOffset);
         }
         // check if the start of the window represents a transition
         $effectiveWallOffset = $this->deduplicate(ZoneOffset::ofTotalSeconds($loopStandardOffset->getTotalSeconds() + $effectiveSavings));
         if ($loopWindowOffset->equals($effectiveWallOffset) === false) {
             $trans = $this->deduplicate(ZoneOffsetTransition::of($loopWindowStart, $loopWindowOffset, $effectiveWallOffset));
             $transitionList[] = $trans;
         }
         $loopSavings = $effectiveSavings;
         // apply rules within the window
         foreach ($window->ruleList as $rule) {
             /** @var ZoneOffsetTransition $trans */
             $trans = $this->deduplicate($rule->toTransition($loopStandardOffset, $loopSavings));
             if ($trans !== null && $trans->toEpochSecond() < $loopWindowStart->toEpochSecond($loopWindowOffset) === false && $trans->toEpochSecond() < $window->createDateTimeEpochSecond($loopSavings) && $trans->getOffsetBefore()->equals($trans->getOffsetAfter()) === false) {
                 $transitionList[] = $trans;
                 $loopSavings = $rule->savingAmountSecs;
             }
         }
         // calculate last rules
         foreach ($window->lastRuleList as $lastRule) {
             $transitionRule = $this->deduplicate($lastRule->toTransitionRule($loopStandardOffset, $loopSavings));
             $lastTransitionRuleList[] = $transitionRule;
             $loopSavings = $lastRule->savingAmountSecs;
         }
         // finally we can calculate the true end of the window, passing it to the next window
         $loopWindowOffset = $this->deduplicate($window->createWallOffset($loopSavings));
         $loopWindowStart = $this->deduplicate(LocalDateTime::ofEpochSecond($window->createDateTimeEpochSecond($loopSavings), 0, $loopWindowOffset));
     }
     return ZoneRules::of($firstWindow->standardOffset, $firstWallOffset, $standardTransitionList, $transitionList, $lastTransitionRuleList);
 }
コード例 #4
0
 public function test_factory_ofEpochSecond_longOffset_nullOffset()
 {
     TestHelper::assertNullException($this, function () {
         LocalDateTime::ofEpochSecond(0, 500, null);
     });
 }
コード例 #5
0
 /**
  * Obtains an instance from an instant using the specified time-zone.
  *
  * @param Chronology $chrono the chronology, not null
  * @param Instant $instant the instant, not null
  * @param ZoneId $zone the zone identifier, not null
  * @return ChronoZonedDateTimeImpl the zoned date-time, not null
  */
 static function ofInstant(Chronology $chrono, Instant $instant, ZoneId $zone)
 {
     $rules = $zone->getRules();
     $offset = $rules->getOffset($instant);
     // TODO Objects.requireNonNull(offset, "offset");  // protect against bad ZoneRules
     $ldt = LocalDateTime::ofEpochSecond($instant->getEpochSecond(), $instant->getNano(), $offset);
     $cldt = $chrono->localDateTime($ldt);
     return new ChronoZonedDateTimeImpl($cldt, $offset, $zone);
 }
コード例 #6
0
 /**
  * Creates an instance from epoch-second and offsets.
  *
  * @param int $epochSecond the transition epoch-second
  * @param ZoneOffset $offsetBefore the offset before the transition, not null
  * @param ZoneOffset $offsetAfter the offset at and after the transition, not null
  * @return ZoneOffsetTransition
  */
 public static function ofEpoch($epochSecond, ZoneOffset $offsetBefore, ZoneOffset $offsetAfter)
 {
     return self::of(LocalDateTime::ofEpochSecond($epochSecond, 0, $offsetBefore), $offsetBefore, $offsetAfter);
 }
コード例 #7
0
 public function format(DateTimePrintContext $context, &$buf)
 {
     // use INSTANT_SECONDS, thus this code is not bound by Instant.MAX
     $inSecs = $context->getValueField(ChronoField::INSTANT_SECONDS());
     $inNanos = null;
     if ($context->getTemporal()->isSupported(ChronoField::NANO_OF_SECOND())) {
         $inNanos = $context->getTemporal()->getLong(ChronoField::NANO_OF_SECOND());
     }
     if ($inSecs === null) {
         return false;
     }
     $inSec = $inSecs;
     $inNano = ChronoField::NANO_OF_SECOND()->checkValidIntValue($inNanos !== null ? $inNanos : 0);
     // format mostly using LocalDateTime.toString
     if ($inSec >= -self::SECONDS_0000_TO_1970) {
         // current era
         $zeroSecs = $inSec - self::SECONDS_PER_10000_YEARS + self::SECONDS_0000_TO_1970;
         $hi = Math::floorDiv($zeroSecs, self::SECONDS_PER_10000_YEARS) + 1;
         $lo = Math::floorMod($zeroSecs, self::SECONDS_PER_10000_YEARS);
         $ldt = LocalDateTime::ofEpochSecond($lo - self::SECONDS_0000_TO_1970, 0, ZoneOffset::UTC());
         if ($hi > 0) {
             $buf .= '+' . $hi;
         }
         $buf .= $ldt;
         if ($ldt->getSecond() === 0) {
             $buf .= ":00";
         }
     } else {
         // before current era
         $zeroSecs = $inSec + self::SECONDS_0000_TO_1970;
         $hi = Math::div($zeroSecs, self::SECONDS_PER_10000_YEARS);
         $lo = $zeroSecs % self::SECONDS_PER_10000_YEARS;
         $ldt = LocalDateTime::ofEpochSecond($lo - self::SECONDS_0000_TO_1970, 0, ZoneOffset::UTC());
         $pos = strlen($buf);
         $buf .= $ldt;
         if ($ldt->getSecond() === 0) {
             $buf .= ":00";
         }
         if ($hi < 0) {
             if ($ldt->getYear() === -10000) {
                 $buf = substr_replace($buf, $hi - 1, $pos, 2);
             } else {
                 if ($lo === 0) {
                     $buf = substr_replace($buf, $hi, $pos, 0);
                 } else {
                     $buf = substr_replace($buf, Math::abs($hi), $pos + 1, 0);
                 }
             }
         }
     }
     // add fraction
     if ($this->fractionalDigits < 0 && $inNano > 0 || $this->fractionalDigits > 0) {
         $buf .= '.';
         $div = 100000000;
         for ($i = 0; $this->fractionalDigits === -1 && $inNano > 0 || $this->fractionalDigits === -2 && ($inNano > 0 || $i % 3 !== 0) || $i < $this->fractionalDigits; $i++) {
             $digit = Math::div($inNano, $div);
             $buf .= $digit;
             $inNano = $inNano - $digit * $div;
             $div = Math::div($div, 10);
         }
     }
     $buf .= 'Z';
     return true;
 }
コード例 #8
0
 /**
  * Obtains an instance of {@code ZonedDateTime} using seconds from the
  * epoch of 1970-01-01T00:00:00Z.
  *
  * @param int $epochSecond the number of seconds from the epoch of 1970-01-01T00:00:00Z
  * @param int $nanoOfSecond the nanosecond within the second, from 0 to 999,999,999
  * @param ZoneId $zone the time-zone, not null
  * @return ZonedDateTime the zoned date-time, not null
  * @throws DateTimeException if the result exceeds the supported range
  */
 private static function create($epochSecond, $nanoOfSecond, ZoneId $zone)
 {
     $rules = $zone->getRules();
     $instant = Instant::ofEpochSecond($epochSecond, $nanoOfSecond);
     // TODO: rules should be queryable by epochSeconds
     $offset = $rules->getOffset($instant);
     $ldt = LocalDateTime::ofEpochSecond($epochSecond, $nanoOfSecond, $offset);
     return new ZonedDateTime($ldt, $offset, $zone);
 }
コード例 #9
0
 public function test_compareTo_sameInstant()
 {
     $a = ZoneOffsetTransition::of(LocalDateTime::ofEpochSecond(23875287, 0, self::OFFSET_0200()), self::OFFSET_0200(), self::OFFSET_0300());
     $b = ZoneOffsetTransition::of(LocalDateTime::ofEpochSecond(23875287, 0, self::OFFSET_0300()), self::OFFSET_0300(), self::OFFSET_0200());
     $c = ZoneOffsetTransition::of(LocalDateTime::ofEpochSecond(23875287, 0, self::OFFSET_0100()), self::OFFSET_0100(), self::OFFSET_0400());
     $this->assertEquals($a->compareTo($a) == 0, true);
     $this->assertEquals($a->compareTo($b) == 0, true);
     $this->assertEquals($a->compareTo($c) == 0, true);
     $this->assertEquals($b->compareTo($a) == 0, true);
     $this->assertEquals($b->compareTo($b) == 0, true);
     $this->assertEquals($b->compareTo($c) == 0, true);
     $this->assertEquals($c->compareTo($a) == 0, true);
     $this->assertEquals($c->compareTo($b) == 0, true);
     $this->assertEquals($c->compareTo($c) == 0, true);
 }