public function test_London_previousTransition_rulesBased() { $test = $this->europeLondon(); $rules = $test->getTransitionRules(); $trans = $test->getTransitions(); $last = $trans[count($trans) - 1]; $this->assertEquals($test->previousTransition($last->getInstant()->plusSeconds(1)), $last); $this->assertEquals($test->previousTransition($last->getInstant()->plusNanos(1)), $last); // Jan 1st of year between transitions and rules $odt = ZonedDateTime::ofInstant($last->getInstant(), $last->getOffsetAfter()); $odt = $odt->withDayOfYear(1)->plusYears(1)->adjust(LocalTime::MIDNIGHT()); $this->assertEquals($test->previousTransition($odt->toInstant()), $last); // later years for ($year = 1998; $year < 2010; $year++) { $a = $rules[0]->createTransition($year); $b = $rules[1]->createTransition($year); $c = $rules[0]->createTransition($year + 1); $this->assertEquals($test->previousTransition($c->getInstant()), $b); $this->assertEquals($test->previousTransition($b->getInstant()->plusSeconds(1)), $b); $this->assertEquals($test->previousTransition($b->getInstant()->plusNanos(1)), $b); $this->assertEquals($test->previousTransition($b->getInstant()), $a); $this->assertEquals($test->previousTransition($a->getInstant()->plusSeconds(1)), $a); $this->assertEquals($test->previousTransition($a->getInstant()->plusNanos(1)), $a); } }
/** * Adds a multi-year transition rule to the current window. * <p> * This adds a rule such that the offset, expressed as a daylight savings amount, * changes at the specified date-time for each year in the range. * * @param int $startYear the start year of the rule, from MIN_VALUE to MAX_VALUE * @param int $endYear the end year of the rule, from MIN_VALUE to MAX_VALUE * @param Month $month the month of the transition, not null * @param int $dayOfMonthIndicator the day-of-month of the transition, adjusted by dayOfWeek, * from 1 to 31 adjusted later, or -1 to -28 adjusted earlier from the last day of the month * @param DayOfWeek|null $dayOfWeek the day-of-week to adjust to, null if day-of-month should not be adjusted * @param LocalTime $time the time that the transition occurs as defined by timeDefintion, not null * @param bool $timeEndOfDay whether midnight is at the end of day * @param TimeDefinition $timeDefinition the definition of how to convert local to actual time, not null * @param int $savingAmountSecs the amount of saving from the standard offset after the transition in seconds * @return ZoneRulesBuilder $this, for chaining * @throws DateTimeException if a date-time field is out of range * @throws IllegalArgumentException if the day of month indicator is invalid * @throws IllegalArgumentException if the end of day midnight flag does not match the time * @throws \LogicException if no window has yet been added * @throws \LogicException if the window already has fixed savings * @throws \LogicException if the window has reached the maximum capacity of 2000 rules */ public function addRuleToWindow9($startYear, $endYear, Month $month, $dayOfMonthIndicator, $dayOfWeek, LocalTime $time, $timeEndOfDay, TimeDefinition $timeDefinition, $savingAmountSecs) { ChronoField::YEAR()->checkValidValue($startYear); ChronoField::YEAR()->checkValidValue($endYear); if ($dayOfMonthIndicator < -28 || $dayOfMonthIndicator > 31 || $dayOfMonthIndicator === 0) { throw new IllegalArgumentException("Day of month indicator must be between -28 and 31 inclusive excluding zero"); } if ($timeEndOfDay && $time->equals(LocalTime::MIDNIGHT()) == false) { throw new IllegalArgumentException("Time must be midnight when end of day flag is true"); } if (empty($this->windowList)) { throw new \LogicException("Must add a window before adding a rule"); } $window = $this->windowList[count($this->windowList) - 1]; $window->addRule($startYear, $endYear, $month, $dayOfMonthIndicator, $dayOfWeek, $time, $timeEndOfDay, $timeDefinition, $savingAmountSecs); return $this; }
public function test_truncatedTo_normal() { $this->assertEquals($this->TEST_DATE_TIME->truncatedTo(CU::NANOS()), $this->TEST_DATE_TIME); $this->assertEquals($this->TEST_DATE_TIME->truncatedTo(CU::SECONDS()), $this->TEST_DATE_TIME->withNano(0)); $this->assertEquals($this->TEST_DATE_TIME->truncatedTo(CU::DAYS()), $this->TEST_DATE_TIME->adjust(LocalTime::MIDNIGHT())); }
/** * Returns a zoned date-time from this date at the earliest valid time according * to the rules in the time-zone. * <p> * Time-zone rules, such as daylight savings, mean that not every local date-time * is valid for the specified zone, thus the local date-time may not be midnight. * <p> * In most cases, there is only one valid offset for a local date-time. * In the case of an overlap, there are two valid offsets, and the earlier one is used, * corresponding to the first occurrence of midnight on the date. * In the case of a gap, the zoned date-time will represent the instant just after the gap. * <p> * If the zone ID is a {@link ZoneOffset}, then the result always has a time of midnight. * <p> * To convert to a specific time in a given time-zone call {@link #atTime(LocalTime)} * followed by {@link LocalDateTime#atZone(ZoneId)}. * * @param ZoneId $zone the zone ID to use, not null * @return ZonedDateTime the zoned date-time formed from this date and the earliest valid time for the zone, not null */ public function atStartOfDayWithZone(ZoneId $zone) { // need to handle case where there is a gap from 11:30 to 00:30 // standard ZDT factory would result in 01:00 rather than 00:30 $ldt = $this->atTime(LocalTime::MIDNIGHT()); if ($zone instanceof ZoneOffset === false) { $rules = $zone->getRules(); $trans = $rules->getTransition($ldt); if ($trans != null && $trans->isGap()) { $ldt = $trans->getDateTimeAfter(); } } return ZonedDateTime::ofDateTime($ldt, $zone); }
public function __construct() { $this->month = Month::JANUARY(); $this->time = LocalTime::MIDNIGHT(); $this->timeDefinition = TimeDefinition::WALL(); }
function comparisons_LocalDateTime(array $localDates) { $this->comparisons_LocalDateTime2($localDates, [LocalTime::MIDNIGHT(), LocalTime::of(0, 0, 0, 999999999), LocalTime::of(0, 0, 59, 0), LocalTime::of(0, 0, 59, 999999999), LocalTime::of(0, 59, 0, 0), LocalTime::of(0, 59, 59, 999999999), LocalTime::NOON(), LocalTime::of(12, 0, 0, 999999999), LocalTime::of(12, 0, 59, 0), LocalTime::of(12, 0, 59, 999999999), LocalTime::of(12, 59, 0, 0), LocalTime::of(12, 59, 59, 999999999), LocalTime::of(23, 0, 0, 0), LocalTime::of(23, 0, 0, 999999999), LocalTime::of(23, 0, 59, 0), LocalTime::of(23, 0, 59, 999999999), LocalTime::of(23, 59, 0, 0), LocalTime::of(23, 59, 59, 999999999)]); }
public function test_truncatedTo_normal() { $this->assertEquals(self::TEST_2008_6_30_11_30_59_000000500()->truncatedTo(CU::NANOS()), self::TEST_2008_6_30_11_30_59_000000500()); $this->assertEquals(self::TEST_2008_6_30_11_30_59_000000500()->truncatedTo(CU::SECONDS()), self::TEST_2008_6_30_11_30_59_000000500()->withNano(0)); $this->assertEquals(self::TEST_2008_6_30_11_30_59_000000500()->truncatedTo(CU::DAYS()), self::TEST_2008_6_30_11_30_59_000000500()->adjust(LocalTime::MIDNIGHT())); }
/** * Obtains an instance defining the yearly rule to create transitions between two offsets. * <p> * Applications should normally obtain an instance from {@link ZoneRules}. * This factory is only intended for use when creating {@link ZoneRules}. * * @param Month $month the month of the month-day of the first day of the cutover week, not null * @param int $dayOfMonthIndicator the day of the month-day of the cutover week, positive if the week is that * day or later, negative if the week is that day or earlier, counting from the last day of the month, * from -28 to 31 excluding 0 * @param DayOfWeek|null $dayOfWeek the required day-of-week, null if the month-day should not be changed * @param LocalTime $time the cutover time in the 'before' offset, not null * @param bool $timeEndOfDay whether the time is midnight at the end of day * @param TimeDefinition $timeDefnition how to interpret the cutover * @param ZoneOffset $standardOffset the standard offset in force at the cutover, not null * @param ZoneOffset $offsetBefore the offset before the cutover, not null * @param ZoneOffset $offsetAfter the offset after the cutover, not null * @return ZoneOffsetTransitionRule the rule, not null * @throws IllegalArgumentException if the day of month indicator is invalid * @throws IllegalArgumentException if the end of day flag is true when the time is not midnight */ public static function of(Month $month, $dayOfMonthIndicator, $dayOfWeek, LocalTime $time, $timeEndOfDay, TimeDefinition $timeDefnition, ZoneOffset $standardOffset, ZoneOffset $offsetBefore, ZoneOffset $offsetAfter) { if ($dayOfMonthIndicator < -28 || $dayOfMonthIndicator > 31 || $dayOfMonthIndicator == 0) { throw new IllegalArgumentException("Day of month indicator must be between -28 and 31 inclusive excluding zero"); } if ($timeEndOfDay && $time->equals(LocalTime::MIDNIGHT()) == false) { throw new IllegalArgumentException("Time must be midnight when end of day flag is true"); } return new ZoneOffsetTransitionRule($month, $dayOfMonthIndicator, $dayOfWeek, $time, $timeEndOfDay, $timeDefnition, $standardOffset, $offsetBefore, $offsetAfter); }
public function test_toString_floatingWeek_overlap_endOfDay() { $test = ZoneOffsetTransitionRule::of(Month::OCTOBER(), 20, DayOfWeek::SUNDAY(), LocalTime::MIDNIGHT(), true, TimeDefinition::WALL(), self::OFFSET_0200(), self::OFFSET_0300(), self::OFFSET_0200()); $this->assertEquals($test->__toString(), "TransitionRule[Overlap +03:00 to +02:00, SUNDAY on or after OCTOBER 20 at 24:00 WALL, standard offset +02:00]"); }
private function resolveTime($hod, $moh, $som, $nos) { if ($this->resolverStyle == ResolverStyle::LENIENT()) { $totalNanos = Math::multiplyExact($hod, 3600000000000); $totalNanos = Math::addExact($totalNanos, Math::multiplyExact($moh, 60000000000)); $totalNanos = Math::addExact($totalNanos, Math::multiplyExact($som, 1000000000)); $totalNanos = Math::addExact($totalNanos, $nos); $excessDays = (int) Math::floorDiv($totalNanos, 86400000000000); // safe int cast $nod = Math::floorMod($totalNanos, 86400000000000); $this->updateCheckConflict(LocalTime::ofNanoOfDay($nod), Period::ofDays($excessDays)); } else { // STRICT or SMART $mohVal = CF::MINUTE_OF_HOUR()->checkValidIntValue($moh); $nosVal = CF::NANO_OF_SECOND()->checkValidIntValue($nos); // handle 24:00 end of day if ($this->resolverStyle == ResolverStyle::SMART() && $hod == 24 && $mohVal == 0 && $som == 0 && $nosVal == 0) { $this->updateCheckConflict(LocalTime::MIDNIGHT(), Period::ofDays(1)); } else { $hodVal = CF::HOUR_OF_DAY()->checkValidIntValue($hod); $somVal = CF::SECOND_OF_MINUTE()->checkValidIntValue($som); $this->updateCheckConflict(LocalTime::of($hodVal, $mohVal, $somVal, $nosVal), Period::ZERO()); } } }
public function test_comparisons() { $this->doTest_comparisons_LocalTime([LocalTime::MIDNIGHT(), LocalTime::of(0, 0, 0, 999999999), LocalTime::of(0, 0, 59, 0), LocalTime::of(0, 0, 59, 999999999), LocalTime::of(0, 59, 0, 0), LocalTime::of(0, 59, 0, 999999999), LocalTime::of(0, 59, 59, 0), LocalTime::of(0, 59, 59, 999999999), LocalTime::NOON(), LocalTime::of(12, 0, 0, 999999999), LocalTime::of(12, 0, 59, 0), LocalTime::of(12, 0, 59, 999999999), LocalTime::of(12, 59, 0, 0), LocalTime::of(12, 59, 0, 999999999), LocalTime::of(12, 59, 59, 0), LocalTime::of(12, 59, 59, 999999999), LocalTime::of(23, 0, 0, 0), LocalTime::of(23, 0, 0, 999999999), LocalTime::of(23, 0, 59, 0), LocalTime::of(23, 0, 59, 999999999), LocalTime::of(23, 59, 0, 0), LocalTime::of(23, 59, 0, 999999999), LocalTime::of(23, 59, 59, 0), LocalTime::of(23, 59, 59, 999999999)]); }