Search code examples
javaandroiddatecalendartimeunit

Formatting milliseconds to hh:mm:ss format


I am having milliseconds value and want to display the time subtracting 5 minutes from current milliseconds value in hh:mm:ss format.

Code

String str = String.format("%02d:%02d:%02d", 
                                TimeUnit.MILLISECONDS.toHours((cal.getTimeInMillis()-300000)),
                                TimeUnit.MILLISECONDS.toMinutes(cal.getTimeInMillis()-300000) - 
                                TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(cal.getTimeInMillis()-300000)),
                                TimeUnit.MILLISECONDS.toSeconds(cal.getTimeInMillis()-300000) - 
                                TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(cal.getTimeInMillis()-300000)));

Toast.makeText(getApplicationContext(), "Alarm Set."+str, Toast.LENGTH_LONG).show()

Output now

Alarm Set. 386467:25:00

Output Required

Alarm Set. 07:25:00

As you see minutes and seconds are getting retrieved quiet right but there's some problem with hours.

P.S

1.I referred this post.They say it works fine.But don't know why not in my case.

2.I am sure about what i want to get as hours value i.e 07 as i have set the value using Calendar.HOUR and its getting displayed too if i use cal.get(Calendar.HOUR).cal is of course object of Calendar class.

Alternative Solution

 SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
 String str1 = sdf.format(new Date(cal.getTimeInMillis()-300000));
 Toast.makeText(getApplicationContext(), "Alarm Set."+str1, Toast.LENGTH_LONG).show();

Solution

  • It is working fine as is, the only reason you see such a huge offset is because it is calculating the total number of hours since the UNIX epoch.

    When you do a Calendar.getInstance() it gets you the current point in time. Converting it to milliseconds are the total millis since the UNIX epoch.

    You can check the total number of hours since the epoch:

    //Check for the hours since the UNIX Epoch
    System.out.println(System.currentTimeMillis() / 3600000);
    

    Output:

    386439
    

    You code below would also produce this result appended with the minutes and seconds of the current point in time:

    Calendar cal = Calendar.getInstance();
    
    String str = String
            .format("%02d:%02d:%02d",
                    TimeUnit.MILLISECONDS.toHours((cal.getTimeInMillis() - 300000)),
                    TimeUnit.MILLISECONDS.toMinutes(cal.getTimeInMillis() - 300000)
                            - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS
                                    .toHours(cal.getTimeInMillis() - 300000)),
                    TimeUnit.MILLISECONDS.toSeconds(cal.getTimeInMillis() - 300000)
                            - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS
                                    .toMinutes(cal.getTimeInMillis() - 300000)));
    
    System.out.println(str);
    

    Output:

    386439:38:20
    

    Note: Your reference example considers a constant value of millis (3600000) hence it gets a readable time there.

    The better solution is provided in the other answer which provides for your requirement.