我发现这个有趣的行为,同时使用日期和日历类来处理指数分布以模拟商店的到达时间(学术工作)。代码很简单,下面显示。好吧,假设“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;
答案 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类。
如果您希望使用没有任何时区或从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 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。