java.util.Date使用相同的输入参数显示不同的值

我尝试System.out相同的字符串

System.out.println(" DATE 29 " + new Date(1330462800000l) + " Date 01 "
                + new Date(1330549200000l));

但是当我在Build(在控制台模式下运行)中检查它时以及在Eclipse中运行应用程序时,我得到了不同的结果。

来自eclipse的输出(看起来像是正确的结果):

日期29 Wed Feb 29 00:00:00 EET 2012日期01 Thu Mar 01 00:00:00 EET 2012

从构建输出(控制台模式)

日期29 2月28日23:00:00 EET 2012日期01 Wed 2月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 =“Europe / Minsk”,offset = 7200000,dstSavings = 3600000,useDaylight = true,transitions = 121,lastRule = java.util.SimpleTimeZone [id = Europe /明斯克,偏移= 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"));

没有任何结果

编辑:我使用jres的不同版本和体系结构在build和eclipse中。它可能是原因吗? 编辑:

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 Europe / Minsk !!!区域后的日历时间:sun.util.calendar.ZoneInfo [id =“Europe / Minsk”,offset = 7200000,dstSavings = 3600000,useDaylight = true,transitions = 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]]

正确的时区。 但日期仍然是错误的


添加到测试:

System.out.println(Calendar.getInstance().getTimeZone());

要么

System.getProperty("user.timezone");

Java时区可以通过系统属性user.timezone设置,详情请参阅Java系统属性。

时间使用乔达时间。 您可以为所有乔达物体重新定义时区:

DateTimeZone.setDefault(DateTimeZone.UTC);

TL;博士

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

使用java.time.Instant代替java.util.Date

Instant

Instant类表示UTC时间轴上的某个时刻,分辨率为纳秒(小数点后最多九位数字)。

Instant instant = Instant.ofEpochMilli( 1_330_462_800_000L ) ;

学习以UTC为主要思想和工作 。 将UTC视为一个真正的时间™。 所有其他时区仅仅是该主题的变体。 在作为程序员的工作中,忘记你的个人当地时间,并停止在区域之间来回转换,因为这可能会驱动你蝙蝠。 在您的编程和日志中关注UTC。

ZonedDateTime

要通过另一个时区的镜头查看同一时刻,请应用ZoneId以获取ZonedDateTime对象。 我们仍然有相同的时间点,时间轴上的同一点,但又有另一个挂钟时间。

ZoneId z = ZoneId.of( "Europe/Minsk" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

看到这个代码在IdeOne.com上运行。

instant.toString():2012-02-28T21:00:00Z

zdt.toString():2012-02-29T00:00 + 03:00 [欧洲/明斯克]


关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了诸如java.util.DateCalendarSimpleDateFormat等麻烦的旧式遗留日期时间类。

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle教程。 并搜索堆栈溢出了很多例子和解释。 规范是JSR 310。

何处获取java.time类?

  • Java SE 8Java SE 9和更高版本
  • 内置。
  • 带有捆绑实现的标准Java API的一部分。
  • Java 9增加了一些次要功能和修复。
  • Java SE 6Java SE 7
  • 大部分java.time功能都在ThreeTen-Backport中移植到Java 6和7。
  • Android的
  • 后续版本的java.time类的Android捆绑实现。
  • 对于早期的Android, ThreeTenABP项目采用ThreeTen-Backport(上文提到)。 请参阅如何使用ThreeTenABP ...。
  • ThreeTen-Extra项目将java.time扩展到其他类。 这个项目是未来可能增加java.time的一个试验场。 您可以在这里找到一些有用的课程,例如IntervalYearWeekYearQuarter等。

    链接地址: http://www.djcxy.com/p/389.html

    上一篇: java.util.Date shows different values with the same input parameters

    下一篇: Why does Date.parse give incorrect results?