我只是向Date的类构造函数提供2160000000(即1000 * 60 * 60 * 24 * 25 - 仅25天)的值。我希望看到这里将是1970-01-26 00:00:00,但我收到的是1970-01-26 03:00:00(另外三个小时)!我没有发现这个构造函数也依赖于JVM语言环境设置的任何要点,我找到的只是关于闰秒的信息。但闰秒不是同一个月的三个小时。但无论如何,我已经改变了一个测试方法的默认语言环境(美国的一个。我位于欧洲)只是为了实验,但没有任何改变。
我刚收到这个(我之前已经解释过,你知道的)
Date date = new Date(1000* 60 * 60 * 24 * 25);
(这只是为了举例)。我只是使用调试器看到实际值,这就是全部:
答案 0 :(得分:4)
您获得了预期的Date
,Date
为1970-01-26 00:00:00 UTC 。此时间点相当于UTC偏移+03:00的1970-01-26 03:00:00。
在调试器中,您正在查看Date
对象的私有字段。客户没有记录这些(这就是重点),所以不要指望任何特定的值。
我相信你会发现Instant.ofEpochMilli(1000L * 60 * 60 * 24 * 25)
不那么混乱。或者更好,Instant.EPOCH.plus(Duration.ofDays(25))
。 java.time,现代Java日期和时间API,可以更好地使用。如果您确实需要Date
用于您不想立即更改的旧API,我建议先使用Instant
,然后使用Date.from(yourInstant)
,以便尽量减少使用(并且依赖于过时且令人困惑的Date
类。
最后,更改区域设置没有任何区别。虽然时区和UTC偏移密切相关(在某种程度上,有些人认为它是相同的:-) locale并没有真正与它们有任何关系。相反,该区域设置处理一组用户的语言和文化规范 - 它甚至不需要与地理位置相关联。
答案 1 :(得分:2)
您认为您所看到的小时差异与您所在国家/地区的时区相同(GMT + 3)是巧合吗?我想不是。
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = dateFormat.parse("/*TimeToParse*/");
这肯定会有所帮助。
编辑:如果您在调试屏幕截图中检查zoneOffset和ZoneInfo值,您会更好地理解。
答案 2 :(得分:2)
Instant.ofEpochMilli( 2_160_000_000L )
The Answer by Acar可能是正确的:您对Date::toString
的不幸设计感到困惑,以便在生成字符串时动态应用JVM的当前默认时区。 许多的原因之一是永远不会使用麻烦的Date
类,现在由 java.time 类取代。
要使用分辨率为纳秒的UTC时间轴上的时刻表示,请使用Instant
。
Instant instant = Instant.ofEpochMilli( 2_160_000_000L ) ;
如果您的真实意图是将25天整天表示为未附加到时间线的时间段,请使用Period
。
LocalDate today = LocalDate.now( ZoneId.of( “Africa/Tunis” ) ) ;
Period p = Period.ofDays( 25 ) ;
LocalDate later = today.plus( p ) ;