public function test_parse_leapSecond()
 {
     $expected = OffsetDateTime::of(1970, 2, 3, 23, 59, 59, 123456789, ZoneOffset::UTC())->toInstant();
     $f = (new DateTimeFormatterBuilder())->appendInstant4(-1)->toFormatter();
     foreach (ResolverStyle::values() as $style) {
         $pared = $f->withResolverStyle($style)->parse("1970-02-03T23:59:60.123456789Z");
         $this->assertEquals($pared->query(Instant::fromQuery()), $expected);
         $this->assertEquals($pared->query(DateTimeFormatter::parsedExcessDays()), Period::ZERO());
         $this->assertEquals($pared->query(DateTimeFormatter::parsedLeapSecond()), true);
     }
 }
Пример #2
0
 /**
  * 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);
 }
Пример #3
0
 function data_minus_TemporalAmount()
 {
     return [[YearMonth::of(1, 1), Period::ofYears(1), YearMonth::of(0, 1), null], [YearMonth::of(1, 1), Period::ofYears(-12), YearMonth::of(13, 1), null], [YearMonth::of(1, 1), Period::ofYears(0), YearMonth::of(1, 1), null], [YearMonth::of(999999999, 12), Period::ofYears(0), YearMonth::of(999999999, 12), null], [YearMonth::of(-999999999, 1), Period::ofYears(0), YearMonth::of(-999999999, 1), null], [YearMonth::of(0, 1), Period::ofYears(999999999), YearMonth::of(-999999999, 1), null], [YearMonth::of(0, 12), Period::ofYears(-999999999), YearMonth::of(999999999, 12), null], [YearMonth::of(1, 1), Period::ofMonths(1), YearMonth::of(0, 12), null], [YearMonth::of(1, 1), Period::ofMonths(-12), YearMonth::of(2, 1), null], [YearMonth::of(1, 1), Period::ofMonths(121), YearMonth::of(-10, 12), null], [YearMonth::of(1, 1), Period::ofMonths(0), YearMonth::of(1, 1), null], [YearMonth::of(999999999, 12), Period::ofMonths(0), YearMonth::of(999999999, 12), null], [YearMonth::of(-999999999, 1), Period::ofMonths(0), YearMonth::of(-999999999, 1), null], [YearMonth::of(-999999999, 2), Period::ofMonths(1), YearMonth::of(-999999999, 1), null], [YearMonth::of(999999999, 11), Period::ofMonths(-1), YearMonth::of(999999999, 12), null], [YearMonth::of(1, 1), Period::ofYears(1)->withMonths(2), YearMonth::of(-1, 11), null], [YearMonth::of(1, 1), Period::ofYears(-12)->withMonths(-1), YearMonth::of(13, 2), null], [YearMonth::of(1, 1), Period::ofMonths(2)->withYears(1), YearMonth::of(-1, 11), null], [YearMonth::of(1, 1), Period::ofMonths(-1)->withYears(-12), YearMonth::of(13, 2), null], [YearMonth::of(1, 1), Period::ofDays(365), null, DateTimeException::class], [YearMonth::of(1, 1), Duration::ofDays(365), null, DateTimeException::class], [YearMonth::of(1, 1), Duration::ofHours(365 * 24), null, DateTimeException::class], [YearMonth::of(1, 1), Duration::ofMinutes(365 * 24 * 60), null, DateTimeException::class], [YearMonth::of(1, 1), Duration::ofSeconds(365 * 24 * 3600), null, DateTimeException::class], [YearMonth::of(1, 1), Duration::ofNanos(365 * 24 * 3600 * 1000000000), null, DateTimeException::class]];
 }
 /**
  * @dataProvider data_plusDays
  */
 public function test_minus_TemporalAmount_Period_days(ZonedDateTime $base, $amount, ZonedDateTime $expected)
 {
     $this->assertEquals($base->minusAmount(Period::ofDays(-$amount)), $expected);
 }
Пример #5
0
 /**
  * @expectedException \Celest\DateTimeException
  */
 public function test_factory_from_TemporalAmount_Period()
 {
     Duration::from(Period::ZERO());
 }
Пример #6
0
 public function period($years, $months, $days)
 {
     return Period::of($years, $months, $days);
 }
Пример #7
0
 /**
  * A query that provides access to the excess days that were parsed.
  * <p>
  * This returns a singleton {@linkplain TemporalQuery query} that provides
  * access to additional information from the parse. The query always returns
  * a non-null period, with a zero period returned instead of null.
  * <p>
  * There are two situations where this query may return a non-zero period.
  * <ul>
  * <li>If the {@code ResolverStyle} is {@code LENIENT} and a time is parsed
  *  without a date, then the complete result of the parse consists of a
  *  {@code LocalTime} and an excess {@code Period} in days.
  *
  * <li>If the {@code ResolverStyle} is {@code SMART} and a time is parsed
  *  without a date where the time is 24:00:00, then the complete result of
  *  the parse consists of a {@code LocalTime} of 00:00:00 and an excess
  *  {@code Period} of one day.
  * </ul>
  * <p>
  * In both cases, if a complete {@code ChronoLocalDateTime} or {@code Instant}
  * is parsed, then the excess days are added to the date part.
  * As a result, this query will return a zero period.
  * <p>
  * The {@code SMART} behaviour handles the common "end of day" 24:00 value.
  * Processing in {@code LENIENT} mode also produces the same result:
  * <pre>
  *  Text to parse        Parsed object                         Excess days
  *  "2012-12-03T00:00"   LocalDateTime.of(2012, 12, 3, 0, 0)   ZERO
  *  "2012-12-03T24:00"   LocalDateTime.of(2012, 12, 4, 0, 0)   ZERO
  *  "00:00"              LocalTime.of(0, 0)                    ZERO
  *  "24:00"              LocalTime.of(0, 0)                    Period.ofDays(1)
  * </pre>
  * The query can be used as follows:
  * <pre>
  *  TemporalAccessor parsed = formatter.parse(str);
  *  LocalTime time = parsed.query(LocalTime::from);
  *  Period extraDays = parsed.query(DateTimeFormatter.parsedExcessDays());
  * </pre>
  * @return TemporalQuery a query that provides access to the excess days that were parsed
  */
 public static function parsedExcessDays()
 {
     return self::$PARSED_EXCESS_DAYS = new FuncTemporalQuery(function (TemporalAccessor $t) {
         if ($t instanceof Parsed) {
             return $t->excessDays;
         } else {
             return Period::ZERO();
         }
     });
 }
