Details
-
Type:
Bug
-
Status: Closed
-
Priority:
P4
-
Resolution: Not an Issue
-
Affects Version/s: 11.0.10
-
Fix Version/s: None
-
Component/s: core-libs
-
Labels:
-
Subcomponent:
-
CPU:generic
-
OS:generic
Description
ADDITIONAL SYSTEM INFORMATION :
OSX 10.15, Windows 10, CentOs 7/8
Java 8 and 11 tested
A DESCRIPTION OF THE PROBLEM :
When getting the difference between two zoned dates (UTC) if now is in February of a leap year and the other date is beyond February. The between returns an incorrect value. One less than expected
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
ZonedDateTime systemCurrent = ZonedDateTime.now(ZoneId.of("UTC"));
ZonedDateTime constructedNow = ZonedDateTime
.of(systemCurrent.getYear(), systemCurrent.getMonthValue(), systemCurrent
.getDayOfMonth(), systemCurrent.getHour(), systemCurrent.getMinute(), systemCurrent
.getSecond(), 0, ZoneId.of("UTC"));
ZonedDateTime plus25days = constructedNow.plus(25, ChronoUnit.DAYS);
System.out.println("Constructed Now: " + constructedNow + " Plus 25: " + plus25days);
System.out.println("Days between: " + ChronoUnit.DAYS.between(constructedNow, plus25days));
System.out.println(("hours between: " + ChronoUnit.HOURS.between(constructedNow, plus25days)));
System.out.println("System Current: " + systemCurrent + "\nDays Between " + ChronoUnit.DAYS
.between(systemCurrent, plus25days));
System.out.println(("hours between: " + ChronoUnit.HOURS.between(systemCurrent, plus25days)));
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Days between should be 25 and hours between should be 600
ACTUAL -
onstructed Now: 2021-02-23T19:42:49Z[UTC] Plus 25: 2021-03-20T19:42:49Z[UTC]
Days between: 25
hours between: 600
System Current: 2021-02-23T19:42:49.576340Z[UTC]
Days Between 24 <-- off by 1 (day)
hours between: 599 <-- off by 1 (hour)
---------- BEGIN SOURCE ----------
import java.time.*;
import java.time.temporal.ChronoUnit;
class Scratch {
public static void main(String[] args) {
ZonedDateTime systemCurrent = ZonedDateTime.now(ZoneId.of("UTC"));
ZonedDateTime constructedNow = ZonedDateTime
.of(systemCurrent.getYear(), systemCurrent.getMonthValue(), systemCurrent
.getDayOfMonth(), systemCurrent.getHour(), systemCurrent.getMinute(), systemCurrent
.getSecond(), 0, ZoneId.of("UTC"));
ZonedDateTime plus25days = constructedNow.plus(25, ChronoUnit.DAYS);
System.out.println("Constructed Now: " + constructedNow + " Plus 25: " + plus25days);
System.out.println("Days between: " + ChronoUnit.DAYS.between(constructedNow, plus25days));
System.out.println(("hours between: " + ChronoUnit.HOURS.between(constructedNow, plus25days)));
System.out.println("System Current: " + systemCurrent + "\nDays Between " + ChronoUnit.DAYS
.between(systemCurrent, plus25days));
System.out.println(("hours between: " + ChronoUnit.HOURS.between(systemCurrent, plus25days)));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Strangely if you set the nanoOfSecond of the constructedNow to the value of systemCurrent.getNano()
then ChronoUnit.HOURS.between(systemCurrent, plus25days) returns the correct value.
**** calling a the getter on ZonedDateTime in the context of a ZonedDateTime constructor fixes the issue ****
OSX 10.15, Windows 10, CentOs 7/8
Java 8 and 11 tested
A DESCRIPTION OF THE PROBLEM :
When getting the difference between two zoned dates (UTC) if now is in February of a leap year and the other date is beyond February. The between returns an incorrect value. One less than expected
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
ZonedDateTime systemCurrent = ZonedDateTime.now(ZoneId.of("UTC"));
ZonedDateTime constructedNow = ZonedDateTime
.of(systemCurrent.getYear(), systemCurrent.getMonthValue(), systemCurrent
.getDayOfMonth(), systemCurrent.getHour(), systemCurrent.getMinute(), systemCurrent
.getSecond(), 0, ZoneId.of("UTC"));
ZonedDateTime plus25days = constructedNow.plus(25, ChronoUnit.DAYS);
System.out.println("Constructed Now: " + constructedNow + " Plus 25: " + plus25days);
System.out.println("Days between: " + ChronoUnit.DAYS.between(constructedNow, plus25days));
System.out.println(("hours between: " + ChronoUnit.HOURS.between(constructedNow, plus25days)));
System.out.println("System Current: " + systemCurrent + "\nDays Between " + ChronoUnit.DAYS
.between(systemCurrent, plus25days));
System.out.println(("hours between: " + ChronoUnit.HOURS.between(systemCurrent, plus25days)));
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Days between should be 25 and hours between should be 600
ACTUAL -
onstructed Now: 2021-02-23T19:42:49Z[UTC] Plus 25: 2021-03-20T19:42:49Z[UTC]
Days between: 25
hours between: 600
System Current: 2021-02-23T19:42:49.576340Z[UTC]
Days Between 24 <-- off by 1 (day)
hours between: 599 <-- off by 1 (hour)
---------- BEGIN SOURCE ----------
import java.time.*;
import java.time.temporal.ChronoUnit;
class Scratch {
public static void main(String[] args) {
ZonedDateTime systemCurrent = ZonedDateTime.now(ZoneId.of("UTC"));
ZonedDateTime constructedNow = ZonedDateTime
.of(systemCurrent.getYear(), systemCurrent.getMonthValue(), systemCurrent
.getDayOfMonth(), systemCurrent.getHour(), systemCurrent.getMinute(), systemCurrent
.getSecond(), 0, ZoneId.of("UTC"));
ZonedDateTime plus25days = constructedNow.plus(25, ChronoUnit.DAYS);
System.out.println("Constructed Now: " + constructedNow + " Plus 25: " + plus25days);
System.out.println("Days between: " + ChronoUnit.DAYS.between(constructedNow, plus25days));
System.out.println(("hours between: " + ChronoUnit.HOURS.between(constructedNow, plus25days)));
System.out.println("System Current: " + systemCurrent + "\nDays Between " + ChronoUnit.DAYS
.between(systemCurrent, plus25days));
System.out.println(("hours between: " + ChronoUnit.HOURS.between(systemCurrent, plus25days)));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Strangely if you set the nanoOfSecond of the constructedNow to the value of systemCurrent.getNano()
then ChronoUnit.HOURS.between(systemCurrent, plus25days) returns the correct value.
**** calling a the getter on ZonedDateTime in the context of a ZonedDateTime constructor fixes the issue ****