Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Date from millis - long vs int

Tags:

java

time

For the following code:

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)));
    }

}

I get the following outputs:

10-12-2013
24-12-1969

Why do they differ?

like image 284
Vlad Avatar asked Dec 10 '13 13:12

Vlad


1 Answers

Because the second value is using an integer not a long and has overflowed.

If you add an L at the end of either constant it will switch it to using long values and the difference will disappear.

This is because in the second example both values are integers. int*int = int. It only gets promoted to long if one or more of the values being multiplied (or any other mathematical operation for that matter) is a long. There is no "magic" that detects the overflow and does the promotion for you.

Even if you did long x = int*int it will still do the multiplication in 32 bits and then convert the result to 64 bit for the assignment.

You can also see this in more subtle places too - for example:

long l;
int x,y;

long result = l+x*y;

Even though result and l are both long, the x*y is still being done as integers since the multiplication is done first. Even if x and y individually fit in a 32 bit integer, if the product of the two does not you run into an overflow situation. The fix is to make sure its converted to long at the earliest point where you run into overflow risk - for example:

long result = l+((long)x)*y;
like image 106
Tim B Avatar answered Oct 08 '22 15:10

Tim B