-
Bug
-
Resolution: Won't Fix
-
P4
-
None
-
8u20
-
x86_64
-
windows_7
FULL PRODUCT VERSION :
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Windows 7 64-bit
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
Using java.util.Calendar and java.time.Instant to compute the milliseconds since the epoch for a given java.time.LocalDate yields different values for dates before 1893-04-01.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the attached test-program and see its Output:
javac at/sphinx/bug/MillisecondTest.java
java at.sphinx.bug.MillisecondTest
pause
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No output.
ACTUAL -
Date = 1916-10-01, Calendar = -1680483600000, Instant = -1680487200000, delta = -3600000 = PT-1H
Date = 1916-09-30, Calendar = -1680573600000, Instant = -1680573600000, delta = 0 = PT0S
Date = 1893-04-01, Calendar = -2422054800000, Instant = -2422054408000, delta = 392000 = PT6M32S
Date = 1582-10-14, Calendar = -12218518800000, Instant = -12219382408000, delta = -863608000 = PT-239H-53M-28S
Date = 1500-02-28, Calendar = -14825984400000, Instant = -14826761608000, delta = -777208000 = PT-215H-53M-28S
Date = 1400-02-28, Calendar = -17981744400000, Instant = -17982435208000, delta = -690808000 = PT-191H-53M-28S
Date = 1300-02-28, Calendar = -21137504400000, Instant = -21138108808000, delta = -604408000 = PT-167H-53M-28S
Date = 1100-02-28, Calendar = -27449024400000, Instant = -27449542408000, delta = -518008000 = PT-143H-53M-28S
Date = 1000-02-28, Calendar = -30604784400000, Instant = -30605216008000, delta = -431608000 = PT-119H-53M-28S
Date = 0900-02-28, Calendar = -33760544400000, Instant = -33760889608000, delta = -345208000 = PT-95H-53M-28S
Date = 0700-02-28, Calendar = -40072064400000, Instant = -40072323208000, delta = -258808000 = PT-71H-53M-28S
Date = 0600-02-28, Calendar = -43227824400000, Instant = -43227996808000, delta = -172408000 = PT-47H-53M-28S
Date = 0500-02-28, Calendar = -46383584400000, Instant = -46383670408000, delta = -86008000 = PT-23H-53M-28S
Date = 0300-02-28, Calendar = -52695104400000, Instant = -52695104008000, delta = 392000 = PT6M32S
Date = 0200-02-28, Calendar = -55850864400000, Instant = -55850777608000, delta = 86792000 = PT24H6M32S
Date = 0100-02-28, Calendar = -59006624400000, Instant = -59006451208000, delta = 173192000 = PT48H6M32S
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package at.sphinx.bug;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
@SuppressWarnings("nls")
public class MillisecondTest
{
public static void main(String... arguments)
{
new MillisecondTest().performTest();
}
public void performTest()
{
LocalDate date = LocalDate.of(9999, 12, 31);
long oldDelta = 0;
while (date.getYear() >= 1)
{
long millis1 = computeMillisUsingCalendar(date);
long millis2 = computeMillisUsingInstant(date);
long newDelta = millis2 - millis1;
if (newDelta != oldDelta)
{
System.out.printf("Date = %1$8s, Calendar = %2$15d, Instant = %3$15d, delta = %4$10d = %5$s\n",
date, millis1, millis2, newDelta, Duration.ofMillis(newDelta));
}
oldDelta = newDelta;
date = date.minusDays(1);
}
}
private long computeMillisUsingCalendar(LocalDate date)
{
Calendar vCalendar = Calendar.getInstance();
vCalendar.clear();
vCalendar.set(date.getYear(), date.getMonthValue() - 1, date.getDayOfMonth(), 0, 0, 0);
return vCalendar.getTimeInMillis();
}
private long computeMillisUsingInstant(LocalDate date)
{
LocalDateTime dt = date.atStartOfDay();
ZonedDateTime zdt = dt.atZone(ZoneId.systemDefault());
Instant instant = zdt.toInstant();
return instant.toEpochMilli();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I used the conversion from a LocalDate to an Instant to get its milliseconds to instantiate a Java.utilDate that was sent to the JDBC Driver.
I now use java.sql.Date.valueOf(LocalDate) to directly get a Java.sql.Date that is sent to the JDBC Driver.
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Windows 7 64-bit
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
Using java.util.Calendar and java.time.Instant to compute the milliseconds since the epoch for a given java.time.LocalDate yields different values for dates before 1893-04-01.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the attached test-program and see its Output:
javac at/sphinx/bug/MillisecondTest.java
java at.sphinx.bug.MillisecondTest
pause
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No output.
ACTUAL -
Date = 1916-10-01, Calendar = -1680483600000, Instant = -1680487200000, delta = -3600000 = PT-1H
Date = 1916-09-30, Calendar = -1680573600000, Instant = -1680573600000, delta = 0 = PT0S
Date = 1893-04-01, Calendar = -2422054800000, Instant = -2422054408000, delta = 392000 = PT6M32S
Date = 1582-10-14, Calendar = -12218518800000, Instant = -12219382408000, delta = -863608000 = PT-239H-53M-28S
Date = 1500-02-28, Calendar = -14825984400000, Instant = -14826761608000, delta = -777208000 = PT-215H-53M-28S
Date = 1400-02-28, Calendar = -17981744400000, Instant = -17982435208000, delta = -690808000 = PT-191H-53M-28S
Date = 1300-02-28, Calendar = -21137504400000, Instant = -21138108808000, delta = -604408000 = PT-167H-53M-28S
Date = 1100-02-28, Calendar = -27449024400000, Instant = -27449542408000, delta = -518008000 = PT-143H-53M-28S
Date = 1000-02-28, Calendar = -30604784400000, Instant = -30605216008000, delta = -431608000 = PT-119H-53M-28S
Date = 0900-02-28, Calendar = -33760544400000, Instant = -33760889608000, delta = -345208000 = PT-95H-53M-28S
Date = 0700-02-28, Calendar = -40072064400000, Instant = -40072323208000, delta = -258808000 = PT-71H-53M-28S
Date = 0600-02-28, Calendar = -43227824400000, Instant = -43227996808000, delta = -172408000 = PT-47H-53M-28S
Date = 0500-02-28, Calendar = -46383584400000, Instant = -46383670408000, delta = -86008000 = PT-23H-53M-28S
Date = 0300-02-28, Calendar = -52695104400000, Instant = -52695104008000, delta = 392000 = PT6M32S
Date = 0200-02-28, Calendar = -55850864400000, Instant = -55850777608000, delta = 86792000 = PT24H6M32S
Date = 0100-02-28, Calendar = -59006624400000, Instant = -59006451208000, delta = 173192000 = PT48H6M32S
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package at.sphinx.bug;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
@SuppressWarnings("nls")
public class MillisecondTest
{
public static void main(String... arguments)
{
new MillisecondTest().performTest();
}
public void performTest()
{
LocalDate date = LocalDate.of(9999, 12, 31);
long oldDelta = 0;
while (date.getYear() >= 1)
{
long millis1 = computeMillisUsingCalendar(date);
long millis2 = computeMillisUsingInstant(date);
long newDelta = millis2 - millis1;
if (newDelta != oldDelta)
{
System.out.printf("Date = %1$8s, Calendar = %2$15d, Instant = %3$15d, delta = %4$10d = %5$s\n",
date, millis1, millis2, newDelta, Duration.ofMillis(newDelta));
}
oldDelta = newDelta;
date = date.minusDays(1);
}
}
private long computeMillisUsingCalendar(LocalDate date)
{
Calendar vCalendar = Calendar.getInstance();
vCalendar.clear();
vCalendar.set(date.getYear(), date.getMonthValue() - 1, date.getDayOfMonth(), 0, 0, 0);
return vCalendar.getTimeInMillis();
}
private long computeMillisUsingInstant(LocalDate date)
{
LocalDateTime dt = date.atStartOfDay();
ZonedDateTime zdt = dt.atZone(ZoneId.systemDefault());
Instant instant = zdt.toInstant();
return instant.toEpochMilli();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I used the conversion from a LocalDate to an Instant to get its milliseconds to instantiate a Java.utilDate that was sent to the JDBC Driver.
I now use java.sql.Date.valueOf(LocalDate) to directly get a Java.sql.Date that is sent to the JDBC Driver.
- relates to
-
JDK-6281408 (tz) TimeZone doesn't support Local Mean Time correctly
- Closed