Java日期之前的时间在生产中未按预期工作

时间:2012-08-01 14:09:54

标签: java

这是我的代码:

long treatmentTimeBeginDay;
if ( effectiveBegin.after(businessClosing) ) {
    LOGGER.debug("Compute treatment time for beginDay = 0: the effective begin {} is after business closing {}",
                            config.formatLogDate(effectiveBegin),config.formatLogDate(businessClosing));
    treatmentTimeBeginDay = 0;
} else {
    LOGGER.debug("Compute treatment time for beginDay between {} and {}",config.formatLogDate(effectiveBegin),config.formatLogDate(businessClosing));
    treatmentTimeBeginDay = businessClosing.getTime() - effectiveBegin.getTime();
}
Preconditions.checkState( treatmentTimeBeginDay >= 0 , "Internal bug! treatmentTimeBeginDay="+treatmentTimeBeginDay );

effectiveBegin和businessClosing不为null,也是由Guava前提条件检查的,你可以在日志中看到它......

在大多数情况下它运行良好,但在生产中我们有这些错误:

  

引起:java.lang.IllegalStateException:内部错误!   treatmentTimeBeginDay = -852

我没有给你剩下的堆栈/代码,因为它应该足够了...... 我的Guava checkState调用显式引发了异常。

我也有日志:

  

DEBUG [BusinessHoursUtils.java:257] llairie - 计算治疗时间   适用于2012年7月19日晚8点至晚上7点19分8点之间的开始日。

(我现在不能用毫克记录)


我想要了解的是。

如果我得到了我给你的日志,这意味着测试if ( effectiveBegin.after(businessClosing) )是假的,所以effectiveBegin应该在businessClosing之前或之前等。

在这种情况下,effectiveBegin时间戳应该低于businessClosing时间戳。

所以,当我businessClosing.getTime() - effectiveBegin.getTime();时,我希望得到一个正数。

所以请有人告诉我为什么我的异常消息中有-852毫秒?这怎么可能?


编辑:我怀疑是一个棘手的情况,其中after / before方法不会工作毫秒,而且似乎问题是因为我可以在本地重现它。

运行时的两个日期是:

businessClosing = {java.util.Date@503}"Thu Jul 19 20:00:00 CEST 2012"
fastTime = 1342720800000
cdate = null

effectiveBegin = {java.sql.Timestamp@498}"2012-07-19 20:00:00.999"
nanos = 999000000
fastTime = 1342720800000
cdate = {sun.util.calendar.Gregorian$Date@512}"2012-07-19T20:00:00.000+0200"

使用这些运行时对象effectiveBegin.after(businessClosing) = false 如果我在DB中设置effectiveBegin = 2012-07-19 20:00:01.000,之后1毫秒,那么test = true

在这两种情况下,我都希望effectiveBegin.after(businessClosing) = true

似乎有人怀疑,我的日期不同。

所以最后,问题是什么? 我们不应该能够以毫秒精度比较2日期实例吗? 即使它们是java.util.Date的子类?

1 个答案:

答案 0 :(得分:4)

这里的问题是你混合时间戳和日期。 Timestamp.after(Date)仅比较Date组件的毫秒数,它们在您的示例中均为1342720800000。 但是,Timestamp.getTime()还会考虑存储在时间戳中的纳秒(999000000ns = 999ms)并返回1342720800999。因此businessClosing.getTime() - effectiveBegin.getTime()将返回-999作为结果。

要解决此问题,您可以将if语句修改为if(effectiveBegin.compareTo(businessClosing) > 0),或者可以在if语句之前将businessClosingDate转换为Timestamp