日历日期Java,在2014-02-16跳过一小时

时间:2013-12-04 22:16:50

标签: java date calendar

我发现这个有趣的行为,同时使用日期和日历类来处理指数分布以模拟商店的到达时间(学术工作)。代码很简单,下面显示。好吧,假设“this.currentDate”是“2月15日08:00:00 BRST 2014”。 如果我向前移动24小时(参数iSeconds = 86.400),应该返回什么?预期的字符串将是“2014-02-16 08:00:00”,但是时间缩短了1小时,结果是“2014-02-16 07:00:00”,我想知道是否有人可以解释为什么我的一小时被“偷走”。没什么大不了的,但是因为我的下一个到达时间取决于前一个时间,所以我的时间基线会使所有这些时间都变得一团糟。

我认为这可能是一些TZ问题,但是,我刚刚在2月中旬24小时内搬了。

public  String shiftTimeStamp( int iSeconds)
{
 Calendar cal = Calendar.getInstance();     
     cal.setTime(this.currentDate);
     cal.add(Calendar.SECOND, iSeconds);
     this.currentDate = cal.getTime();
     String sTS = new SimpleDateFormat(SCSimLabels.DATE_TS_FORMAT).format(this.currentDate);
return sTS;
}

注意:夏令时问题:) BRT< - > BRST tz。

我的解决方法:我只想要一个灯塔来指导间隔到达时间引起的时间跳跃,我对这样的日历特性不感兴趣,所以当我需要移动到第二天的第一个工作小时时我只是强迫转换1天后的时间为08:00:00。它就像一个魅力:)

Calendar cal = Calendar.getInstance();
cal.setTime(this.currentDate);
cal.add(Calendar.DATE, 1);

String sDate = (new SimpleDateFormat("yyyy-MM-dd 08:00:00")).format(cal.getTime());
Date newDate =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(sDate);   
this.currentDate = newDate;

2 个答案:

答案 0 :(得分:0)

将格式调用更改为:

return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z").format(this.currentDate);

查看格式调用使用的时区。我打赌.add()的调用正在修改Calendar对象的时区,因为它超过了标准的时间/日光时间边界。

如果是这种情况,您可以尝试添加Calendar.DAY,1或简单地添加Calendar obj的.setTimeZone(...)。在.add调用之后回到原来的时区。

答案 1 :(得分:0)

避免遗留日期时间类

你正在使用现在遗留下来的麻烦的旧日期时间类,取而代之的是java.time类。

使用java.time

如果您希望使用没有任何时区或从UTC偏移的通用24小时工作日,请使用LocalDateTime课程。如果您始终要在上午8点开始,请指定LocalTime

LocalDate ld = LocalDate.of( 2014 , Month.FEBRUARY , 15 ) ;
LocalTime lt = LocalTime.of( 8 , 0 ) ; // Specify hour in 24-hour clock, 0-23.
LocalDateTime ldt = LocalDateTime.of( ld , lt );

将您的24小时范围表示为Duration

Duration d = Duration.ofHours( 24 );
LocalDateTime ldtLater = ldt.plus( d );

如果您希望通过区域特定wall-clock time的镜头在时间轴上处理特定时刻,请指定ZoneId以获得ZonedDateTime

ZoneId z = ZoneId.of( "America/Sao_Paulo" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
ZonedDateTime zdtLater = zdt.plus( d );

请注意,向ZonedDateTime添加24小时与添加一天相同。正如您所了解的那样,夏令时(DST)等异常意味着一天可能是23,24或25小时,甚至是其他长度。因此,如果您想添加一天并让java.time应用其逻辑来达到适当的时间,同时考虑到DST等异常情况,请添加而不是小时

ZonedDateTime zdtLater = zdt.plusDays( 1 );  

或者添加一整天的Period而不是{24}的Duration

Period p = Period.ofDays( 1 );
ZonedDateTime zdtLater = zdt.plus( p );

关于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