Как конвертировать миллисекунды в "X минут, x секунд" в Java? - PullRequest
533 голосов
/ 09 марта 2009

Я хочу записать время, используя System.currentTimeMillis(), когда пользователь начинает что-то в моей программе. Когда он закончит, я вычту текущий System.currentTimeMillis() из переменной start, и я хочу показать им время, прошедшее с использованием удобочитаемого формата, такого как «XX часов, XX минут, XX секунд» или даже «XX минут». , XX секунд ", потому что это вряд ли займет у кого-то час.

Какой лучший способ сделать это?

Ответы [ 26 ]

1148 голосов
/ 09 марта 2009

Используйте класс java.util.concurrent.TimeUnit:

String.format("%d min, %d sec", 
    TimeUnit.MILLISECONDS.toMinutes(millis),
    TimeUnit.MILLISECONDS.toSeconds(millis) - 
    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);

Примечание: TimeUnit является частью спецификации Java 1.5, но toMinutes было добавлено с Java 1.6.

Чтобы добавить начальный ноль для значений 0-9, просто выполните:

String.format("%02d min, %02d sec", 
    TimeUnit.MILLISECONDS.toMinutes(millis),
    TimeUnit.MILLISECONDS.toSeconds(millis) - 
    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);

Если TimeUnit или toMinutes не поддерживаются (например, в Android до API версии 9), используйте следующие уравнения:

int seconds = (int) (milliseconds / 1000) % 60 ;
int minutes = (int) ((milliseconds / (1000*60)) % 60);
int hours   = (int) ((milliseconds / (1000*60*60)) % 24);
//etc...
119 голосов
/ 05 октября 2011

Основываясь на ответе @ siddhadev, я написал функцию, которая преобразует миллисекунды в форматированную строку:

   /**
     * Convert a millisecond duration to a string format
     * 
     * @param millis A duration to convert to a string form
     * @return A string of the form "X Days Y Hours Z Minutes A Seconds".
     */
    public static String getDurationBreakdown(long millis) {
        if(millis < 0) {
            throw new IllegalArgumentException("Duration must be greater than zero!");
        }

        long days = TimeUnit.MILLISECONDS.toDays(millis);
        millis -= TimeUnit.DAYS.toMillis(days);
        long hours = TimeUnit.MILLISECONDS.toHours(millis);
        millis -= TimeUnit.HOURS.toMillis(hours);
        long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
        millis -= TimeUnit.MINUTES.toMillis(minutes);
        long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);

        StringBuilder sb = new StringBuilder(64);
        sb.append(days);
        sb.append(" Days ");
        sb.append(hours);
        sb.append(" Hours ");
        sb.append(minutes);
        sb.append(" Minutes ");
        sb.append(seconds);
        sb.append(" Seconds");

        return(sb.toString());
    }
67 голосов
/ 16 февраля 2012
long time = 1536259;

return (new SimpleDateFormat("mm:ss:SSS")).format(new Date(time));

Печать:

25: 36: 259

35 голосов
/ 09 марта 2009

Хм ... сколько миллисекунд в секунду? А через минуту? Деление не так уж сложно.

int seconds = (int) ((milliseconds / 1000) % 60);
int minutes = (int) ((milliseconds / 1000) / 60);

Продолжайте в том же духе в течение нескольких часов, дней, недель, месяцев, года, десятилетий и т.д.

26 голосов
/ 20 апреля 2014

Использование пакета java.time в Java 8:

Instant start = Instant.now();
Thread.sleep(63553);
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

Выходные данные в Формат продолжительности ISO 8601 : PT1M3.553S (1 минута и 3,553 секунды).

26 голосов
/ 09 марта 2009

Я бы не стал использовать дополнительную зависимость только для этого (в конце концов, деление не так уж сложно), но если вы все равно используете Commons Lang, есть DurationFormatUtils .

25 голосов
/ 09 марта 2009

Либо деление рук, либо используйте SimpleDateFormat API .

long start = System.currentTimeMillis();
// do your work...
long elapsed = System.currentTimeMillis() - start;
DateFormat df = new SimpleDateFormat("HH 'hours', mm 'mins,' ss 'seconds'");
df.setTimeZone(TimeZone.getTimeZone("GMT+0"));
System.out.println(df.format(new Date(elapsed)));

Редактировать Бомба : в комментариях было показано, что этот подход работает только в течение меньших периодов времени (то есть менее суток).

21 голосов
/ 25 мая 2011

Просто чтобы добавить больше информации если вы хотите отформатировать как: ЧЧ: мм: сс

0 <= ЧЧ <= бесконечное </p>

0 <= мм <60 </p>

0 <= сс <60 </p>

используйте это:

int h = (int) ((startTimeInMillis / 1000) / 3600);
int m = (int) (((startTimeInMillis / 1000) / 60) % 60);
int s = (int) ((startTimeInMillis / 1000) % 60);

У меня сейчас была эта проблема, и я понял это

12 голосов
/ 05 апреля 2011

Я думаю, что лучший способ это:

String.format("%d min, %d sec", 
    TimeUnit.MILLISECONDS.toSeconds(length)/60,
    TimeUnit.MILLISECONDS.toSeconds(length) % 60 );
11 голосов
/ 17 июля 2014

Кратчайшее решение:

Вот, вероятно, самый короткий, который также касается часовых поясов.

System.out.printf("%tT", millis-TimeZone.getDefault().getRawOffset());

Какие выходы например:

00:18:32

Пояснение:

%tT - это время, отформатированное для 24-часовых часов как %tH:%tM:%tS.

%tT также принимает длинные как входные данные, поэтому нет необходимости создавать Date. printf() просто выведет время, указанное в миллисекундах, но в текущем часовом поясе, поэтому мы должны вычесть необработанное смещение текущего часового пояса, так что 0 миллисекунд будут равны 0 часам, а не значение смещения времени текущего часового пояса .

Примечание # 1: Если вам нужен результат как String, вы можете получить его так:

String t = String.format("%tT", millis-TimeZone.getDefault().getRawOffset());

Примечание # 2: Это дает правильный результат, только если millis меньше дня, потому что часть дня не включена в выходные данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...