/** * @inheritdoc */ public function getLong(TemporalField $field) { if ($field instanceof ChronoField) { switch ($field) { case ChronoField::INSTANT_SECONDS(): return $this->toEpochSecond(); case ChronoField::OFFSET_SECONDS(): return $this->getOffset()->getTotalSeconds(); } return $this->toLocalDateTime()->getLong($field); } return $field->getFrom($this); }
public function format(DateTimePrintContext $context, &$buf) { /** @var ZoneID $zone */ $zone = $context->getValue(TemporalQueries::zoneId()); if ($zone === null) { return false; } $zname = $zone->getId(); if (!$zone instanceof ZoneOffset) { $dt = $context->getTemporal(); $name = $this->getDisplayName($zname, $dt->isSupported(ChronoField::INSTANT_SECONDS()) ? $zone->getRules()->isDaylightSavings(Instant::from($dt)) ? self::$DST : self::$STD : self::$GENERIC, $context->getLocale()); if ($name !== null) { $zname = $name; } } $buf .= $zname; return true; }
/** * Adjusts the specified temporal object to have this instant. * <p> * This returns a temporal object of the same observable type as the input * with the instant changed to be the same as this. * <p> * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)} * twice, passing {@link ChronoField#INSTANT_SECONDS} and * {@link ChronoField#NANO_OF_SECOND} as the fields. * <p> * In most cases, it is clearer to reverse the calling pattern by using * {@link Temporal#with(TemporalAdjuster)}: * <pre> * // these two lines are equivalent, but the second approach is recommended * temporal = thisInstant.adjustInto(temporal); * temporal = temporal.with(thisInstant); * </pre> * <p> * This instance is immutable and unaffected by this method call. * * @param Temporal $temporal the target object to be adjusted, not null * @return Temporal the adjusted object, not null * @throws DateTimeException if unable to make the adjustment * @throws ArithmeticException if numeric overflow occurs */ public function adjustInto(Temporal $temporal) { return $temporal->with(ChronoField::INSTANT_SECONDS(), $this->seconds)->with(ChronoField::NANO_OF_SECOND(), $this->nanos); }
public function test_isSupported_TemporalField() { //$this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(null), false); TODO $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::NANO_OF_SECOND()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::NANO_OF_DAY()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::MICRO_OF_SECOND()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::MICRO_OF_DAY()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::MILLI_OF_SECOND()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::MILLI_OF_DAY()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::SECOND_OF_MINUTE()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::SECOND_OF_DAY()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::MINUTE_OF_HOUR()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::MINUTE_OF_DAY()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::HOUR_OF_AMPM()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::CLOCK_HOUR_OF_AMPM()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::HOUR_OF_DAY()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::CLOCK_HOUR_OF_DAY()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::AMPM_OF_DAY()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::DAY_OF_WEEK()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::ALIGNED_DAY_OF_WEEK_IN_MONTH()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::ALIGNED_DAY_OF_WEEK_IN_YEAR()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::DAY_OF_MONTH()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::DAY_OF_YEAR()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::EPOCH_DAY()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::ALIGNED_WEEK_OF_MONTH()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::ALIGNED_WEEK_OF_YEAR()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::MONTH_OF_YEAR()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::PROLEPTIC_MONTH()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::YEAR()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::YEAR_OF_ERA()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::ERA()), true); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::INSTANT_SECONDS()), false); $this->assertEquals(self::TEST_200707_15_12_30_40_987654321()->isSupported(CF::OFFSET_SECONDS()), false); }
/** * @dataProvider data_instantNoZone */ public function test_parse_instantNoZone_supported(DateTimeFormatter $formatter, $text, Instant $expected) { $actual = $formatter->parse($text); $this->assertEquals($actual->isSupported(CF::INSTANT_SECONDS()), true); $this->assertEquals($actual->isSupported(CF::EPOCH_DAY()), false); $this->assertEquals($actual->isSupported(CF::SECOND_OF_DAY()), false); $this->assertEquals($actual->isSupported(CF::NANO_OF_SECOND()), true); $this->assertEquals($actual->isSupported(CF::MICRO_OF_SECOND()), true); $this->assertEquals($actual->isSupported(CF::MILLI_OF_SECOND()), true); }
private static function adjust(TemporalAccessor $temporal, DateTimeFormatter $formatter) { // normal case first (early return is an optimization) $overrideChrono = $formatter->getChronology(); $overrideZone = $formatter->getZone(); if ($overrideChrono == null && $overrideZone == null) { return $temporal; } // ensure minimal change (early return is an optimization) $temporalChrono = $temporal->query(TemporalQueries::chronology()); $temporalZone = $temporal->query(TemporalQueries::zoneId()); if ($temporalChrono !== null && $temporalChrono->equals($overrideChrono)) { $overrideChrono = null; } if ($temporalZone !== null && $temporalZone->equals($overrideZone)) { $overrideZone = null; } if ($overrideChrono === null && $overrideZone === null) { return $temporal; } // make adjustment $effectiveChrono = $overrideChrono != null ? $overrideChrono : $temporalChrono; if ($overrideZone != null) { // if have zone and instant, calculation is simple, defaulting chrono if necessary if ($temporal->isSupported(ChronoField::INSTANT_SECONDS())) { $chrono = $effectiveChrono != null ? $effectiveChrono : IsoChronology::INSTANCE(); return $chrono->zonedDateTime(Instant::from($temporal), $overrideZone); } // block changing zone on OffsetTime, and similar problem cases if ($overrideZone->normalized() instanceof ZoneOffset && $temporal->isSupported(ChronoField::OFFSET_SECONDS()) && $temporal->get(ChronoField::OFFSET_SECONDS()) != $overrideZone->getRules()->getOffset(Instant::EPOCH())->getTotalSeconds()) { throw new DateTimeException("Unable to apply override zone '" . $overrideZone . "' because the temporal object being formatted has a different offset but" . " does not represent an instant: " . $temporal); } } $effectiveZone = $overrideZone !== null ? $overrideZone : $temporalZone; $effectiveDate = null; if ($overrideChrono !== null) { if ($temporal->isSupported(ChronoField::EPOCH_DAY())) { $effectiveDate = $effectiveChrono->dateFrom($temporal); } else { // check for date fields other than epoch-day, ignoring case of converting null to ISO if (!($overrideChrono == IsoChronology::INSTANCE() && $temporalChrono === null)) { foreach (ChronoField::values() as $f) { if ($f->isDateBased() && $temporal->isSupported($f)) { throw new DateTimeException("Unable to apply override chronology '" . $overrideChrono . "' because the temporal object being formatted contains date fields but" . " does not represent a whole date: " . $temporal); } } } $effectiveDate = null; } } else { $effectiveDate = null; } // combine available data // this is a non-standard temporal that is almost a pure delegate // this better handles map-like underlying temporal instances return new Test($effectiveDate, $temporal, $effectiveZone, $effectiveChrono); }
public function test_isSupported_TemporalField() { //$this->assertEquals(DayOfWeek::THURSDAY()->isSupported(null), false); TODO $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::NANO_OF_SECOND()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::NANO_OF_DAY()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::MICRO_OF_SECOND()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::MICRO_OF_DAY()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::MILLI_OF_SECOND()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::MILLI_OF_DAY()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::SECOND_OF_MINUTE()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::SECOND_OF_DAY()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::MINUTE_OF_HOUR()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::MINUTE_OF_DAY()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::HOUR_OF_AMPM()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::CLOCK_HOUR_OF_AMPM()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::HOUR_OF_DAY()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::CLOCK_HOUR_OF_DAY()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::AMPM_OF_DAY()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::DAY_OF_WEEK()), true); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::ALIGNED_DAY_OF_WEEK_IN_MONTH()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::ALIGNED_DAY_OF_WEEK_IN_YEAR()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::DAY_OF_MONTH()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::DAY_OF_YEAR()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::EPOCH_DAY()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::ALIGNED_WEEK_OF_MONTH()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::ALIGNED_WEEK_OF_YEAR()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::MONTH_OF_YEAR()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::PROLEPTIC_MONTH()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::YEAR()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::YEAR_OF_ERA()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::ERA()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::INSTANT_SECONDS()), false); $this->assertEquals(DayOfWeek::THURSDAY()->isSupported(ChronoField::OFFSET_SECONDS()), false); }
private function buildAccessorInstant($instantSecs, $nano) { $mock = new MockAccessor(); $mock->fields->put(ChronoField::INSTANT_SECONDS(), $instantSecs); if ($nano !== null) { $mock->fields->put(ChronoField::NANO_OF_SECOND(), $nano); } return $mock; }
public function with(TemporalField $field, $newValue) { if ($field instanceof ChronoField) { $f = $field; switch ($f) { case ChronoField::INSTANT_SECONDS(): return $this->plus($newValue - $this->toEpochSecond(), ChronoUnit::SECONDS()); case ChronoField::OFFSET_SECONDS(): $offset = ZoneOffset::ofTotalSeconds($f->checkValidIntValue($newValue)); return $this->create($this->dateTime->toInstant($offset), $this->zone); } return $this->ofBest($this->dateTime->with($field, $newValue), $this->zone, $this->offset); } return ChronoZonedDateTimeImpl::ensureValid($this->getChronology(), $field->adjustInto($this, $newValue)); }
public function test_parse_fromField_InstantSeconds_NanoOfSecond() { $fmt = (new DateTimeFormatterBuilder())->appendValue(ChronoField::INSTANT_SECONDS())->appendLiteral('.')->appendValue(ChronoField::NANO_OF_SECOND())->toFormatter(); $acc = $fmt->parse("86402.123456789"); $expected = Instant::ofEpochSecond(86402, 123456789); $this->assertEquals($acc->isSupported(ChronoField::INSTANT_SECONDS()), true); $this->assertEquals($acc->isSupported(ChronoField::NANO_OF_SECOND()), true); $this->assertEquals($acc->isSupported(ChronoField::MICRO_OF_SECOND()), true); $this->assertEquals($acc->isSupported(ChronoField::MILLI_OF_SECOND()), true); $this->assertEquals($acc->getLong(ChronoField::INSTANT_SECONDS()), 86402); $this->assertEquals($acc->getLong(ChronoField::NANO_OF_SECOND()), 123456789); $this->assertEquals($acc->getLong(ChronoField::MICRO_OF_SECOND()), 123456); $this->assertEquals($acc->getLong(ChronoField::MILLI_OF_SECOND()), 123); $this->assertEquals(Instant::from($acc), $expected); }
public function test_isSupported_TemporalField() { // TODO check //$this->assertEquals(TEST_2008.isSupported((TemporalField) null()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::NANO_OF_SECOND()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::NANO_OF_DAY()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::MICRO_OF_SECOND()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::MICRO_OF_DAY()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::MILLI_OF_SECOND()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::MILLI_OF_DAY()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::SECOND_OF_MINUTE()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::SECOND_OF_DAY()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::MINUTE_OF_HOUR()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::MINUTE_OF_DAY()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::HOUR_OF_AMPM()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::CLOCK_HOUR_OF_AMPM()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::HOUR_OF_DAY()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::CLOCK_HOUR_OF_DAY()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::AMPM_OF_DAY()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::DAY_OF_WEEK()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::ALIGNED_DAY_OF_WEEK_IN_MONTH()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::ALIGNED_DAY_OF_WEEK_IN_YEAR()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::DAY_OF_MONTH()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::DAY_OF_YEAR()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::EPOCH_DAY()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::ALIGNED_WEEK_OF_MONTH()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::ALIGNED_WEEK_OF_YEAR()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::MONTH_OF_YEAR()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::PROLEPTIC_MONTH()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::YEAR()), true); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::YEAR_OF_ERA()), true); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::ERA()), true); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::INSTANT_SECONDS()), false); $this->assertEquals(self::$TEST_2008->isSupported(ChronoField::OFFSET_SECONDS()), false); }
public function parse(DateTimeParseContext $context, $text, $position) { // TODO cache formatter // new context to avoid overwriting fields like year/month/day $minDigits = $this->fractionalDigits < 0 ? 0 : $this->fractionalDigits; $maxDigits = $this->fractionalDigits < 0 ? 9 : $this->fractionalDigits; $parser = (new DateTimeFormatterBuilder())->append(DateTimeFormatter::ISO_LOCAL_DATE())->appendLiteral('T')->appendValue2(ChronoField::HOUR_OF_DAY(), 2)->appendLiteral(':')->appendValue2(ChronoField::MINUTE_OF_HOUR(), 2)->appendLiteral(':')->appendValue2(ChronoField::SECOND_OF_MINUTE(), 2)->appendFraction(ChronoField::NANO_OF_SECOND(), $minDigits, $maxDigits, true)->appendLiteral('Z')->toFormatter()->toPrinterParser(false); $newContext = $context->copy(); $pos = $parser->parse($newContext, $text, $position); if ($pos < 0) { return $pos; } // parser restricts most fields to 2 digits, so definitely int // correctly parsed nano is also guaranteed to be valid $yearParsed = $newContext->getParsed(ChronoField::YEAR()); $month = $newContext->getParsed(ChronoField::MONTH_OF_YEAR()); $day = $newContext->getParsed(ChronoField::DAY_OF_MONTH()); $hour = $newContext->getParsed(ChronoField::HOUR_OF_DAY()); $min = $newContext->getParsed(ChronoField::MINUTE_OF_HOUR()); $secVal = $newContext->getParsed(ChronoField::SECOND_OF_MINUTE()); $nanoVal = $newContext->getParsed(ChronoField::NANO_OF_SECOND()); $sec = $secVal !== null ? $secVal : 0; $nano = $nanoVal !== null ? $nanoVal : 0; $days = 0; if ($hour === 24 && $min === 0 && $sec === 0 && $nano === 0) { $hour = 0; $days = 1; } else { if ($hour === 23 && $min === 59 && $sec === 60) { $context->setParsedLeapSecond(); $sec = 59; } } $year = $yearParsed % 10000; try { $ldt = LocalDateTime::of($year, $month, $day, $hour, $min, $sec, 0)->plusDays($days); $instantSecs = $ldt->toEpochSecond(ZoneOffset::UTC()); $instantSecs += Math::multiplyExact(Math::div($yearParsed, 10000), self::SECONDS_PER_10000_YEARS); } catch (RuntimeException $ex) { // TODO What do we actually catch here and why return ~$position; } $successPos = $pos; $successPos = $context->setParsedField(ChronoField::INSTANT_SECONDS(), $instantSecs, $position, $successPos); return $context->setParsedField(ChronoField::NANO_OF_SECOND(), $nano, $position, $successPos); }
/** * Returns a copy of this date-time with the specified field set to a new value. * <p> * This returns a {@code ZonedDateTime}, based on this one, with the value * for the specified field changed. * This can be used to change any supported field, such as the year, month or day-of-month. * If it is not possible to set the value, because the field is not supported or for * some other reason, an exception is thrown. * <p> * In some cases, changing the specified field can cause the resulting date-time to become invalid, * such as changing the month from 31st January to February would make the day-of-month invalid. * In cases like this, the field is responsible for resolving the date. Typically it will choose * the previous valid date, which would be the last valid day of February in this example. * <p> * If the field is a {@link ChronoField} then the adjustment is implemented here. * <p> * The {@code INSTANT_SECONDS} field will return a date-time with the specified instant. * The zone and nano-of-second are unchanged. * The result will have an offset derived from the new instant and original zone. * If the new instant value is outside the valid range then a {@code DateTimeException} will be thrown. * <p> * The {@code OFFSET_SECONDS} field will typically be ignored. * The offset of a {@code ZonedDateTime} is controlled primarily by the time-zone. * As such, changing the offset does not generally make sense, because there is only * one valid offset for the local date-time and zone. * If the zoned date-time is in a daylight savings overlap, then the offset is used * to switch between the two valid offsets. In all other cases, the offset is ignored. * If the new offset value is outside the valid range then a {@code DateTimeException} will be thrown. * <p> * The other {@link #isSupported(TemporalField) supported fields} will behave as per * the matching method on {@link LocalDateTime#with(TemporalField, long) LocalDateTime}. * The zone is not part of the calculation and will be unchanged. * When converting back to {@code ZonedDateTime}, if the local date-time is in an overlap, * then the offset will be retained if possible, otherwise the earlier offset will be used. * If in a gap, the local date-time will be adjusted forward by the length of the gap. * <p> * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}. * <p> * If the field is not a {@code ChronoField}, then the result of this method * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)} * passing {@code this} as the argument. In this case, the field determines * whether and how to adjust the instant. * <p> * This instance is immutable and unaffected by this method call. * * @param TemporalField $field the field to set in the result, not null * @param int $newValue the new value of the field in the result * @return ZonedDateTime a {@code ZonedDateTime} based on {@code this} with the specified field set, not null * @throws DateTimeException if the field cannot be set * @throws UnsupportedTemporalTypeException if the field is not supported * @throws ArithmeticException if numeric overflow occurs */ public function with(TemporalField $field, $newValue) { if ($field instanceof ChronoField) { $f = $field; switch ($f) { case ChronoField::INSTANT_SECONDS(): return self::create($newValue, $this->getNano(), $this->zone); case ChronoField::OFFSET_SECONDS(): $offset = ZoneOffset::ofTotalSeconds($f->checkValidIntValue($newValue)); return $this->resolveOffset($offset); } return $this->resolveLocal($this->dateTime->with($field, $newValue)); } return $field->adjustInto($this, $newValue); }
public function test_getLong_TemporalField() { $test = ZonedDateTime::ofDateTime(LocalDateTime::of(2008, 6, 30, 12, 30, 40, 987654321), self::ZONE_0100()); $this->assertEquals($test->getLong(CF::YEAR()), 2008); $this->assertEquals($test->getLong(CF::MONTH_OF_YEAR()), 6); $this->assertEquals($test->getLong(CF::DAY_OF_MONTH()), 30); $this->assertEquals($test->getLong(CF::DAY_OF_WEEK()), 1); $this->assertEquals($test->getLong(CF::DAY_OF_YEAR()), 182); $this->assertEquals($test->getLong(CF::HOUR_OF_DAY()), 12); $this->assertEquals($test->getLong(CF::MINUTE_OF_HOUR()), 30); $this->assertEquals($test->getLong(CF::SECOND_OF_MINUTE()), 40); $this->assertEquals($test->getLong(CF::NANO_OF_SECOND()), 987654321); $this->assertEquals($test->getLong(CF::HOUR_OF_AMPM()), 0); $this->assertEquals($test->getLong(CF::AMPM_OF_DAY()), 1); $this->assertEquals($test->getLong(CF::OFFSET_SECONDS()), 3600); $this->assertEquals($test->getLong(CF::INSTANT_SECONDS()), $test->toEpochSecond()); }
private function resolveInstant() { // add instant seconds if we have date, time and zone if ($this->date !== null && $this->time !== null) { if ($this->zone !== null) { $instant = $this->date->atTime($this->time)->atZone($this->zone)->getLong(CF::INSTANT_SECONDS()); $this->fieldValues->put(CF::INSTANT_SECONDS(), $instant); } else { $offsetSecs = $this->fieldValues->get(CF::OFFSET_SECONDS()); if ($offsetSecs !== null) { $offset = ZoneOffset::ofTotalSeconds($offsetSecs); $instant = $this->date->atTime($this->time)->atZone($offset)->getLong(CF::INSTANT_SECONDS()); $this->fieldValues->put(CF::INSTANT_SECONDS(), $instant); } } } }
/** * Returns a copy of this date-time with the specified field set to a new value. * <p> * This returns an {@code OffsetDateTime}, based on this one, with the value * for the specified field changed. * This can be used to change any supported field, such as the year, month or day-of-month. * If it is not possible to set the value, because the field is not supported or for * some other reason, an exception is thrown. * <p> * In some cases, changing the specified field can cause the resulting date-time to become invalid, * such as changing the month from 31st January to February would make the day-of-month invalid. * In cases like this, the field is responsible for resolving the date. Typically it will choose * the previous valid date, which would be the last valid day of February in this example. * <p> * If the field is a {@link ChronoField} then the adjustment is implemented here. * <p> * The {@code INSTANT_SECONDS} field will return a date-time with the specified instant. * The offset and nano-of-second are unchanged. * If the new instant value is outside the valid range then a {@code DateTimeException} will be thrown. * <p> * The {@code OFFSET_SECONDS} field will return a date-time with the specified offset. * The local date-time is unaltered. If the new offset value is outside the valid range * then a {@code DateTimeException} will be thrown. * <p> * The other {@link #isSupported(TemporalField) supported fields} will behave as per * the matching method on {@link LocalDateTime#with(TemporalField, long) LocalDateTime}. * In this case, the offset is not part of the calculation and will be unchanged. * <p> * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}. * <p> * If the field is not a {@code ChronoField}, then the result of this method * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)} * passing {@code this} as the argument. In this case, the field determines * whether and how to adjust the instant. * <p> * This instance is immutable and unaffected by this method call. * * @param TemporalField $field the field to set in the result, not null * @param int $newValue the new value of the field in the result * @return OffsetDateTime an {@code OffsetDateTime} based on {@code this} with the specified field set, not null * @throws DateTimeException if the field cannot be set * @throws UnsupportedTemporalTypeException if the field is not supported * @throws ArithmeticException if numeric overflow occurs */ public function with(TemporalField $field, $newValue) { if ($field instanceof ChronoField) { $f = $field; switch ($f) { case ChronoField::INSTANT_SECONDS(): return $this->ofInstant(Instant::ofEpochSecond($newValue, $this->getNano()), $this->offset); case ChronoField::OFFSET_SECONDS(): return $this->_with($this->dateTime, ZoneOffset::ofTotalSeconds($f->checkValidIntValue($newValue))); } return $this->_with($this->dateTime->with($field, $newValue), $this->offset); } return $field->adjustInto($this, $newValue); }
function data_with_longTemporalField() { return [[Instant::ofEpochSecond(10, 200), CF::INSTANT_SECONDS(), 100, Instant::ofEpochSecond(100, 200), null], [Instant::ofEpochSecond(10, 200), CF::INSTANT_SECONDS(), 0, Instant::ofEpochSecond(0, 200), null], [Instant::ofEpochSecond(10, 200), CF::INSTANT_SECONDS(), -100, Instant::ofEpochSecond(-100, 200), null], [Instant::ofEpochSecond(10, 200), CF::NANO_OF_SECOND(), 100, Instant::ofEpochSecond(10, 100), null], [Instant::ofEpochSecond(10, 200), CF::NANO_OF_SECOND(), 0, Instant::ofEpochSecond(10), null], [Instant::ofEpochSecond(10, 200), CF::MICRO_OF_SECOND(), 100, Instant::ofEpochSecond(10, 100 * 1000), null], [Instant::ofEpochSecond(10, 200), CF::MICRO_OF_SECOND(), 0, Instant::ofEpochSecond(10), null], [Instant::ofEpochSecond(10, 200), CF::MILLI_OF_SECOND(), 100, Instant::ofEpochSecond(10, 100 * 1000 * 1000), null], [Instant::ofEpochSecond(10, 200), CF::MILLI_OF_SECOND(), 0, Instant::ofEpochSecond(10), null], [Instant::ofEpochSecond(10, 200), CF::NANO_OF_SECOND(), 1000000000, null, DateTimeException::class], [Instant::ofEpochSecond(10, 200), CF::MICRO_OF_SECOND(), 1000000, null, DateTimeException::class], [Instant::ofEpochSecond(10, 200), CF::MILLI_OF_SECOND(), 1000, null, DateTimeException::class], [Instant::ofEpochSecond(10, 200), CF::SECOND_OF_MINUTE(), 1, null, DateTimeException::class], [Instant::ofEpochSecond(10, 200), CF::SECOND_OF_DAY(), 1, null, DateTimeException::class], [Instant::ofEpochSecond(10, 200), CF::OFFSET_SECONDS(), 1, null, DateTimeException::class], [Instant::ofEpochSecond(10, 200), CF::NANO_OF_DAY(), 1, null, DateTimeException::class], [Instant::ofEpochSecond(10, 200), CF::MINUTE_OF_HOUR(), 1, null, DateTimeException::class], [Instant::ofEpochSecond(10, 200), CF::MINUTE_OF_DAY(), 1, null, DateTimeException::class], [Instant::ofEpochSecond(10, 200), CF::MILLI_OF_DAY(), 1, null, DateTimeException::class], [Instant::ofEpochSecond(10, 200), CF::MICRO_OF_DAY(), 1, null, DateTimeException::class]]; }