mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8236903: ZoneRules#getOffset throws DateTimeException for rules with last rules
Reviewed-by: scolebourne, rriggs
This commit is contained in:
parent
b7cdc097e3
commit
d517220df6
2 changed files with 94 additions and 12 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -69,7 +69,6 @@ import java.io.ObjectInputStream;
|
|||
import java.io.Serializable;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
|
@ -162,6 +161,16 @@ public final class ZoneRules implements Serializable {
|
|||
* The zero-length ldt array.
|
||||
*/
|
||||
private static final LocalDateTime[] EMPTY_LDT_ARRAY = new LocalDateTime[0];
|
||||
/**
|
||||
* The number of days in a 400 year cycle.
|
||||
*/
|
||||
private static final int DAYS_PER_CYCLE = 146097;
|
||||
/**
|
||||
* The number of days from year zero to year 1970.
|
||||
* There are five 400 year cycles from year zero to 2000.
|
||||
* There are 7 leap years from 1970 to 2000.
|
||||
*/
|
||||
private static final long DAYS_0000_TO_1970 = (DAYS_PER_CYCLE * 5L) - (30L * 365L + 7L);
|
||||
|
||||
/**
|
||||
* Obtains an instance of a ZoneRules.
|
||||
|
@ -921,10 +930,34 @@ public final class ZoneRules implements Serializable {
|
|||
}
|
||||
|
||||
private int findYear(long epochSecond, ZoneOffset offset) {
|
||||
// inline for performance
|
||||
long localSecond = epochSecond + offset.getTotalSeconds();
|
||||
long localEpochDay = Math.floorDiv(localSecond, 86400);
|
||||
return LocalDate.ofEpochDay(localEpochDay).getYear();
|
||||
long zeroDay = Math.floorDiv(localSecond, 86400) + DAYS_0000_TO_1970;
|
||||
|
||||
// find the march-based year
|
||||
zeroDay -= 60; // adjust to 0000-03-01 so leap day is at end of four year cycle
|
||||
long adjust = 0;
|
||||
if (zeroDay < 0) {
|
||||
// adjust negative years to positive for calculation
|
||||
long adjustCycles = (zeroDay + 1) / DAYS_PER_CYCLE - 1;
|
||||
adjust = adjustCycles * 400;
|
||||
zeroDay += -adjustCycles * DAYS_PER_CYCLE;
|
||||
}
|
||||
long yearEst = (400 * zeroDay + 591) / DAYS_PER_CYCLE;
|
||||
long doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
|
||||
if (doyEst < 0) {
|
||||
// fix estimate
|
||||
yearEst--;
|
||||
doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
|
||||
}
|
||||
yearEst += adjust; // reset any negative year
|
||||
int marchDoy0 = (int) doyEst;
|
||||
|
||||
// convert march-based values back to january-based
|
||||
int marchMonth0 = (marchDoy0 * 5 + 2) / 153;
|
||||
yearEst += marchMonth0 / 10;
|
||||
|
||||
// Cap to the max value
|
||||
return (int)Math.min(yearEst, Year.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue