我尝试使用相同的字符串System.out
System.out.println(" DATE 29 " + new Date(1330462800000l) + " Date 01 "
+ new Date(1330549200000l));
但是当我在Build(在控制台模式下运行)和从eclipse运行应用程序时检查它时,我得到了不同的结果。
从eclipse输出(看起来是正确的结果):
DATE 29 Wed Feb 29 00:00:00 EET 2012 Date 01 Thu Mar 01 00:00:00 EET 2012
构建输出(控制台模式)
DATE 29 Tue Feb 28 23:00:00 EET 2012 Date 01 Wed Feb 29 23:00:00 EET 2012
对不起愚蠢的问题,但您对可能的原因有任何想法吗?
PS:我使用maven + tycho制作构建,打包类型的eclipse-repository。(如果它真的很重要)
编辑: 在Eclipse中,我查看了timeZone值:
Calendar calendar=Calendar.getInstance();
System.out.println("!!!time zone before: " + calendar.getTimeZone());
!!!之前的时区: sun.util.calendar.ZoneInfo [ID = “欧洲/明斯克”,偏移= 7200000,dstSavings = 3600000,useDaylight =真,过渡= 121,lastRule = java.util.SimpleTimeZone中[ID =欧洲/明斯克,偏移= 7200000, dstSavings = 3600000,useDaylight =真,startYear = 0,STARTMODE = 2,startMonth = 2,朝九特派= -1,startDayOfWeek = 1,开始时间= 7200000,startTimeMode = 1,endMode = 2,endMonth = 9,endday指定= -1,一个endDayOfWeek = 1,结束时间= 7200000,endTimeMode = 1]]
然后我用硬编码的zoneId设置时区并进行构建
calendar.setTimeZone(TimeZone.getTimeZone("Europe/Minsk"));
没有任何结果
编辑:我在构建和eclipse中使用不同版本和jres的体系结构。这可能是原因吗? 编辑:System.out.println("!!!!!! system.timezone " + System.getProperty("user.timezone"));
System.setProperty("user.timezone", "Europe/Minsk");
System.out.println("!!!!!! system.timezone " + System.getProperty("user.timezone"));
!!!!!! system.timezone欧洲/明斯克
!!!!!! system.timezone欧洲/明斯克!!!区域之后的日历时间: sun.util.calendar.ZoneInfo [ID = “欧洲/明斯克”,偏移= 7200000,dstSavings = 3600000,useDaylight =真,过渡= 121,lastRule = java.util.SimpleTimeZone中[ID =欧洲/明斯克,偏移= 7200000, dstSavings = 3600000,useDaylight =真,startYear = 0,STARTMODE = 2,startMonth = 2,朝九特派= -1,startDayOfWeek = 1,开始时间= 7200000,startTimeMode = 1,endMode = 2,endMonth = 9,endday指定= -1,一个endDayOfWeek = 1,结束时间= 7200000,endTimeMode = 1]]
更正时区。但是日期仍然是错误的
答案 0 :(得分:1)
添加测试:
System.out.println(Calendar.getInstance().getTimeZone());
或
System.getProperty("user.timezone");
Java时区可以由系统属性user.timezone设置,有关详细信息,请参阅Java system properties。
时间使用joda time。您可以为所有joda对象重新定义时区:
DateTimeZone.setDefault(DateTimeZone.UTC);
答案 1 :(得分:0)
Instant.ofEpochMilli( 1_330_462_800_000L ) // Convert count-of-milliseconds-since-epoch to an `Instant`, a moment on the timeline in UTC.
.atZone( ZoneId.of( "Europe/Minsk" ) ) // Adjust into another time zone. Same moment, different wall-clock time.
你正在使用现在遗留下来的麻烦的旧日期时间类,取而代之的是java.time类。在许多缺陷中,Date::toString
方法在生成字符串时动态应用JVM的当前默认时区。 Date
表示UTC中的一个时刻,但这个善意的反特征会带来混乱。 JVM的当前默认时区可以随时更改,甚至在运行时期间,因此您可能会看到各种结果。
使用java.time.Instant
代替java.util.Date
。
Instant
Instant
类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。
Instant instant = Instant.ofEpochMilli( 1_330_462_800_000L ) ;
学会思考主要使用UTC 。将UTC视为 One True Time™。所有其他时区仅仅是该主题的变体。在作为程序员的工作中,忘记您的个人当地时间,并停止在区域之间来回转换,因为这可能会让您感到沮丧。在编程和日志记录中关注UTC。
ZonedDateTime
要通过其他时区的镜头查看同一时刻,请应用ZoneId
以获取ZonedDateTime
个对象。我们仍然有相同的时刻,时间轴上的相同点,但是有另一个挂钟时间。
ZoneId z = ZoneId.of( "Europe/Minsk" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
请参阅此code run live at IdeOne.com。
instant.toString():2012-02-28T21:00:00Z
zdt.toString():2012-02-29T00:00 + 03:00 [欧洲/明斯克]
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。