public function test__print_fullDateTime() { $buf = ''; $this->builder->padNext2(3, '-')->appendLiteral('Z'); $this->getFormatter()->formatTo(LocalDate::of(2008, 12, 3), $buf); $this->assertEquals($buf, "--Z"); }
/** * The base date for reduced value parsing. * @return LocalDate */ public static function BASE_DATE() { if (self::$BASE_DATE === null) { self::$BASE_DATE = LocalDate::of(2000, 1, 1); } return self::$BASE_DATE; }
public function adjustToFowards($year) { if ($this->adjustForwards === false && $this->dayOfMonth > 0) { $adjustedDate = LocalDate::ofMonth($year, $this->month, $this->dayOfMonth)->minusDays(6); $this->dayOfMonth = $adjustedDate->getDayOfMonth(); $this->month = $adjustedDate->getMonth(); $this->adjustForwards = true; } }
public function resolve(FieldValues $fieldValues, TemporalAccessor $partialTemporal, ResolverStyle $resolverStyle) { $wbyLong = $fieldValues->get(IsoFields::WEEK_BASED_YEAR()); $dowLong = $fieldValues->get(ChronoField::DAY_OF_WEEK()); if ($wbyLong === null || $dowLong === null) { return null; } $wby = IsoFields::WEEK_BASED_YEAR()->range()->checkValidIntValue($wbyLong, IsoFields::WEEK_BASED_YEAR()); // always validate $wowby = $fieldValues->get(IsoFields::WEEK_OF_WEEK_BASED_YEAR()); IsoFields::ensureIso($partialTemporal); $date = LocalDate::of($wby, 1, 4); if ($resolverStyle == ResolverStyle::LENIENT()) { $dow = $dowLong; // unvalidated if ($dow > 7) { $date = $date->plusWeeks(Math::div($dow - 1, 7)); $dow = ($dow - 1) % 7 + 1; } else { if ($dow < 1) { $date = $date->plusWeeks(Math::div(Math::subtractExact($dow, 7), 7)); $dow = ($dow + 6) % 7 + 1; } } $date = $date->plusWeeks(Math::subtractExact($wowby, 1))->with(ChronoField::DAY_OF_WEEK(), $dow); } else { $dow = ChronoField::DAY_OF_WEEK()->checkValidIntValue($dowLong); // validated if ($wowby < 1 || $wowby > 52) { if ($resolverStyle == ResolverStyle::STRICT()) { IsoFields::getWeekRange($date)->checkValidValue($wowby, $this); // only allow exact range } else { // SMART $this->range()->checkValidValue($wowby, $this); // allow 1-53 rolling into next year } } $date = $date->plusWeeks($wowby - 1)->with(ChronoField::DAY_OF_WEEK(), $dow); } $fieldValues->remove($this); $fieldValues->remove(IsoFields::WEEK_BASED_YEAR()); $fieldValues->remove(ChronoField::DAY_OF_WEEK()); return $date; }
public function adjustInto(Temporal $temporal, $newValue) { if ($this->isSupportedBy($temporal) === false) { throw new UnsupportedTemporalTypeException("Unsupported field: WeekBasedYear"); } $newWby = $this->range()->checkValidIntValue($newValue, IsoFields::WEEK_BASED_YEAR()); // strict check $date = LocalDate::from($temporal); $dow = $date->get(ChronoField::DAY_OF_WEEK()); $week = IsoFields::getWeek($date); if ($week == 53 && IsoFields::getWeekRangeInt($newWby) == 52) { $week = 52; } $resolved = LocalDate::of($newWby, 1, 4); // 4th is guaranteed to be in week one $days = $dow - $resolved->get(ChronoField::DAY_OF_WEEK()) + ($week - 1) * 7; $resolved = $resolved->plusDays($days); return $temporal->adjust($resolved); }
private function toDateTime($year) { $this->adjustToFowards($year); if ($this->dayOfMonth === -1) { $dayOfMonth = $this->month->length(Year::isLeapYear($year)); $date = LocalDate::ofMonth($year, $this->month, $dayOfMonth); if ($this->dayOfWeek !== null) { $date = $date->adjust(TemporalAdjusters::previousOrSame($this->dayOfWeek)); } } else { $date = LocalDate::ofMonth($year, $this->month, $this->dayOfMonth); if ($this->dayOfWeek !== null) { $date = $date->adjust(TemporalAdjusters::nextOrSame($this->dayOfWeek)); } } $ldt = LocalDateTime::ofDateAndTime($date, $this->time); if ($this->endOfDay) { $ldt = $ldt->plusDays(1); } return $ldt; }
/** * @group long */ public function test_comparisons() { $this->comparisons_LocalDateTime([LocalDate::of(Year::MIN_VALUE, 1, 1), LocalDate::of(Year::MIN_VALUE, 12, 31), LocalDate::of(-1, 1, 1), LocalDate::of(-1, 12, 31), LocalDate::of(0, 1, 1), LocalDate::of(0, 12, 31), LocalDate::of(1, 1, 1), LocalDate::of(1, 12, 31), LocalDate::of(2008, 1, 1), LocalDate::of(2008, 2, 29), LocalDate::of(2008, 12, 31), LocalDate::of(Year::MAX_VALUE, 1, 1), LocalDate::of(Year::MAX_VALUE, 12, 31)]); }
function data_atEndOfMonth() { return [[YearMonth::of(2008, 1), LocalDate::of(2008, 1, 31)], [YearMonth::of(2008, 2), LocalDate::of(2008, 2, 29)], [YearMonth::of(2008, 3), LocalDate::of(2008, 3, 31)], [YearMonth::of(2008, 4), LocalDate::of(2008, 4, 30)], [YearMonth::of(2008, 5), LocalDate::of(2008, 5, 31)], [YearMonth::of(2008, 6), LocalDate::of(2008, 6, 30)], [YearMonth::of(2008, 12), LocalDate::of(2008, 12, 31)], [YearMonth::of(2009, 1), LocalDate::of(2009, 1, 31)], [YearMonth::of(2009, 2), LocalDate::of(2009, 2, 28)], [YearMonth::of(2009, 3), LocalDate::of(2009, 3, 31)], [YearMonth::of(2009, 4), LocalDate::of(2009, 4, 30)], [YearMonth::of(2009, 5), LocalDate::of(2009, 5, 31)], [YearMonth::of(2009, 6), LocalDate::of(2009, 6, 30)], [YearMonth::of(2009, 12), LocalDate::of(2009, 12, 31)]]; }
/** * Compares this date to another date, including the chronology. * <p> * Compares this {@code ThaiBuddhistDate} with another ensuring that the date is the same. * <p> * Only objects of type {@code ThaiBuddhistDate} are compared, other types return false. * To compare the dates of two {@code TemporalAccessor} instances, including dates * in two different chronologies, use {@link ChronoField#EPOCH_DAY} as a comparator. * * @param mixed $obj the object to check, null returns false * @return true if this is equal to the other date */ public function equals($obj) { if ($this === $obj) { return true; } if ($obj instanceof ThaiBuddhistDate) { return $this->isoDate->equals($obj->isoDate); } return false; }
public function resolve(FieldValues $fieldValues, TemporalAccessor $partialTemporal, ResolverStyle $resolverStyle) { $yearLong = $fieldValues->get(ChronoField::YEAR()); $qoyLong = $fieldValues->get(IsoFields::QUARTER_OF_YEAR()); if ($yearLong === null || $qoyLong === null) { return null; } $y = ChronoField::YEAR()->checkValidIntValue($yearLong); // always validate $doq = $fieldValues->get(IsoFields::DAY_OF_QUARTER()); IsoFields::ensureIso($partialTemporal); if ($resolverStyle == ResolverStyle::LENIENT()) { $date = LocalDate::of($y, 1, 1)->plusMonths(Math::multiplyExact(Math::subtractExact($qoyLong, 1), 3)); $doq = Math::subtractExact($doq, 1); } else { $qoy = IsoFields::QUARTER_OF_YEAR()->range()->checkValidIntValue($qoyLong, IsoFields::QUARTER_OF_YEAR()); // validated $date = LocalDate::of($y, ($qoy - 1) * 3 + 1, 1); if ($doq < 1 || $doq > 90) { if ($resolverStyle == ResolverStyle::STRICT()) { $this->rangeRefinedBy($date)->checkValidValue($doq, $this); // only allow exact range } else { // SMART $this->range()->checkValidValue($doq, $this); // allow 1-92 rolling into next quarter } } $doq--; } $fieldValues->remove($this); $fieldValues->remove(ChronoField::YEAR()); $fieldValues->remove(IsoFields::QUARTER_OF_YEAR()); return $date->plusDays($doq); }
function resolveYMD(FieldValues $fieldValues, ResolverStyle $resolverStyle) { $y = CF::YEAR()->checkValidIntValue($fieldValues->remove(CF::YEAR())); if ($resolverStyle == ResolverStyle::LENIENT()) { $months = Math::subtractExact($fieldValues->remove(CF::MONTH_OF_YEAR()), 1); $days = Math::subtractExact($fieldValues->remove(CF::DAY_OF_MONTH()), 1); return LocalDate::of($y, 1, 1)->plusMonths($months)->plusDays($days); } $moy = CF::MONTH_OF_YEAR()->checkValidIntValue($fieldValues->remove(CF::MONTH_OF_YEAR())); $dom = CF::DAY_OF_MONTH()->checkValidIntValue($fieldValues->remove(CF::DAY_OF_MONTH())); if ($resolverStyle == ResolverStyle::SMART()) { // previous valid if ($moy == 4 || $moy == 6 || $moy == 9 || $moy == 11) { $dom = Math::min($dom, 30); } else { if ($moy == 2) { $dom = Math::min($dom, Month::FEBRUARY()->length(Year::isLeapYear($y))); } } } return LocalDate::of($y, $moy, $dom); }
/** * Calculates the period between this date and another date as a {@code Period}. * <p> * This calculates the period between two dates in terms of years, months and days. * The start and end points are {@code this} and the specified date. * The result will be negative if the end is before the start. * The negative sign will be the same in each of year, month and day. * <p> * The calculation is performed using the ISO calendar system. * If necessary, the input date will be converted to ISO. * <p> * The start date is included, but the end date is not. * The period is calculated by removing complete months, then calculating * the remaining number of days, adjusting to ensure that both have the same sign. * The number of months is then normalized into years and months based on a 12 month year. * A month is considered to be complete if the end day-of-month is greater * than or equal to the start day-of-month. * For example, from {@code 2010-01-15} to {@code 2011-03-18} is "1 year, 2 months and 3 days". * <p> * There are two equivalent ways of using this method. * The first is to invoke this method. * The second is to use {@link Period#between(LocalDate, LocalDate)}: * <pre> * // these two lines are equivalent * period = start.until(end); * period = Period.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. * * @param ChronoLocalDate $endDateExclusive the end date, exclusive, which may be in any chronology, not null * @return Period the period between this date and the end date, not null */ public function untilDate(ChronoLocalDate $endDateExclusive) { $end = LocalDate::from($endDateExclusive); $totalMonths = $end->getProlepticMonth() - $this->getProlepticMonth(); // safe $days = $end->day - $this->day; if ($totalMonths > 0 && $days < 0) { $totalMonths--; $calcDate = $this->plusMonths($totalMonths); $days = (int) ($end->toEpochDay() - $calcDate->toEpochDay()); // safe } else { if ($totalMonths < 0 && $days > 0) { $totalMonths++; $days -= $end->lengthOfMonth(); } } $years = Math::div($totalMonths, 12); // safe $months = (int) ($totalMonths % 12); // safe return Period::of(Math::toIntExact($years), $months, $days); }
public function test_parseBest_secondOption() { $test = DateTimeFormatter::ofPattern("yyyy-MM-dd[ HH:mm[XXX]]"); $result = $test->parseBest("2011-06-30", TemporalQueries::fromCallable([ZonedDateTime::class, "from"]), TemporalQueries::fromCallable([LocalDate::class, 'from'])); $this->assertEquals($result, LocalDate::of(2011, 6, 30)); }
/** * @group long */ public function test_loop() { // loop round at least one 400 $year cycle, including before 1970 $date = LocalDate::of(1960, 1, 5); // Tuseday of $week 1 1960 $year = 1960; $wby = 1960; $weekLen = 52; $week = 1; while ($date->getYear() < 2400) { $loopDow = $date->getDayOfWeek(); if ($date->getYear() != $year) { $year = $date->getYear(); } if ($loopDow == DayOfWeek::MONDAY()) { $week++; if ($week == 53 && $weekLen == 52 || $week == 54) { $week = 1; $firstDayOfWeekBasedYear = $date->plusDays(14)->withDayOfYear(1); $firstDay = $firstDayOfWeekBasedYear->getDayOfWeek(); $weekLen = $firstDay == DayOfWeek::THURSDAY() || $firstDay == DayOfWeek::WEDNESDAY() && $firstDayOfWeekBasedYear->isLeapYear() ? 53 : 52; $wby++; } } $this->assertEquals(IsoFields::WEEK_OF_WEEK_BASED_YEAR()->rangeRefinedBy($date), ValueRange::of(1, $weekLen), "Failed on " . $date . " " . $date->getDayOfWeek()); $this->assertEquals(IsoFields::WEEK_OF_WEEK_BASED_YEAR()->getFrom($date), $week, "Failed on " . $date . " " . $date->getDayOfWeek()); $this->assertEquals($date->get(IsoFields::WEEK_OF_WEEK_BASED_YEAR()), $week, "Failed on " . $date . " " . $date->getDayOfWeek()); $this->assertEquals(IsoFields::WEEK_BASED_YEAR()->getFrom($date), $wby, "Failed on " . $date . " " . $date->getDayOfWeek()); $this->assertEquals($date->get(IsoFields::WEEK_BASED_YEAR()), $wby, "Failed on " . $date . " " . $date->getDayOfWeek()); $date = $date->plusDays(1); } }
public function dateFrom(TemporalAccessor $temporal) { if ($temporal instanceof ThaiBuddhistDate) { return $temporal; } return ThaiBuddhistDate::ofIsoDate(LocalDate::from($temporal)); }
public function test_range() { $this->assertEquals(CF::MONTH_OF_YEAR()->range(), ValueRange::of(1, 12)); $this->assertEquals(CF::MONTH_OF_YEAR()->rangeRefinedBy(LocalDate::of(2000, 2, 29)), ValueRange::of(1, 12)); $this->assertEquals(CF::DAY_OF_MONTH()->range(), ValueRange::ofVariable(1, 28, 31)); $this->assertEquals(CF::DAY_OF_MONTH()->rangeRefinedBy(LocalDate::of(2000, 2, 29)), ValueRange::of(1, 29)); }
public function test_withNanoOfSecond_normal() { $base = OffsetDateTime::ofDateAndTime(LocalDate::of(2008, 6, 30), LocalTime::of(11, 30, 59, 1), self::OFFSET_PONE()); $test = $base->withNano(15); $this->assertEquals($test, OffsetDateTime::ofDateAndTime(LocalDate::of(2008, 6, 30), LocalTime::of(11, 30, 59, 15), self::OFFSET_PONE())); }
private function date($year, $month, $day) { return LocalDate::of($year, $month, $day); }
/** * @internal * @param LocalDate $date * @return int */ public static function getWeekBasedYear(LocalDate $date) { $year = $date->getYear(); $doy = $date->getDayOfYear(); if ($doy <= 3) { $dow = $date->getDayOfWeek()->getValue() - 1; if ($doy - $dow < -2) { $year--; } } else { if ($doy >= 363) { $dow = $date->getDayOfWeek()->getValue() - 1; $doy = $doy - 363 - ($date->isLeapYear() ? 1 : 0); if ($doy - $dow >= 0) { $year++; } } } return $year; }
public function dateNowOf(Clock $clock) { return $this->dateFrom(LocalDate::nowOf($clock)); }
/** * A query for {@code LocalDate} returning null if not found. * @param TemporalAccessor $temporal * @return null|LocalDate */ public static function _localDate(TemporalAccessor $temporal) { if ($temporal->isSupported(ChronoField::EPOCH_DAY())) { return LocalDate::ofEpochDay($temporal->getLong(ChronoField::EPOCH_DAY())); } return null; }
public function test_atYear_int_leapYearAdjust() { $test = MonthDay::of(2, 29); $this->assertEquals($test->atYear(2005), LocalDate::of(2005, 2, 28)); }
public function test_until_parisLondon() { $midnightLondon = LocalDate::of(2012, 6, 28)->atStartOfDayWithZone(self::ZONE_LONDON()); $midnightParis1 = LocalDate::of(2012, 6, 29)->atStartOfDayWithZone(self::ZONE_PARIS()); $oneAm1 = LocalDateTime::of(2012, 6, 29, 1, 0)->atZone(self::ZONE_PARIS()); $midnightParis2 = LocalDate::of(2012, 6, 30)->atStartOfDayWithZone(self::ZONE_PARIS()); $this->assertEquals($midnightLondon->until($midnightParis1, CU::HOURS()), 23); $this->assertEquals($midnightLondon->until($oneAm1, CU::HOURS()), 24); $this->assertEquals($midnightLondon->until($midnightParis2, CU::HOURS()), 23 + 24); $this->assertEquals($midnightLondon->until($midnightParis1, CU::DAYS()), 0); $this->assertEquals($midnightLondon->until($oneAm1, CU::DAYS()), 1); $this->assertEquals($midnightLondon->until($midnightParis2, CU::DAYS()), 1); }
public function data_signStyle() { return [[LocalDate::of(0, 10, 2), SignStyle::ALWAYS(), null, "+00"], [LocalDate::of(2001, 10, 2), SignStyle::ALWAYS(), null, "+2001"], [LocalDate::of(-2001, 10, 2), SignStyle::ALWAYS(), null, "-2001"], [LocalDate::of(2001, 10, 2), SignStyle::NORMAL(), null, "2001"], [LocalDate::of(-2001, 10, 2), SignStyle::NORMAL(), null, "-2001"], [LocalDate::of(2001, 10, 2), SignStyle::NEVER(), null, "2001"], [LocalDate::of(-2001, 10, 2), SignStyle::NEVER(), null, "2001"], [LocalDate::of(2001, 10, 2), SignStyle::NOT_NEGATIVE(), null, "2001"], [LocalDate::of(-2001, 10, 2), SignStyle::NOT_NEGATIVE(), DateTimeException::class, ""], [LocalDate::of(0, 10, 2), SignStyle::EXCEEDS_PAD(), null, "00"], [LocalDate::of(1, 10, 2), SignStyle::EXCEEDS_PAD(), null, "01"], [LocalDate::of(-1, 10, 2), SignStyle::EXCEEDS_PAD(), null, "-01"], [LocalDate::of(20001, 10, 2), SignStyle::ALWAYS(), DateTimeException::class, ""], [LocalDate::of(20001, 10, 2), SignStyle::NORMAL(), DateTimeException::class, ""], [LocalDate::of(20001, 10, 2), SignStyle::NEVER(), DateTimeException::class, ""], [LocalDate::of(20001, 10, 2), SignStyle::EXCEEDS_PAD(), DateTimeException::class, ""], [LocalDate::of(20001, 10, 2), SignStyle::NOT_NEGATIVE(), DateTimeException::class, ""]]; }
public function test_print_append() { $buf = "EXISTING"; $this->getFormatterWidth(ChronoField::DAY_OF_MONTH(), 1, 2, SignStyle::NEVER())->formatTo(LocalDate::of(2012, 1, 3), $buf); $this->assertEquals($buf, "EXISTING3"); }
/** * @expectedException \Celest\DateTimeException */ public function test_factory_between_TemporalTemporal_invalidMixedTypes() { $start = Instant::ofEpochSecond(1); $end = LocalDate::of(2010, 6, 20); Duration::between($start, $end); }
public function test_Apia_jumpForwardOverInternationalDateLine_P12_to_M12() { // transition occurred at 1879-07-04T00:00+12:33:04 $test = $this->pacificApia(); $instantBefore = LocalDate::of(1879, 7, 2)->atStartOfDayWithZone(ZoneOffset::UTC())->toInstant(); $trans = $test->nextTransition($instantBefore); $this->assertEquals($trans->getDateTimeBefore(), LocalDateTime::of(1879, 7, 5, 0, 0)); $this->assertEquals($trans->getDateTimeAfter(), LocalDateTime::of(1879, 7, 4, 0, 0)); $this->assertEquals($trans->isGap(), false); $this->assertEquals($trans->isOverlap(), true); $this->assertEquals($trans->isValidOffset(ZoneOffset::ofHoursMinutesSeconds(+12, 33, 4)), true); $this->assertEquals($trans->isValidOffset(ZoneOffset::ofHoursMinutesSeconds(-11, -26, -56)), true); $this->assertEquals($trans->getDuration(), Duration::ofHours(-24)); $this->assertEquals($trans->getInstant(), LocalDateTime::of(1879, 7, 4, 0, 0)->toInstant(ZoneOffset::ofHoursMinutesSeconds(-11, -26, -56))); $zdt = ZonedDateTime::of(1879, 7, 4, 23, 0, 0, 0, ZoneId::of("Pacific/Apia")); $this->assertEquals($zdt->plusHours(2)->toLocalDateTime(), LocalDateTime::of(1879, 7, 4, 1, 0, 0)); }
function provider_patternLocalWeekBasedYearDate() { return [["e w Y", "6 29 2012", LocalDate::of(2012, 7, 20)], ["'Date: 'Y', day-of-week: 'e', week-of-year: 'w", "Date: 2012, day-of-week: 6, week-of-year: 29", LocalDate::of(2012, 7, 20)], ["Y-ww-ee", "2008-01-01", LocalDate::of(2007, 12, 30)], ["Y-w-e", "2008-52-1", LocalDate::of(2008, 12, 21)], ["Y-w-e", "2008-52-7", LocalDate::of(2008, 12, 27)], ["Y-ww-e", "2009-01-1", LocalDate::of(2008, 12, 28)], ["Y-w-e", "2009-1-4", LocalDate::of(2008, 12, 31)], ["Y-w-e", "2009-1-5", LocalDate::of(2009, 1, 1)], ["YYYYYYYYY-w-e", "000002009-1-5", LocalDate::of(2009, 1, 1)]]; }
/** * @expectedException \Celest\DateTimeException */ public function test_adjustInto_dateOnly() { $base = ZoneOffset::ofHoursMinutesSeconds(1, 1, 1); $base->adjustInto(LocalDate::of(1909, 2, 2)); }
/** * Combines this year with a day-of-year to create a {@code LocalDate}. * <p> * This returns a {@code LocalDate} formed from this year and the specified day-of-year. * <p> * The day-of-year value 366 is only valid in a leap year. * * @param int $dayOfYear the day-of-year to use, from 1 to 365-366 * @return LocalDate the local date formed from this year and the specified date of year, not null * @throws DateTimeException if the day of year is zero or less, 366 or greater or equal * to 366 and this is not a leap year */ public function atDay($dayOfYear) { return LocalDate::ofYearDay($this->year, $dayOfYear); }