Get Human readable time from nanoseconds

Viewed 5020

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?

5 Answers

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.

Related