【问题标题】:Java Date from millis - long vs int来自millis的Java日期 - long vs int
【发布时间】:2013-12-10 13:18:00
【问题描述】:

对于以下代码:

import java.text.SimpleDateFormat;
import java.util.Date;

public class TestMain {

    public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        System.out.println(sdf.format(new Date(1386633600000L)));
        System.out.println(sdf.format(new Date(1386633600 * 1000)));
    }

}

我得到以下输出:

10-12-2013
24-12-1969

它们为什么不同?

【问题讨论】:

    标签: java time


    【解决方案1】:

    因为第二个值使用的是integer 而不是long 并且已经溢出。

    如果您在任一常量的末尾添加 L,它将切换为使用 long 值,并且差异将消失。

    这是因为在第二个示例中,两个值都是整数。整数 * 整数 = 整数。只有当一个或多个被相乘的值(或任何其他数学运算)为 long 时,它才会被提升为 long。没有“魔法”可以检测溢出并为您进行促销。

    即使您执行了long x = int*int,它仍会以 32 位进行乘法运算,然后将结果转换为 64 位以进行赋值。

    您也可以在更微妙的地方看到这一点 - 例如:

    long l;
    int x,y;
    
    long result = l+x*y;
    

    即使 result 和 l 都是 long,x*y 仍然是整数,因为乘法是先完成的。即使 x 和 y 分别适合一个 32 位整数,如果两者的乘积不适合,您就会遇到溢出情况。解决方法是确保在您遇到溢出风险的最早点将其转换为 long - 例如:

    long result = l+((long)x)*y;
    

    【讨论】:

    • @Vlad:你看,第一个参数中的L 很重要。试试System.out.println(1386633600 * 1000) 看看你会得到什么......
    • @Vlad Java 编译器不进行类型推断,类型检查的方式与您想象的相反:它首先确定表达式的类型,然后为其选择适当的方法。在这种情况下,它有一个int,因此Date(long) 构造函数是最合适的。 (如果方法根本没有重载也没关系。)
    猜你喜欢
    • 2014-11-24
    • 1970-01-01
    • 2016-07-29
    • 1970-01-01
    • 2011-08-17
    • 2017-02-08
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多