Java 减去1ms会导致意外行为

Java 减去1ms会导致意外行为,java,date,datetime,Java,Date,Datetime,怎么了?我假设如果我从1980年1月1日的0:0:0减去1ms,那么我得到了1979年。但我必须减去500毫秒。请给我一个提示 val cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")) cal.set(1980, 0, 1, 0, 0, 0) val date = new Date date.setTime(cal.getTimeInMillis()) // <- 1980 Jan 01 0:0:0 date.setTime(c

怎么了?我假设如果我从1980年1月1日的0:0:0减去1ms,那么我得到了1979年。但我必须减去500毫秒。请给我一个提示

val cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
cal.set(1980, 0, 1, 0, 0, 0)
val date = new Date
date.setTime(cal.getTimeInMillis()) // <- 1980 Jan 01 0:0:0
date.setTime(cal.getTimeInMillis() - 1) // <- 1980 Jan 01 0:0:0 too !!!
使用
Calendar.set(年、月、日、小时、日、分钟、秒)
未设置毫秒。因此,日历实现将毫秒设置为“未知”,这实际上被视为给定秒内的中点


减去500毫秒意味着你只需跨过中点。如果增加500毫秒,同样的情况也会发生,这将使你刚好超过第二秒。实际上,减去500毫秒有效,你必须加620毫秒才能看到下一秒。

只是猜测,但可能内部日历会将秒数取整?尝试在第一次
setTime()调用后打印
date
内容。可能年、月、日、小时、分钟和秒是您设置的值,但不是毫秒。这有点令人困惑。我不想使用尤达时间或其他第三方图书馆。我需要将年、月、日转换为毫秒,然后得到一天中的最后一毫秒。我想找到正确的解决办法。不幸的是,javadoc对这种情况保持沉默。即使正确的秒值也不足以满足我的情况:-(我认为这是Jon Skeet的一个问题:-)减去500毫秒不一定会得到1979年的最后一毫秒。@Ezhik,用
calendar.set(calendar.millis秒,0)明确地设置毫秒。当你从中减去一毫秒,你直接得到1979年的最后一毫秒。为什么要加620呢?
val cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
cal.setTimeInMillis(0)
cal.set(1980, 0, 1, 0, 0, 0)