I have checked questions about converting time in milliseconds and I followed all answers, but I am still getting the wrong number of hours, although the minutes and seconds are ok.
In my application the user has to select a time from a TimePickerDialog
and set the time in the textview. It will show for example 01:30
in a clock. It will show me 502125000222:30:00
My code TimePickerDialog
:
TimePickerDialog timePickerDialog = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
Calendar mycalendar = Calendar.getInstance();
mycalendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
mycalendar.set(Calendar.MINUTE, minute);
mycalendar.set(Calendar.SECOND, 0);
long times = mycalendar.getTimeInMillis();
// hmsTimeFormatter is a method return time format
String timerRemaind = hmsTimeFormatter(times);
//tv_remaindertime is TextView
tv_remaindertime.setText(timerRemaind);
............
And this hmsTimeFormatter
method that converts milliseconds:
private String hmsTimeFormatter(long milliSeconds) {
String hms = String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(milliSeconds),
TimeUnit.MILLISECONDS.toMinutes(milliSeconds) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(milliSeconds)),
TimeUnit.MILLISECONDS.toSeconds(milliSeconds) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milliSeconds)));
return hms;
}
To understand what's happening:
Calendar.getInstance()
creates a Calendar
with the current date/time in the JVM default timezone01:30:00
I suppose)getTimeInMillis()
, that returns the number of milliseconds since unix epoch (1970-01-01T00:00Z
)Then you use this milliseconds value with TimeUnit
, but that's not what you need. TimeUnit
will treat the number of milliseconds as an amount of time, but what you need is a time of the day:
Although both concepts might use the same words ("hours", "minutes", "seconds", etc), they're not the same thing.
TimeUnit
deals with amounts of time, so it does conversions like "1000 seconds is equivalent to how many minutes?".
Example: TimeUnit.MILLISECONDS.toHours(value)
returns the number of hours equivalent to value
milliseconds (not the time of the day). As the value you're using is the result of getTimeInMillis()
, you're getting the total number of hours since January 1970.
By using the result of getTimeInMillis()
(which represents a specific point in time) with TimeUnit
, you're misusing the value, treating like it was an amount of time.
To format a date, you can use a SimpleDateFormat
:
Calendar mycalendar = Calendar.getInstance();
mycalendar.set(Calendar.HOUR_OF_DAY, 1);
mycalendar.set(Calendar.MINUTE, 30);
mycalendar.set(Calendar.SECOND, 0);
// format: hour:minute:second
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String hms = sdf.format(mycalendar.getTime()); // 01:30:00
With this, hms
will have the value 01:30:00
. Check the javadoc to know what the format HH:mm:ss
means, so you can change it in case you need a different format (If you want just 01:30
, for example, the format will be HH:mm
).
The old classes (Date
, Calendar
and SimpleDateFormat
) have lots of problems and design issues, and they're being replaced by the new APIs.
In Android you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. To make it work, you'll also need the ThreeTenABP (more on how to use it here).
First you create a org.threeten.bp.LocalTime
(a class that represents a time of the day), then you format it with a org.threeten.bp.format.DateTimeFormatter
:
// create time for 01:30
LocalTime time = LocalTime.of(1, 30);
// format: hour:minute:second
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("HH:mm:ss");
String hms = fmt.format(time);
System.out.println(hms); // 01:30:00
Also, check the javadoc for all available formats.