【发布时间】:2016-09-29 18:43:25
【问题描述】:
我正在为 java.util.Date 和 java.time.LocalDateTime 之间的 java-8 转换编写一些测试代码,发现在 java.util.Date 之间似乎发生了异常strong>从正常时间过渡到夏季时间后的一小时,此时年份为 2038 年或更高。
我只是想知道这是否是 jdk8 中的错误,还是我做错了什么?
注意:我使用的是 Windows-7,64 位 jdk,所以应该不受 2038-unix 错误的影响,这会产生更糟糕的影响.
这是我的演示代码:
package conversiontest;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
public class ConversionTest {
public static void main(String[] args) {
new ConversionTest().testDateConversion();
}
// Method under test:
public java.util.Date toJavaUtilDate(LocalDateTime localDateTime) {
return java.util.Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
// Test-code:
public void testDateConversion() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
LocalDate localDate = LocalDate.of(2016, 1, 1);
LocalTime localTime = LocalTime.of(3, 22, 22); // 03:22:22
while (!localDate.toString().startsWith("2045-")) {
LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
java.util.Date date = toJavaUtilDate(localDateTime);
String sLocalDateTime = localDateTime.toString().replace("T", " ");
String sJavaUtilDate = sdf.format(date);
if (!sLocalDateTime.equals(sJavaUtilDate)) {
System.out.println(String.format("FAILURE: '%s' != '%s'", sLocalDateTime, sJavaUtilDate));
}
localDate = localDate.plusDays(1);
}
}
}
输出:
FAILURE: '2038-03-28 03:22:22' != '2038-03-28 02:22:22'
FAILURE: '2039-03-27 03:22:22' != '2039-03-27 02:22:22'
FAILURE: '2040-03-25 03:22:22' != '2040-03-25 02:22:22'
FAILURE: '2041-03-31 03:22:22' != '2041-03-31 02:22:22'
FAILURE: '2042-03-30 03:22:22' != '2042-03-30 02:22:22'
FAILURE: '2043-03-29 03:22:22' != '2043-03-29 02:22:22'
FAILURE: '2044-03-27 03:22:22' != '2044-03-27 02:22:22'
从输出中可以看出,LocalDateTime(2038-03-28 03:22:22) 转换为 java.util.Date(2038-03-28 02:22:22) 等。但是当年份低于 2038 年时不。
有人对此有意见吗?
编辑:
我的 ZoneId.systemDefault() 给出:“欧洲/柏林”
C:\>java -version
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b15, mixed mode)
C:\>javac -version
javac 1.8.0_91
【问题讨论】:
-
提示:你用谷歌搜索了
java.util.date 2038。这会产生例如stackoverflow.com/questions/15014589/java-util-date-bug 和阅读的乐趣stackoverflow.com/questions/4313707/… -
Java 类是否使用
int或long来表示特定值(例如,自特定时间点以来的(毫秒)秒),与操作系统或实际CPU 完全无关.在 8 位 CPU 上进行long计算可能需要更多的 CPU 周期,但这不会影响有效的 JVM/JRE 必须产生以满足规范的结果。 -
你的系统时区和java版本是多少(有subversion)?至少我们需要知道这些细节的重现性。
-
我可以重现您的问题。
java.time-part 没问题,但GregorianCalendar中似乎存在 2038 年或更晚的错误。旧的基于Calendar的API 似乎计算出在UTC 偏移前只有一个而不是两个小时。如果您使用其toString()-方法(生成CET 而不是CEST)打印Date-变量,或者将其转换为GregorianCalendar(SimpleDateFormat内部执行的操作),则可以看到它。我的建议:使用java.time.format.DateTimeFormatter而不是SimpleDateFormat。 -
@Meno Hochschild:一小时内出现不匹配。在 2028 年 3 月 28 日,
java.util.Date在3:00CET/4:00CEST更改为夏令时,而java.time已经在2:00CET/3:00CEST更改。
标签: java java-8 java-time java.util.date