java.util.Date显示具有相同输入参数的不同值

时间:2012-03-05 23:44:35

标签: date maven eclipse-plugin eclipse-rcp tycho

我尝试使用相同的字符串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]]

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

2 个答案:

答案 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)

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中时间轴上的一个时刻,分辨率为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.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore