[15] RFR: 8239836: ZoneRules.of() doesn't check transitionList/standardOffsetTL arguments validity
naoto.sato at oracle.com
naoto.sato at oracle.com
Wed Mar 4 19:05:47 UTC 2020
Hi Stephen,
Thank you for the detailed explanation and correcting the
implementation. I incorporated all the suggestions below, as well as
adding a new test for isFixedOffset() implementation (with some clean-up):
https://cr.openjdk.java.net/~naoto/8239836/webrev.03/
Please take a look at it.
Naoto
On 3/3/20 3:30 PM, Stephen Colebourne wrote:
> I fear more changes are needed here.
>
> 1) The code is isFixedOffset() is indeed wrong, but the fix is
> insufficient. The zone is fixed if baseStandardOffset=baseWallOffset
> and all three other lists are empty. A fixed offset rule is the
> equivalent of a ZoneOffset. See ZoneId.normalized() for the code that
> assumes that.
>
> 2) The code in getOffset(Instant) is wrong, but so is the proposed
> fix. The purpose of the if statement is to optimise the following few
> lines which refer to savingsInstantTransitions and wallOffsets. The
> code does have a bug as it should return the first wall offset.
> Corrected code:
> public ZoneOffset getOffset(Instant instant) {
> if (savingsInstantTransitions.length == 0) {
> return wallOffsets[0];
> }
> With the correct definition of isFixedOffset() it becomes apparent
> that this if statement is in fact not related to the fixed offset.
>
> Currently this test case fails (a zone in DST for all eternity):
> ZoneRules rules = ZoneRules.of(
> ZoneOffset.ofHours(1),
> ZoneOffset.ofHours(2),
> Collections.emptyList(),
> Collections.emptyList(),
> Collections.emptyList());
> assertEquals(rules.getStandardOffset(Instant.EPOCH),
> ZoneOffset.ofHours(1));
> assertEquals(rules.getOffset(Instant.EPOCH), ZoneOffset.ofHours(2));
>
> 3) The code in getStandardOffset(Instant) also has an error as it
> checks the wrong array. It should check standardTransitions as that is
> what is used in the following few lines. Corrected code:
> public ZoneOffset getStandardOffset(Instant instant) {
> if (standardTransitions.length == 0) {
> return standardOffsets[0];
> }
>
> 4) The code in getOffsetInfo(LocalDateTime dt) has a similar fault.
> Since it protects savingsLocalTransitions, it should return
> wallOffsets[0].
>
> 5) The code in getDaylightSavings(Instant instant) has an optimising
> if statement that should refer to isFixedOffset().
>
> 6) Also, in the test.
> assertTrue(!rules.isFixedOffset());
> should be
> assertFalse(rules.isFixedOffset());
>
> The class has worked so far as every normal case has
> baseStandardOffset = baseWallOffset, even though it is conceptually
> valid for this not to be true.
>
> Stephen
>
>
>
>
> On Thu, 27 Feb 2020 at 20:42, <naoto.sato at oracle.com> wrote:
>>
>> Hello,
>>
>> Please review the fix to the following issue:
>>
>> https://bugs.openjdk.java.net/browse/JDK-8239836
>>
>> The proposed changeset is located at:
>>
>> https://cr.openjdk.java.net/~naoto/8239836/webrev.00/
>>
>> It turned out that 'transitionList' is not necessarily a superset of
>> 'standardOffsetTransitionList', as in some occasions where a standard
>> offset change and a savings change happen at the same time (canceling
>> each other), resulting in no wall time transition. This means that the
>> "rules" in the sample code is a valid ZoneRules instance.
>>
>> However, there is an assumption in ZoneRules where no (wall time)
>> transition means the fixed offset zone. With that assumption, the
>> example rule is considered a fixed offset zone which is not correct. So
>> the fix proposed here is not to throw an IAE but to recognize the rule
>> as a valid, non-fixed offset ZoneRules instance.
>>
>> Naoto
>>
>>
More information about the core-libs-dev
mailing list