Tommy Saechao Tommy Saechao - 1 year ago 61
Android Question

Displaying hours from converting milleseconds isnt displaying right

I want to get the difference between times who are Calendar object instances. For some reason I am getting a negative number (-17666324.42) when using this function.

For overtimeHourLimit I use the value of 8.

Calendar mDateIn = Calendar.getInstance();
Calendar mDateOut = Calendar.getInstance();
mDateOut.set(mDateOut.YEAR, mDateOut.MONTH, mDateOut.DAY_OF_MONTH, mDateOut.HOUR_OF_DAY+10, mDateOut.MINUTE+25);

public String getRegHours(float overtimeHourLimit)
DecimalFormat twoDecimal = new DecimalFormat("0.##");
double totalHours = 0;
totalHours = (mDateOut.getTimeInMillis() - mDateIn.getTimeInMillis()) / (3.6f * Math.pow(10, 6));
if (totalHours <= overtimeHourLimit)
return twoDecimal.format(totalHours);
else return twoDecimal.format(overtimeHourLimit);

edit: narrowed it down to the mDateOut.set() method. @HarshPandey found out when using mDateOut.add() method instead, it adds to the time correctly. However, I am still stumped on why the .set() method didn't work in the first place.

edit2: I pushed out a sample code that should be equivalent to the code snippet in this question. The only difference is that YEAR, MONTH, DAY_OF_MONTH constants aren't static in Android, but it shouldn't make a difference since I initialized them with the same instances.

tl;dr The .set() method isn't working as expected.

Answer Source

The reason of the problem is here:

mDateOut.set(mDateOut.YEAR, mDateOut.MONTH, mDateOut.DAY_OF_MONTH, mDateOut.HOUR_OF_DAY + 10,
    mDateOut.MINUTE + 25);

for the sake of the explanation:

getTimeInMillis() is getting the epoch: time since 1 January 1970 00:00:00

and this method:


Sets the values for the calendar fields YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY, and MINUTE. in the calendar instance....

but you are passing as parameter the constants of the class Calendar so you are setting the date to a value previous to 1 January 1970 00:00:00

consider that doing this:

mDateOut.set(mDateOut.YEAR, mDateOut.MONTH, mDateOut.DAY_OF_MONTH, mDateOut.HOUR_OF_DAY + 10,
        mDateOut.MINUTE + 25);

is the same as doing this....

mDateOut.set(1, 2, 5, 21, 37);

you can verify that new value by doing:

System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(mDateOut.getTime()));

and you will get as output:

0001-03-05 21:37:40

therefore mDateOut is actually a date waaaaay back in the past...

and the result negative :)