Пример #8
0
 public function test_periodUntil_LocalDate_max()
 {
     $years = Math::toIntExact(Year::MAX_VALUE - Year::MIN_VALUE);
     $this->assertEquals(LocalDate::MIN()->untilDate(LocalDate::MAX()), Period::of($years, 11, 30));
 }
Пример #9
0
 private static function pymd($y, $m, $d)
 {
     return Period::of($y, $m, $d);
 }
Пример #10
0
 private function updateCheckConflict(LocalTime $timeToSet, Period $periodToSet)
 {
     if ($this->time != null) {
         if ($this->time->equals($timeToSet) == false) {
             throw new DateTimeException("Conflict found: Fields resolved to different times: " . $this->time . " " . $timeToSet);
         }
         if ($this->excessDays->isZero() == false && $periodToSet->isZero() == false && $this->excessDays->equals($periodToSet) == false) {
             throw new DateTimeException("Conflict found: Fields resolved to different excess periods: " . $this->excessDays . " " . $periodToSet);
         } else {
             $this->excessDays = $periodToSet;
         }
     } else {
         $this->time = $timeToSet;
         $this->excessDays = $periodToSet;
     }
 }
 /**
  * @dataProvider data_resolveClockHourOfDay
  */
 public function test_resolveClockHourOfDay(ResolverStyle $style, $value, $expectedHour, $expectedDays)
 {
     $str = strval($value);
     $f = (new DateTimeFormatterBuilder())->appendValue(ChronoField::CLOCK_HOUR_OF_DAY())->toFormatter();
     if ($expectedHour !== null) {
         $accessor = $f->withResolverStyle($style)->parse($str);
         $this->assertEquals($accessor->query(TemporalQueries::localDate()), null);
         $this->assertEquals($accessor->query(TemporalQueries::localTime()), LocalTime::of($expectedHour, 0));
         $this->assertEquals($accessor->query(DateTimeFormatter::parsedExcessDays()), Period::ofDays($expectedDays));
     } else {
         try {
             $f->withResolverStyle($style)->parse($str);
             $this->fail();
         } catch (DateTimeParseException $ex) {
             // $expected
         }
     }
 }
Пример #12
0
 function data_minusInvalidUnit()
 {
     return [[Period::of(0, 1, 0)], [Period::of(0, 0, 1)], [Period::of(0, 1, 1)], [Period::of(1, 1, 1)], [Duration::ofDays(1)], [Duration::ofHours(1)], [Duration::ofMinutes(1)], [Duration::ofSeconds(1)]];
 }
Пример #13
0
 public function test_minus_TemporalAmount_zero()
 {
     $period = Period::ZERO();
     $t = self::TEST_123040987654321()->minusAmount($period);
     $this->assertEquals($t, self::TEST_123040987654321());
 }
Пример #14
0
 public function test_minus_MinusAdjuster_zero()
 {
     $t = self::TEST_11_30_59_500_PONE()->minusAmount(Period::ZERO());
     $this->assertEquals($t, self::TEST_11_30_59_500_PONE());
 }
Пример #15
0
 /**
  * Returns a copy of this period with the specified period subtracted.
  * <p>
  * This operates separately on the years, months and days.
  * No normalization is performed.
  * <p>
  * For example, "1 year, 6 months and 3 days" minus "2 years, 2 months and 2 days"
  * returns "-1 years, 4 months and 1 day".
  * <p>
  * The specified amount is typically an instance of {@code Period}.
  * Other types are interpreted using {@link Period#from(TemporalAmount)}.
  * <p>
  * This instance is immutable and unaffected by this method call.
  *
  * @param TemporalAmount $amountToSubtract the amount to subtract, not null
  * @return Period a {@code Period} based on this period with the requested period subtracted, not null
  * @throws DateTimeException if the specified amount has a non-ISO chronology or
  *  contains an invalid unit
  * @throws ArithmeticException if numeric overflow occurs
  */
 public function minusAmount(TemporalAmount $amountToSubtract)
 {
     $isoAmount = Period::from($amountToSubtract);
     return $this->create(Math::subtractExact($this->years, $isoAmount->years), Math::subtractExact($this->months, $isoAmount->months), Math::subtractExact($this->days, $isoAmount->days));
 }