Java 为什么铸造时间不长

Java 为什么铸造时间不长,java,casting,Java,Casting,从这样的代码中,我今天遇到了奇怪的java转换问题 新日期(System.currentTimeMillis()-1000*60*60*24*31) 这应该给出31天前的日期,但返回16天后的日期。这显然是因为 1000*60*60*24*31 将计算为整数并溢出 新日期(System.currentTimeMillis()-1000L*60*60*24*31) 工作如期进行 我认为java应该将整个表达式强制转换为Long,因为第一个操作数是LongSystem.currentTimeMill

从这样的代码中,我今天遇到了奇怪的java转换问题

新日期(System.currentTimeMillis()-1000*60*60*24*31)

这应该给出31天前的日期,但返回16天后的日期。这显然是因为
1000*60*60*24*31
将计算为整数并溢出

新日期(System.currentTimeMillis()-1000L*60*60*24*31)
工作如期进行


我认为java应该将整个表达式强制转换为Long,因为第一个操作数是Long
System.currentTimeMillis()
,但由于我不理解的原因,它不会在这里发生。硬编码常量为int是否有例外?

已经说过了,但我认为应该给出一个答案。将该类与

刚刚(4月11日)在我的电脑上的输出:

2018-03-11T19:57:47.517032+03:00[印度/科摩罗]

我减去一个月,这意味着28天、29天、30天或31天,这取决于我所在的月份和上个月的天数。如果您无条件地想要31天,您当然可以:

    ZonedDateTime thirtyoneDaysAgo 
            = ZonedDateTime.now(ZoneId.of("Indian/Comoro")).minusDays(31);
由于3月份有31天,因此在本例中的结果是相同的。不会总是这样的

我正在使用和推荐现代Java日期和时间API。与过时的
Date
类相比,它使用起来更方便,更不容易出错

你的代码出了什么问题?
是关于<代码>1000*60*60*24*31由
int
值组成。是的,整数文本具有类型
int
,除非它们具有
L
后缀。因为乘法是在减法之前执行的(正如您所预期的),所以结果也是
int
,但它会溢出,因为结果将大于
int
可以容纳的最大数。不幸的是,Java没有通知您溢出,它只是给了您一个错误的结果,这里是
-1616567296
,大约-19天。减去这些,你得到的日期和时间大约是未来19天

作为一种习惯,使用括号、
L
后缀,以便于阅读

( System.currentTimeMillis() - ( 1_000L * 60L * 60L * 24L * 31L ) )
如果您想知道溢出,可以使用
Math.multiplyExact​()
用于乘法(从Java8开始)。幸运的是,现代图书馆类完全避免了成倍增长。并发出溢流信号

链接
  • 解释如何使用
    java.time

为什么不使用Java提供的
LocalDateTime
?这样的话,它将是:
LocalDateTime.now().minusDays(31)哦,回答你的问题:你所有的数字都是整数,
*
运算符优先于
-
运算符,因此转换只在溢出发生后发生。
1000*60*60*24*31
是一个整数。然后你从一个long中减去它,得到另一个long。但是整数在减法之前已经溢出了。现在我知道了,小学数学,它就像
System.currentTimeMillis()-(1000*60*60*24*31)
对于Java,它意味着使首字母缩略词可以发音:-)实际上,它意味着“订单”;i、 e.权力、根源等
( System.currentTimeMillis() - ( 1_000L * 60L * 60L * 24L * 31L ) )