简体   繁体   中英

Get Human readable time from nanoseconds

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?

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

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).

Here's my suggestion. It's based on the fact that the units in TimeUnit.values() are sorted from smallest (nanoseconds) to longest (days).

    private static String getHumanReadableTime(long nanos) {
        TimeUnit unitToPrint = null;
        String result = "";
        long rest = nanos;
        for(TimeUnit t: TimeUnit.values()) {
            if (unitToPrint == null) {
                unitToPrint = t;
                continue;
            }
            // convert 1 of "t" to "unitToPrint", to get the conversion factor
            long factor = unitToPrint.convert(1, t);
            long value = rest % factor;
            rest /= factor;

            result = value + " " + unitToPrint + " " + result;

            unitToPrint = t;
            if (rest == 0) {
                break;
            }
        }
        if (rest != 0) {
            result = rest + " " + unitToPrint + " " + result;
        }

        return result.trim();
    }

Output for getHumanReadableTime(139543185092L) will be

2 MINUTES 19 SECONDS 543 MILLISECONDS 185 MICROSECONDS 92 NANOSECONDS

java.time

You can use java.time.Duration which is modelled on ISO-8601 standards and was introduced with Java-8 as part of JSR-310 implementation . With Java-9 some more convenience methods were introduced.

Demo:

import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        long elapsedTime = 12345678987654321L;

        Duration duration = Duration.ofNanos(elapsedTime);
        // Default format
        System.out.println(duration);

        // Custom format
        // ####################################Java-8####################################
        String formattedElapsedTime = String.format(
                "%02d Day %02d Hour %02d Minute %02d Second %d Millisecond %d Nanosecond", duration.toDays(),
                duration.toHours() % 24, duration.toMinutes() % 60, duration.toSeconds() % 60,
                duration.toMillis() % 1000, duration.toNanos() % 1000000L);
        System.out.println(formattedElapsedTime);
        // ##############################################################################

        // ####################################Java-9####################################
        formattedElapsedTime = String.format("%02d Day %02d Hour %02d Minute %02d Second %d Millisecond %d Nanosecond",
                duration.toDaysPart(), duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart(),
                duration.toMillisPart(), duration.toNanosPart() % 1000000L);
        System.out.println(formattedElapsedTime);
        // ##############################################################################
    }
}

Output:

PT3429H21M18.987654321S
142 Day 21 Hour 21 Minute 18 Second 987 Millisecond 654321 Nanosecond
142 Day 21 Hour 21 Minute 18 Second 987 Millisecond 654321 Nanosecond

Learn more about the modern date-time API from Trail: Date Time .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM