public function parse(DateTimeParseContext $context, $parseText, $position) { $length = strlen($parseText); if ($position < 0 || $position > $length) { throw new \OutOfRangeException(); } $style = $context->isStrict() ? $this->textStyle : null; $chrono = $context->getEffectiveChronology(); $it = null; if ($chrono === null || $chrono == IsoChronology::INSTANCE()) { $it = $this->provider->getTextIterator($this->field, $style, $context->getLocale()); } else { $it = $this->provider->getTextIterator2($chrono, $this->field, $style, $context->getLocale()); } if ($it !== null) { foreach ($it as $key => $value) { // fix numeric indices $key = strval($key); if ($context->subSequenceEquals($key, 0, $parseText, $position, strlen($key))) { return $context->setParsedField($this->field, $value, $position, $position + strlen($key)); } } if ($context->isStrict()) { return ~$position; } } return $this->numberPrinterParser()->parse($context, $parseText, $position); }
public function getFrom(TemporalAccessor $temporal) { if ($this->isSupportedBy($temporal) == false) { throw new UnsupportedTemporalTypeException("Unsupported field: DayOfQuarter"); } $doy = $temporal->get(ChronoField::DAY_OF_YEAR()); $moy = $temporal->get(ChronoField::MONTH_OF_YEAR()); $year = $temporal->getLong(ChronoField::YEAR()); $quarterDays = [0, 90, 181, 273, 0, 91, 182, 274]; return $doy - $quarterDays[Math::div($moy - 1, 3) + (IsoChronology::INSTANCE()->isLeapYear($year) ? 4 : 0)]; }
public static function RFC_1123_DATE_TIME() { // manually code maps to ensure correct data always used // (locale data can be changed by application code) $dow = [1 => "Mon", 2 => "Tue", 3 => "Wed", 4 => "Thu", 5 => "Fri", 6 => "Sat", 7 => "Sun"]; $moy = [1 => "Jan", 2 => "Feb", 3 => "Mar", 4 => "Apr", 5 => "May", 6 => "Jun", 7 => "Jul", 8 => "Aug", 9 => "Sep", 10 => "Oct", 11 => "Nov", 12 => "Dec"]; return self::$RFC_1123_DATE_TIME = (new DateTimeFormatterBuilder())->parseCaseInsensitive()->parseLenient()->optionalStart()->appendText3(ChronoField::DAY_OF_WEEK(), $dow)->appendLiteral2(", ")->optionalEnd()->appendValue3(ChronoField::DAY_OF_MONTH(), 1, 2, SignStyle::NOT_NEGATIVE())->appendLiteral(' ')->appendText3(ChronoField::MONTH_OF_YEAR(), $moy)->appendLiteral(' ')->appendValue2(ChronoField::YEAR(), 4)->appendLiteral(' ')->appendValue2(ChronoField::HOUR_OF_DAY(), 2)->appendLiteral(':')->appendValue2(ChronoField::MINUTE_OF_HOUR(), 2)->optionalStart()->appendLiteral(':')->appendValue2(ChronoField::SECOND_OF_MINUTE(), 2)->optionalEnd()->appendLiteral(' ')->appendOffset("+HHMM", "GMT")->toFormatter3(ResolverStyle::SMART(), IsoChronology::INSTANCE()); }
public function test_getLocalizedLocaleNPE() { TestHelper::assertNullException($this, function () { DateTimeFormatterBuilder::getLocalizedDateTimePattern(FormatStyle::SHORT(), FormatStyle::SHORT(), IsoChronology::INSTANCE(), null); }); }
/** * Checks if the specified year is a leap year. * <p> * Thai Buddhist leap years occur exactly in line with ISO leap years. * This method does not validate the year passed in, and only has a * well-defined result for years in the supported range. * * @param int $prolepticYear the proleptic-year to check, not validated for range * @return true if the year is a leap year */ public function isLeapYear($prolepticYear) { return IsoChronology::INSTANCE()->isLeapYear($prolepticYear - self::YEARS_DIFFERENCE); }
/** * Checks if the year is a leap year, according to the ISO proleptic * calendar system rules. * <p> * This method applies the current rules for leap years across the whole time-line. * In general, a year is a leap year if it is divisible by four without * remainder. However, years divisible by 100, are not leap years, with * the exception of years divisible by 400 which are. * <p> * For example, 1904 is a leap year it is divisible by 4. * 1900 was not a leap year as it is divisible by 100, however 2000 was a * leap year as it is divisible by 400. * <p> * The calculation is proleptic - applying the same rules into the far future and far past. * This is historically inaccurate, but is correct for the ISO-8601 standard. * * @return bool true if the year is leap, false otherwise */ public function isLeapYear() { return IsoChronology::INSTANCE()->isLeapYear($this->year); }
function data_query() { return [[self::TEST_200707_15_12_30_40_987654321(), TemporalQueries::chronology(), IsoChronology::INSTANCE()], [self::TEST_200707_15_12_30_40_987654321(), TemporalQueries::zoneId(), null], [self::TEST_200707_15_12_30_40_987654321(), TemporalQueries::precision(), CU::NANOS()], [self::TEST_200707_15_12_30_40_987654321(), TemporalQueries::zone(), null], [self::TEST_200707_15_12_30_40_987654321(), TemporalQueries::offset(), null], [self::TEST_200707_15_12_30_40_987654321(), TemporalQueries::localDate(), LocalDate::of(2007, 7, 15)], [self::TEST_200707_15_12_30_40_987654321(), TemporalQueries::localTime(), LocalTime::of(12, 30, 40, 987654321)]]; }
/** * Adjusts the specified temporal object to have this year. * <p> * This returns a temporal object of the same observable type as the input * with the year changed to be the same as this. * <p> * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)} * passing {@link ChronoField#YEAR} as the field. * If the specified temporal object does not use the ISO calendar system then * a {@code DateTimeException} is thrown. * <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 = thisYear.adjustInto(temporal); * temporal = temporal.with(thisYear); * </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) { if (AbstractChronology::from($temporal)->equals(IsoChronology::INSTANCE()) == false) { throw new DateTimeException("Adjustment only supported on ISO date-time"); } return $temporal->with(ChronoField::YEAR(), $this->year); }
/** * @internal * @param TemporalAccessor $temporal * @return bool */ public static function isIso(TemporalAccessor $temporal) { return AbstractChronology::from($temporal)->equals(IsoChronology::INSTANCE()); }
/** * @dataProvider data_resolve_ymaa */ public function test_resolve_ymaa_strict($y, $m, $w, $d, $expected, $smar, $strict) { $fieldValues = new FieldValues(); $fieldValues->put(ChronoField::YEAR(), $y); $fieldValues->put(ChronoField::MONTH_OF_YEAR(), $m); $fieldValues->put(ChronoField::ALIGNED_WEEK_OF_MONTH(), $w); $fieldValues->put(ChronoField::ALIGNED_DAY_OF_WEEK_IN_MONTH(), $d); if ($strict) { $date = IsoChronology::INSTANCE()->resolveDate($fieldValues, ResolverStyle::STRICT()); $this->assertEquals($date, $expected); $this->assertEquals($fieldValues->size(), 0); } else { try { IsoChronology::INSTANCE()->resolveDate($fieldValues, ResolverStyle::STRICT()); $this->fail("Should have failed"); } catch (DateTimeException $ex) { // $expected } } }
public function isSupportedBy(TemporalAccessor $temporal) { return $temporal->isSupported(ChronoField::EPOCH_DAY()) && AbstractChronology::from($temporal)->equals(IsoChronology::INSTANCE()); }
public function test_fieldResolvesToChronoZonedDateTime_noOverrideChrono_matches() { $zdt = ZonedDateTime::of(2010, 6, 30, 12, 30, 0, 0, self::EUROPE_PARIS()); $f = (new DateTimeFormatterBuilder())->appendValue(new ResolvingField($zdt))->toFormatter(); $accessor = $f->parse("1234567890"); $this->assertEquals($accessor->query(TemporalQueries::localDate()), LocalDate::of(2010, 6, 30)); $this->assertEquals($accessor->query(TemporalQueries::localTime()), LocalTime::of(12, 30)); $this->assertEquals($accessor->query(TemporalQueries::chronology()), IsoChronology::INSTANCE()); $this->assertEquals($accessor->query(TemporalQueries::zoneId()), self::EUROPE_PARIS()); }
public function provider_reducedWithChrono() { $baseYear = LocalDate::of(2000, 1, 1); return [[IsoChronology::INSTANCE()->dateFrom($baseYear)], [IsoChronology::INSTANCE()->dateFrom($baseYear)->plus(1, ChronoUnit::YEARS())], [IsoChronology::INSTANCE()->dateFrom($baseYear)->plus(99, ChronoUnit::YEARS())], [MinguoChronology::INSTANCE()->dateFrom($baseYear)], [MinguoChronology::INSTANCE()->dateFrom($baseYear)->plus(1, ChronoUnit::YEARS())], [MinguoChronology::INSTANCE()->dateFrom($baseYear)->plus(99, ChronoUnit::YEARS())], [ThaiBuddhistChronology::INSTANCE()->dateFrom($baseYear)], [ThaiBuddhistChronology::INSTANCE()->dateFrom($baseYear)->plus(1, ChronoUnit::YEARS())], [ThaiBuddhistChronology::INSTANCE()->dateFrom($baseYear)->plus(99, ChronoUnit::YEARS())]]; }
public function test_with() { $base = Year::of(5); $result = $base->with(ChronoField::ERA(), 0); $ad = $base->adjust(IsoEra::of(0)); $this->assertEquals($result, $ad); $prolepticYear = IsoChronology::INSTANCE()->prolepticYear(IsoEra::of(0), 5); $this->assertEquals($result->get(ChronoField::ERA()), 0); $this->assertEquals($result->get(ChronoField::YEAR()), $prolepticYear); $this->assertEquals($result->get(ChronoField::YEAR_OF_ERA()), 5); $result = $base->with(ChronoField::YEAR(), 10); $this->assertEquals($result->get(ChronoField::ERA()), $base->get(ChronoField::ERA())); $this->assertEquals($result->get(ChronoField::YEAR()), 10); $this->assertEquals($result->get(ChronoField::YEAR_OF_ERA()), 10); $result = $base->with(ChronoField::YEAR_OF_ERA(), 20); $this->assertEquals($result->get(ChronoField::ERA()), $base->get(ChronoField::ERA())); $this->assertEquals($result->get(ChronoField::YEAR()), 20); $this->assertEquals($result->get(ChronoField::YEAR_OF_ERA()), 20); }
public function test_rfc1123_basics() { $this->assertEquals(DateTimeFormatter::RFC_1123_DATE_TIME()->getChronology(), IsoChronology::INSTANCE()); $this->assertEquals(DateTimeFormatter::RFC_1123_DATE_TIME()->getZone(), null); $this->assertEquals(DateTimeFormatter::RFC_1123_DATE_TIME()->getResolverStyle(), ResolverStyle::SMART()); }
function data_query() { return [[Month::JUNE(), TemporalQueries::chronology(), IsoChronology::INSTANCE()], [Month::JUNE(), TemporalQueries::zoneId(), null], [Month::JUNE(), TemporalQueries::precision(), ChronoUnit::MONTHS()], [Month::JUNE(), TemporalQueries::zone(), null], [Month::JUNE(), TemporalQueries::offset(), null], [Month::JUNE(), TemporalQueries::localDate(), null], [Month::JUNE(), TemporalQueries::localTime(), null]]; }
/** * Returns the available chronologies. * <p> * Each returned {@code Chronology} is available for use in the system. * The set of chronologies includes the system chronologies and * any chronologies provided by the application via ServiceLoader * configuration. * * @return Chronology[] the independent, modifiable set of the available chronology IDs, not null */ static function getAvailableChronologies() { return [IsoChronology::INSTANCE(), MinguoChronology::INSTANCE(), ThaiBuddhistChronology::INSTANCE()]; }
/** * Gets the effective chronology during parsing. * * @return Chronology the effective parsing chronology, not null */ public function getEffectiveChronology() { $chrono = $this->currentParsed()->chrono; if ($chrono == null) { $chrono = $this->formatter->getChronology(); if ($chrono == null) { $chrono = IsoChronology::INSTANCE(); } } return $chrono; }
function data_query() { return [[self::TEST_2008_6_30_11_30_59_000000500(), TemporalQueries::chronology(), IsoChronology::INSTANCE()], [self::TEST_2008_6_30_11_30_59_000000500(), TemporalQueries::zoneId(), null], [self::TEST_2008_6_30_11_30_59_000000500(), TemporalQueries::precision(), CU::NANOS()], [self::TEST_2008_6_30_11_30_59_000000500(), TemporalQueries::zone(), self::OFFSET_PONE()], [self::TEST_2008_6_30_11_30_59_000000500(), TemporalQueries::offset(), self::OFFSET_PONE()], [self::TEST_2008_6_30_11_30_59_000000500(), TemporalQueries::localDate(), LocalDate::of(2008, 6, 30)], [self::TEST_2008_6_30_11_30_59_000000500(), TemporalQueries::localTime(), LocalTime::of(11, 30, 59, 500)]]; }
/** * Adjusts the specified temporal object to have this month-day. * <p> * This returns a temporal object of the same observable type as the input * with the month and day-of-month changed to be the same as this. * <p> * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)} * twice, passing {@link ChronoField#MONTH_OF_YEAR} and * {@link ChronoField#DAY_OF_MONTH} as the fields. * If the specified temporal object does not use the ISO calendar system then * a {@code DateTimeException} is thrown. * <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 = thisMonthDay.adjustInto(temporal); * temporal = temporal.with(thisMonthDay); * </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) { if (AbstractChronology::from($temporal)->equals(IsoChronology::INSTANCE()) == false) { throw new DateTimeException("Adjustment only supported on ISO date-time"); } $temporal = $temporal->with(ChronoField::MONTH_OF_YEAR(), $this->month); return $temporal->with(ChronoField::DAY_OF_MONTH(), Math::min($temporal->range(ChronoField::DAY_OF_MONTH())->getMaximum(), $this->day)); }
function data_query() { return [[self::TEST_2008_06(), TemporalQueries::chronology(), IsoChronology::INSTANCE()], [self::TEST_2008_06(), TemporalQueries::zoneId(), null], [self::TEST_2008_06(), TemporalQueries::precision(), CU::MONTHS()], [self::TEST_2008_06(), TemporalQueries::zone(), null], [self::TEST_2008_06(), TemporalQueries::offset(), null], [self::TEST_2008_06(), TemporalQueries::localDate(), null], [self::TEST_2008_06(), TemporalQueries::localTime(), null]]; }
/** * Creates a transition instance for the specified year. * <p> * Calculations are performed using the ISO-8601 chronology. * * @param int $year the year to create a transition for, not null * @return ZoneOffsetTransition the transition instance, not null */ public function createTransition($year) { if ($this->dom < 0) { $date = LocalDate::ofMonth($year, $this->month, $this->month->length(IsoChronology::INSTANCE()->isLeapYear($year)) + 1 + $this->dom); if ($this->dow !== null) { $date = $date->adjust(TemporalAdjusters::previousOrSame($this->dow)); } } else { $date = LocalDate::ofMonth($year, $this->month, $this->dom); if ($this->dow !== null) { $date = $date->adjust(TemporalAdjusters::nextOrSame($this->dow)); } } if ($this->timeEndOfDay) { $date = $date->plusDays(1); } $localDT = LocalDateTime::ofDateAndTime($date, $this->time); $transition = $this->timeDefinition->createDateTime($localDT, $this->standardOffset, $this->offsetBefore); return ZoneOffsetTransition::of($transition, $this->offsetBefore, $this->offsetAfter); }
public function test_query_chrono() { $this->assertEquals($this->TEST_DATE_TIME->query(TemporalQueries::chronology()), IsoChronology::INSTANCE()); $this->assertEquals(TemporalQueries::chronology()->queryFrom($this->TEST_DATE_TIME), IsoChronology::INSTANCE()); }
/** * @return LocalDate */ private function toLocalDate() { if ($this->dayOfMonthIndicator < 0) { $monthLen = $this->month->length(IsoChronology::INSTANCE()->isLeapYear($this->year)); $date = LocalDate::ofMonth($this->year, $this->month, $monthLen + 1 + $this->dayOfMonthIndicator); if ($this->dayOfWeek !== null) { $date = $date->adjust(TemporalAdjusters::previousOrSame($this->dayOfWeek)); } } else { $date = LocalDate::ofMonth($this->year, $this->month, $this->dayOfMonthIndicator); if ($this->dayOfWeek != null) { $date = $date->adjust(TemporalAdjusters::nextOrSame($this->dayOfWeek)); } } if ($this->timeEndOfDay) { $date = $date->plusDays(1); } return $date; }
public function test_format_withChronology_nonChronoFieldMapLink() { $temporal = new format_withChronology_nonChronoFieldMapLink(); $test = (new DateTimeFormatterBuilder())->appendValue2(IsoFields::WEEK_BASED_YEAR(), 4)->toFormatter2(Locale::ENGLISH())->withChronology(IsoChronology::INSTANCE()); $result = $test->format($temporal); $this->assertEquals($result, "2345"); }
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); }
/** * Queries this date-time using the specified query. * <p> * This queries this date-time using the specified query strategy object. * The {@code TemporalQuery} object defines the logic to be used to * obtain the result. Read the documentation of the query to understand * what the result of this method will be. * <p> * The result of this method is obtained by invoking the * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the * specified query passing {@code this} as the argument. * * @param <R> the type of the result * @param TemporalQuery $query the query to invoke, not null * @return mixed the query result, null may be returned (defined by the query) * @throws DateTimeException if unable to query (defined by the query) * @throws ArithmeticException if numeric overflow occurs (defined by the query) */ public function query(TemporalQuery $query) { if ($query == TemporalQueries::offset() || $query == TemporalQueries::zone()) { return $this->getOffset(); } else { if ($query == TemporalQueries::zoneId()) { return null; } else { if ($query == TemporalQueries::localDate()) { return $this->toLocalDate(); } else { if ($query == TemporalQueries::localTime()) { return $this->toLocalTime(); } else { if ($query == TemporalQueries::chronology()) { return IsoChronology::INSTANCE(); } else { if ($query == TemporalQueries::precision()) { return ChronoUnit::NANOS(); } } } } } } // inline TemporalAccessor.super.query(query) as an optimization // non-JDK classes are not permitted to make this optimization return $query->queryFrom($this); }
/** * Validates that the temporal has the correct chronology. */ private function validateChrono(TemporalAccessor $temporal) { $temporalChrono = $temporal->query(TemporalQueries::chronology()); if ($temporalChrono != null && IsoChronology::INSTANCE()->equals($temporalChrono) == false) { throw new DateTimeException("Chronology mismatch, expected: ISO, actual: " . $temporalChrono->getId()); } }