A DESCRIPTION OF THE PROBLEM :
The method java.time.zone.ZoneRules#getOffset(java.time.Instant) will throw the following exception:
Exception in thread "main" java.time.DateTimeException: Invalid value for EpochDay (valid values -365243219162 - 365241780471): 365241780472
at java.base/java.time.temporal.ValueRange.checkValidValue(ValueRange.java:311)
at java.base/java.time.temporal.ChronoField.checkValidValue(ChronoField.java:717)
at java.base/java.time.LocalDate.ofEpochDay(LocalDate.java:341)
at java.base/java.time.zone.ZoneRules.findYear(ZoneRules.java:927)
at java.base/java.time.zone.ZoneRules.getOffset(ZoneRules.java:486)
if the ZoneRules has a last rule and has a transition such that when added to the instant will be larger than the maximum epoch-day.
Offsets of the same size that do not contain last rules will not throw an error for the same instants.
The method does not declare that a DateTimeException exception may be thrown and the description implies that it should be possible to get the offset for any instant.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
â observability git:(master) jshell
| Welcome to JShell -- Version 13.0.1
| For an introduction type: /help intro
jshell> import java.time.*;
...> import java.time.zone.ZoneOffsetTransition;
...> import java.time.zone.ZoneOffsetTransitionRule;
...> import java.time.zone.ZoneRules;
...> import java.util.Collections;
...>
jshell> Instant maxLocalDateTime = LocalDateTime.of(Year.MAX_VALUE,
...> 12,
...> 31,
...> 23,
...> 59,
...> 59,
...> 999999999).toInstant(ZoneOffset.UTC);
...> ZoneOffset offsetZero = ZoneOffset.ofHours(0);
...> ZoneOffset offsetPlusOneHour = ZoneOffset.ofHours(1);
...> ZoneRules zoneRulesA = ZoneRules.of(offsetPlusOneHour);
...> ZoneOffsetTransition transition = ZoneOffsetTransition.of(LocalDateTime.ofEpochSecond(0, 0, offsetZero),
...> offsetZero,
...> offsetPlusOneHour);
...> ZoneOffsetTransitionRule transitionRule = ZoneOffsetTransitionRule.of(Month.JANUARY,
...> 1,
...> DayOfWeek.SUNDAY,
...> LocalTime.MIDNIGHT,
...> true,
...> ZoneOffsetTransitionRule.TimeDefinition.STANDARD,
...> offsetZero,
...> offsetZero,
...> offsetPlusOneHour);
...> ZoneRules zoneRulesB = ZoneRules.of(offsetZero,
...> offsetZero,
...> Collections.singletonList(transition),
...> Collections.singletonList(transition),
...> Collections.singletonList(transitionRule));
...> ZoneOffset offsetA = zoneRulesA.getOffset(maxLocalDateTime);
...> ZoneOffset offsetB = zoneRulesB.getOffset(maxLocalDateTime);
...> boolean areEqual = offsetA.equals(offsetB);
...>
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
areEqual ==> true
ACTUAL -
| Exception java.time.DateTimeException: Invalid value for EpochDay (valid values -365243219162 - 365241780471): 365241780472
| at ValueRange.checkValidValue (ValueRange.java:311)
| at ChronoField.checkValidValue (ChronoField.java:717)
| at LocalDate.ofEpochDay (LocalDate.java:341)
| at ZoneRules.findYear (ZoneRules.java:927)
| at ZoneRules.getOffset (ZoneRules.java:486)
| at (#14:1)
---------- BEGIN SOURCE ----------
import java.time.*;
import java.time.zone.ZoneOffsetTransition;
import java.time.zone.ZoneOffsetTransitionRule;
import java.time.zone.ZoneRules;
import java.util.Collections;
public class ZoneRulesBug {
public static void main(String[] args) {
Instant maxLocalDateTime = LocalDateTime.of(Year.MAX_VALUE,
12,
31,
23,
59,
59,
999999999).toInstant(ZoneOffset.UTC);
ZoneOffset offsetZero = ZoneOffset.ofHours(0);
ZoneOffset offsetPlusOneHour = ZoneOffset.ofHours(1);
ZoneRules zoneRulesA = ZoneRules.of(offsetPlusOneHour);
ZoneOffsetTransition transition = ZoneOffsetTransition.of(LocalDateTime.ofEpochSecond(0, 0, offsetZero),
offsetZero,
offsetPlusOneHour);
ZoneOffsetTransitionRule transitionRule = ZoneOffsetTransitionRule.of(Month.JANUARY,
1,
DayOfWeek.SUNDAY,
LocalTime.MIDNIGHT,
true,
ZoneOffsetTransitionRule.TimeDefinition.STANDARD,
offsetZero,
offsetZero,
offsetPlusOneHour);
ZoneRules zoneRulesB = ZoneRules.of(offsetZero,
offsetZero,
Collections.singletonList(transition),
Collections.singletonList(transition),
Collections.singletonList(transitionRule));
ZoneOffset offsetA = zoneRulesA.getOffset(maxLocalDateTime);
ZoneOffset offsetB = zoneRulesB.getOffset(maxLocalDateTime);
boolean areEqual = offsetA.equals(offsetB);
System.out.println(areEqual);
}
}
---------- END SOURCE ----------
FREQUENCY : always
The method java.time.zone.ZoneRules#getOffset(java.time.Instant) will throw the following exception:
Exception in thread "main" java.time.DateTimeException: Invalid value for EpochDay (valid values -365243219162 - 365241780471): 365241780472
at java.base/java.time.temporal.ValueRange.checkValidValue(ValueRange.java:311)
at java.base/java.time.temporal.ChronoField.checkValidValue(ChronoField.java:717)
at java.base/java.time.LocalDate.ofEpochDay(LocalDate.java:341)
at java.base/java.time.zone.ZoneRules.findYear(ZoneRules.java:927)
at java.base/java.time.zone.ZoneRules.getOffset(ZoneRules.java:486)
if the ZoneRules has a last rule and has a transition such that when added to the instant will be larger than the maximum epoch-day.
Offsets of the same size that do not contain last rules will not throw an error for the same instants.
The method does not declare that a DateTimeException exception may be thrown and the description implies that it should be possible to get the offset for any instant.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
â observability git:(master) jshell
| Welcome to JShell -- Version 13.0.1
| For an introduction type: /help intro
jshell> import java.time.*;
...> import java.time.zone.ZoneOffsetTransition;
...> import java.time.zone.ZoneOffsetTransitionRule;
...> import java.time.zone.ZoneRules;
...> import java.util.Collections;
...>
jshell> Instant maxLocalDateTime = LocalDateTime.of(Year.MAX_VALUE,
...> 12,
...> 31,
...> 23,
...> 59,
...> 59,
...> 999999999).toInstant(ZoneOffset.UTC);
...> ZoneOffset offsetZero = ZoneOffset.ofHours(0);
...> ZoneOffset offsetPlusOneHour = ZoneOffset.ofHours(1);
...> ZoneRules zoneRulesA = ZoneRules.of(offsetPlusOneHour);
...> ZoneOffsetTransition transition = ZoneOffsetTransition.of(LocalDateTime.ofEpochSecond(0, 0, offsetZero),
...> offsetZero,
...> offsetPlusOneHour);
...> ZoneOffsetTransitionRule transitionRule = ZoneOffsetTransitionRule.of(Month.JANUARY,
...> 1,
...> DayOfWeek.SUNDAY,
...> LocalTime.MIDNIGHT,
...> true,
...> ZoneOffsetTransitionRule.TimeDefinition.STANDARD,
...> offsetZero,
...> offsetZero,
...> offsetPlusOneHour);
...> ZoneRules zoneRulesB = ZoneRules.of(offsetZero,
...> offsetZero,
...> Collections.singletonList(transition),
...> Collections.singletonList(transition),
...> Collections.singletonList(transitionRule));
...> ZoneOffset offsetA = zoneRulesA.getOffset(maxLocalDateTime);
...> ZoneOffset offsetB = zoneRulesB.getOffset(maxLocalDateTime);
...> boolean areEqual = offsetA.equals(offsetB);
...>
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
areEqual ==> true
ACTUAL -
| Exception java.time.DateTimeException: Invalid value for EpochDay (valid values -365243219162 - 365241780471): 365241780472
| at ValueRange.checkValidValue (ValueRange.java:311)
| at ChronoField.checkValidValue (ChronoField.java:717)
| at LocalDate.ofEpochDay (LocalDate.java:341)
| at ZoneRules.findYear (ZoneRules.java:927)
| at ZoneRules.getOffset (ZoneRules.java:486)
| at (#14:1)
---------- BEGIN SOURCE ----------
import java.time.*;
import java.time.zone.ZoneOffsetTransition;
import java.time.zone.ZoneOffsetTransitionRule;
import java.time.zone.ZoneRules;
import java.util.Collections;
public class ZoneRulesBug {
public static void main(String[] args) {
Instant maxLocalDateTime = LocalDateTime.of(Year.MAX_VALUE,
12,
31,
23,
59,
59,
999999999).toInstant(ZoneOffset.UTC);
ZoneOffset offsetZero = ZoneOffset.ofHours(0);
ZoneOffset offsetPlusOneHour = ZoneOffset.ofHours(1);
ZoneRules zoneRulesA = ZoneRules.of(offsetPlusOneHour);
ZoneOffsetTransition transition = ZoneOffsetTransition.of(LocalDateTime.ofEpochSecond(0, 0, offsetZero),
offsetZero,
offsetPlusOneHour);
ZoneOffsetTransitionRule transitionRule = ZoneOffsetTransitionRule.of(Month.JANUARY,
1,
DayOfWeek.SUNDAY,
LocalTime.MIDNIGHT,
true,
ZoneOffsetTransitionRule.TimeDefinition.STANDARD,
offsetZero,
offsetZero,
offsetPlusOneHour);
ZoneRules zoneRulesB = ZoneRules.of(offsetZero,
offsetZero,
Collections.singletonList(transition),
Collections.singletonList(transition),
Collections.singletonList(transitionRule));
ZoneOffset offsetA = zoneRulesA.getOffset(maxLocalDateTime);
ZoneOffset offsetB = zoneRulesB.getOffset(maxLocalDateTime);
boolean areEqual = offsetA.equals(offsetB);
System.out.println(areEqual);
}
}
---------- END SOURCE ----------
FREQUENCY : always