I am trying to implement an ETA feature Using System.nanoTime()
startTime = System.nanoTime()
Long elapsedTime = System.nanoTime() - startTime;
Long allTimeForDownloading = (elapsedTime * allBytes / downloadedBytes);
Long remainingTime = allTimeForDownloading - elapsedTime;
But I cannot figure how to get a human readable form of the nanoseconds; for example: 1d 1h
, 36s
and 3m 50s
.
How can I do this?
If remainingTime
is in nanoseconds, just do the math and append the values to a StringBuilder
:
long remainingTime = 5023023402000L;
StringBuilder sb = new StringBuilder();
long seconds = remainingTime / 1000000000;
long days = seconds / (3600 * 24);
append(sb, days, "d");
seconds -= (days * 3600 * 24);
long hours = seconds / 3600;
append(sb, hours, "h");
seconds -= (hours * 3600);
long minutes = seconds / 60;
append(sb, minutes, "m");
seconds -= (minutes * 60);
append(sb, seconds, "s");
long nanos = remainingTime % 1000000000;
append(sb, nanos, "ns");
System.out.println(sb.toString());
// auxiliary method
public void append(StringBuilder sb, long value, String text) {
if (value > 0) {
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(value).append(text);
}
}
The output for the above is:
1h 23m 43s 23402000ns
(1 hour, 23 minutes, 43 seconds and 23402000 nanoseconds).
I would say both of these answers are correct, but anyways here is a little shorter version of a function that accepts nano time and returns human-readable String.
private String getReadableTime(Long nanos){
long tempSec = nanos/(1000*1000*1000);
long sec = tempSec % 60;
long min = (tempSec /60) % 60;
long hour = (tempSec /(60*60)) % 24;
long day = (tempSec / (24*60*60)) % 24;
return String.format("%dd %dh %dm %ds", day,hour,min,sec);
}
For maximum accuracy, instead of integer division, you can use float division and round up.
It is my old code, you can convert it to days also.
private String calculateDifference(long timeInMillis) {
String hr = "";
String mn = "";
long seconds = (int) ((timeInMillis) % 60);
long minutes = (int) ((timeInMillis / (60)) % 60);
long hours = (int) ((timeInMillis / (60 * 60)) % 24);
if (hours < 10) {
hr = "0" + hours;
}
if (minutes < 10) {
mn = "0" + minutes;
}
textView.setText(Html.fromHtml("<i><small;text-align: justify;><font color=\"#000\">" + "Total shift time: " + "</font></small; text-align: justify;></i>" + "<font color=\"#47a842\">" + hr + "h " + mn + "m " + seconds + "s" + "</font>"));
return hours + ":" + minutes + ":" + seconds;
}
}