Як перетворити мільйони секунд на "X хв, х секунд" на Java?


571

Я хочу записати час, System.currentTimeMillis()коли користувач починає щось у своїй програмі. Коли він закінчиться, я віднімаю струм System.currentTimeMillis()зі startзмінної, і я хочу показати їм час, що минув, використовуючи читаний людиною формат, такий як "XX годин, XX хвилин, XX секунд" або навіть "XX хвилин, XX секунд", оскільки його не ймовірно, що хтось забере годину.

Який найкращий спосіб зробити це?


5
Якщо це займе більше години, ви все одно можете надрукувати щось подібне; 90 хвилин, 53 сек.
Пітер Лорі

1
моя відповідь запізнюється на 6 років, але я вважаю, що це більш загальне, ніж прийняте: stackoverflow.com/a/35082080/82609
Себастьян Лорбер

1
ознайомтеся з простим прикладом для перетворення
мільйонних

Відповіді:


1227

Використовуйте 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...

5
int months = (int) ((float) дні / 30.4368499f); int years = (int) ((float) дні / 365.242199f);
Натан Шверман

7
Я пропоную використовувати мод 60 замість віднімання хвилин, це виглядає чистіше. Однак потрібно знати, що 1 хв = 60 сек, щоб зробити це ... =)
Пер Александерсон

2
@AndreasDietrich SimpleDateFormat не працює для часових різниць, оскільки повертає лише дату з епохи!
Мухаммед Бабар

5
int hours = (int) ((milliseconds / (1000*60*60)) % 24)це не працює! натомість має бути такint hours = (int) (milliseconds / (1000*60*60)) ;
Мухаммед Бабар

5
Якщо хтось хоче формату відеофайлів ( год: мм: сс ):String.format("%01d:%02d:%02d", hours, minutes, seconds);
кази

124

На основі відповіді @ 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());
    }

2
Ви повинні там перевірити наявність одинарних / кратних, щоб уникнути подібних ситуацій:1 Days 1 Hours 1 Minutes 1 Seconds
Даніель

7
Ми могли б використовувати функцію модуля замість віднімання: long days = TimeUnit.MILLISECONDS.toDays(millis); long hours = TimeUnit.MILLISECONDS.toHours(millis) % 24; long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) % 60; long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % 60; long milliseconds = millis % 1000; а також метод String.format:return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds", days, hours, minutes, seconds, milliseconds);
Хосе Тепедіно

78
long time = 1536259;

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

Друкує:

25: 36: 259


1
Мені подобається, що вищезгаданий підхід є найкращим, якщо нічого іншого простотою! Оскільки ми маємо справу з часом та тривалістю, я зазвичай використовую Джоду. Приклад, якщо у вас є два DateTimes, почніть і Duration dur = new Duration(start, end); long millis = dur.getMillis();
закінчіть

1
Я мав би відзначити 2 способи використання форматорів Joda. Перша варіація вашої теми: DateTimeFormat.forPattern("mm:ss:SSS").print(new DateTime(time)); Або перетворіть тривалість у період, який можна автоматично надрукувати за допомогою Joda PeriodFormatter. Перетворення може втратити точність, якщо крім хронології ISO. Припустимо, тривалість представлена ​​змінною duration. Period period = duration.toPeriod().normalizedStandard(PeriodType.time()); PeriodFormat.getDefault().print(period)) Вихід є приголомшливим: 1 секунда і 581 мілісекунда, що відповідає на головне питання, що було вище
TechTrip

2
Трохи запізнюємось тут :) Але чи не потрібно вам розміщувати simpleDateFormat.setTimezone (TimeZone.getTimeZone ("GMT")), якщо це не ваш фактичний часовий пояс?
Olle Söderström

@ OlleSöderström Тут дійсно є проблема з часовим поясом. Але якщо встановити його на GMT або UTC, то часова частина буде 12 замість 0 за тривалості менше 1 години.
Episodex

2
Часова зона тут не єдина проблема ... ця відповідь вводить в оману і може серйозно збити з пантелику Java. Навіть ігноруючи надмірні зовнішні дужки, ОП запитала, як представити тривалість (різниця між двома пунктами часу, виміряна в мс). Назвати цю тривалість "часом" і трактувати її як зсув з 1 січня 1970 року лише для форматування її менших компонентів - це просто ... неправильно. Більше того, цей самий підхід був запропонований на цю відповідь на 3 роки раніше (див. Коментарі там, щоб отримати докладнішу інформацію про проблеми часового поясу).
Амос М. Карпентер

36

Гм ... скільки мілісекунд за секунду? І за хвилину? Відділення не так складно.

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

Продовжуйте так протягом годин, днів, тижнів, місяців, року, десятиліть, будь-що.


2
Насправді, робити це протягом чого-небудь довшого, ніж на годину, не є хорошою ідеєю, оскільки результати можуть бути неправильними / неінтуїтивними, коли задіяно літній час (23 години або 24 години) або високосний рік. Якщо я прочитаю "X відбудеться через 1 рік / місяць", я би очікував, що це буде однакова дата та час.
Майкл Боргвардт

5
System.currentTimeMillis () захищений від DST, тому це не буде плутати додаткові чи відсутні години. Якщо вам потрібно показати різницю між двома конкретними датами, вам краще створити об’єкти дати з заданим часом і показати різницю між цими двома.
Бомбе

1
Поза тижнями вона не визначена, оскільки тривалість місяця мінлива. Тож дійсно, вам потрібно обчислити відносно заданого часу.
PhiLho

31

Використання пакету 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,555 секунди).



1
(ANDROID) Потрібен рівень 26 API
хтось десь


1
Це дивовижно :) дякую за хед-ап!
Хтось десь

27

Я б не втягував зайву залежність тільки для цього (поділ все-таки не такий важкий, зрештою), але якщо ви все одно використовуєте Commons Lang, є DurationFormatUtils .

Приклад використання (адаптований звідси ):

import org.apache.commons.lang3.time.DurationFormatUtils

public String getAge(long value) {
    long currentTime = System.currentTimeMillis();
    long age = currentTime - value;
    String ageString = DurationFormatUtils.formatDuration(age, "d") + "d";
    if ("0d".equals(ageString)) {
        ageString = DurationFormatUtils.formatDuration(age, "H") + "h";
        if ("0h".equals(ageString)) {
            ageString = DurationFormatUtils.formatDuration(age, "m") + "m";
            if ("0m".equals(ageString)) {
                ageString = DurationFormatUtils.formatDuration(age, "s") + "s";
                if ("0s".equals(ageString)) {
                    ageString = age + "ms";
                }
            }
        }
    }
    return ageString;
}   

Приклад:

long lastTime = System.currentTimeMillis() - 2000;
System.out.println("Elapsed time: " + getAge(lastTime)); 

//Output: 2s

Примітка . Щоб отримати мільйони від двох об’єктів LocalDateTime, ви можете використовувати:

long age = ChronoUnit.MILLIS.between(initTime, LocalDateTime.now())

1
Чудово, я просто запитував себе, чи є надійна бібліотека, яка включає такі речі.
Лайцік

Оскільки посилання, як правило, не дуже корисно, я додав приклад того, як його можна використовувати.
lepe

26

Або підрозділи вручну, або використовуйте API SimpleDateFormat .

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

Редагувати Бомбе : У коментарях було показано, що такий підхід працює лише за меншої тривалості (тобто менше доби).


Ого. Це злий злом, залежний від часового поясу. Він порушиться нещадно, коли у вас буде зміщений часовий пояс, який не є кратним 60 хвилин (і у нас є кілька таких примхливих 30-хвилинних зсувів часових поясів у світі).
Бомбе

Крім того, він порушиться так само погано, як тільки ви включите години в рядок формату і не будете в GMT + 0, з тих же причин.
Бомбе

Так? Дійсно? Де? Не сумніваючись у вас, просто ніколи раніше про це не чули - якась нова помилка, яку слід врахувати ;-)
Треб

Так. Поставте прапорець "Список часових поясів" у Вікіпедії, наприклад Непал знаходиться за GMT + 05: 45.
Бомбе

2
Кадріан, тепер він працюватиме лише тривалістю менше доби. Кількість годин завжди буде від 0 до 23 включно.
Бомбе

21

Просто для того, щоб додати більше інформації, якщо ви хочете форматувати: HH: mm: ss

0 <= HH <= нескінченний

0 <= мм <60

0 <= ss <60

використовуй це:

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

У мене просто було це питання зараз і я з'ясував це


1
Найкраща відповідь тут. Чому всі хочуть зробити такі складні? Це проста математика, люди.
Ламбарт

11

Я думаю, що найкращий спосіб:

String.format("%d min, %d sec", 
    TimeUnit.MILLISECONDS.toSeconds(length)/60,
    TimeUnit.MILLISECONDS.toSeconds(length) % 60 );

хвилин можна скористатись TimeUnit.MILLISECONDS.toMinutes (length)
EminenT

11

Найкоротше рішення:

Ось, мабуть, найкоротший, який також стосується часових поясів.

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

Які результати, наприклад:

00:18:32

Пояснення:

%tT- час, відформатований для 24-годинного годинника як %tH:%tM:%tS.

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

Примітка №1. Якщо результат вам потрібен як String, ви можете отримати його так:

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

Примітка №2: Це дає правильний результат лише у тому випадку, якщо millisменше доби, оскільки денна частина не включена у висновок.


Це така чудова скорочення, але коли я її використовую, я не отримую очікуваних результатів. Отож я маю: long millis = 8398;і коли я передаю це на String.format("%tT", millis)вихід, це 19:00:08. Звідки береться 19?
Nelda.techspiress

1
@ Nelda.techspiress Це зміщення вашого часового поясу. Ви повинні відняти TimeZone.getDefault().getRawOffset()з нього саме так, як написано у відповіді:String.format("%tT", millis-TimeZone.getDefault().getRawOffset())
icza

які подбали про це. Дякую за уточнення.
Nelda.techspiress

8

Joda-Time

Використання часу Joda :

DateTime startTime = new DateTime();

// do something

DateTime endTime = new DateTime();
Duration duration = new Duration(startTime, endTime);
Period period = duration.toPeriod().normalizedStandard(PeriodType.time());
System.out.println(PeriodFormat.getDefault().print(period));

1
Не потрібно цього PeriodFormatв останньому рядку. Просто зателефонуйте, Period::toStringщоб отримати стандартну строку тривалості ISO 8601 за замовчуванням.
Василь Бурк

8

Переглянувши внесок @ brent-nash, ми могли б використовувати функцію модуля замість віднімання та використовувати метод String.format для рядка результатів:

  /**
   * 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 B Milliseconds".
   */
   public static String getDurationBreakdown(long millis) {
       if (millis < 0) {
          throw new IllegalArgumentException("Duration must be greater than zero!");
       }

       long days = TimeUnit.MILLISECONDS.toDays(millis);
       long hours = TimeUnit.MILLISECONDS.toHours(millis) % 24;
       long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) % 60;
       long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % 60;
       long milliseconds = millis % 1000;

       return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds",
                            days, hours, minutes, seconds, milliseconds);
   }

6

для Android нижче API 9

(String.format("%d hr %d min, %d sec", millis/(1000*60*60), (millis%(1000*60*60))/(1000*60), ((millis%(1000*60*60))%(1000*60))/1000)) 

5

У малий час, менше години, я віддаю перевагу:

long millis = ...

System.out.printf("%1$TM:%1$TS", millis);
// or
String str = String.format("%1$TM:%1$TS", millis);

для більш тривалих інтервалів:

private static final long HOUR = TimeUnit.HOURS.toMillis(1);
...
if (millis < HOUR) {
    System.out.printf("%1$TM:%1$TS%n", millis);
} else {
    System.out.printf("%d:%2$TM:%2$TS%n", millis / HOUR, millis % HOUR);
}

Це дорогоцінний натяк: існує багато таких можливостей для дати та часу з API Format Format Java ( docs.oracle.com/javase/8/docs/api/java/util/Formatter.html )! Ви також можете мати інший результат умови за допомогою: System.out.printf ("% 1 $ tH:% 1 $ tM:% 1 $ tS% n", міліс); або навіть System.out.printf ("% 1 $ tT% n", міліс);
Хосе Тепедіно

@JoseTepedino, але ви знаєте, що показує %tH лише від 0 до 23 годин? Це означає, що, наприклад, 24 години відображатимуться як 00, 25 годин як 01... те саме, що діють %tT- дні будуть мовчки відкинуті. Звичайно, також можуть відображатися дні, але це буде надмірною проблемою у мене, коли я писав це (ще в 2011 році) [:-)
user85421

Я бачу ... це дійсно працювало б лише менше, ніж за день (24 години). Дякую.
Хосе Тепедіно

5

Мій простий розрахунок:

String millisecToTime(int millisec) {
    int sec = millisec/1000;
    int second = sec % 60;
    int minute = sec / 60;
    if (minute >= 60) {
        int hour = minute / 60;
        minute %= 60;
        return hour + ":" + (minute < 10 ? "0" + minute : minute) + ":" + (second < 10 ? "0" + second : second);
    }
    return minute + ":" + (second < 10 ? "0" + second : second);
}

Щасливе кодування :)


Я думаю, що long більше підходить для цієї функції, оскільки System.currentTimeMillis () повертає довге значення.
апродан

Це неправильно, ви перевірили вихід?
Хорхесіс

4

Ось відповідь, заснована на відповіді Brent Nash, Сподіваюся, що це допомагає!

public static String getDurationBreakdown(long millis)
{
    String[] units = {" Days ", " Hours ", " Minutes ", " Seconds "};
    Long[] values = new Long[units.length];
    if(millis < 0)
    {
        throw new IllegalArgumentException("Duration must be greater than zero!");
    }

    values[0] = TimeUnit.MILLISECONDS.toDays(millis);
    millis -= TimeUnit.DAYS.toMillis(values[0]);
    values[1] = TimeUnit.MILLISECONDS.toHours(millis);
    millis -= TimeUnit.HOURS.toMillis(values[1]);
    values[2] = TimeUnit.MILLISECONDS.toMinutes(millis);
    millis -= TimeUnit.MINUTES.toMillis(values[2]);
    values[3] = TimeUnit.MILLISECONDS.toSeconds(millis);

    StringBuilder sb = new StringBuilder(64);
    boolean startPrinting = false;
    for(int i = 0; i < units.length; i++){
        if( !startPrinting && values[i] != 0)
            startPrinting = true;
        if(startPrinting){
            sb.append(values[i]);
            sb.append(units[i]);
        }
    }

    return(sb.toString());
}

4
    long startTime = System.currentTimeMillis();
    // do your work...
    long endTime=System.currentTimeMillis();
    long diff=endTime-startTime;       
    long hours=TimeUnit.MILLISECONDS.toHours(diff);
    diff=diff-(hours*60*60*1000);
    long min=TimeUnit.MILLISECONDS.toMinutes(diff);
    diff=diff-(min*60*1000);
    long seconds=TimeUnit.MILLISECONDS.toSeconds(diff);
    //hour, min and seconds variables contains the time elapsed on your work

3
Формула в рядку 6 неправильна. diff=diff-(hours*60*1000);повинно бути diff=diff-(hours*60*60*1000);. Я спробував редагувати його, але дратівлива політика редагування StackOverflow говорить, що символів для редагування недостатньо символів.
quux00

4

По-перше, System.currentTimeMillis()і Instant.now()не ідеально підходять для проведення часу. Вони обоє повідомляють про настінний час, який комп'ютер точно не знає, і який може нерегулярно рухатися, включаючи рух назад, якщо, наприклад, демон NTP коригує системний час. Якщо ваш час відбувається на одній машині, вам слід використовувати System.nanoTime () .

По-друге, від Java 8 далі java.time.Дурація - найкращий спосіб представити тривалість:

long start = System.nanoTime();
// do things...
long end = System.nanoTime();
Duration duration = Duration.ofNanos(end - start);
System.out.println(duration); // Prints "PT18M19.511627776S"
System.out.printf("%d Hours %d Minutes %d Seconds%n",
        duration.toHours(), duration.toMinutes() % 60, duration.getSeconds() % 60);
// prints "0 Hours 18 Minutes 19 Seconds"

3

Якщо ви знаєте, що різниця в часі складе менше години, то ви можете використовувати наступний код:

    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();

    c2.add(Calendar.MINUTE, 51);

    long diff = c2.getTimeInMillis() - c1.getTimeInMillis();

    c2.set(Calendar.MINUTE, 0);
    c2.set(Calendar.HOUR, 0);
    c2.set(Calendar.SECOND, 0);

    DateFormat df = new SimpleDateFormat("mm:ss");
    long diff1 = c2.getTimeInMillis() + diff;
    System.out.println(df.format(new Date(diff1)));

Це призведе до: 51:00


3

Ця відповідь схожа на деякі відповіді вище. Однак я вважаю, що це буде корисно, оскільки, на відміну від інших відповідей, це видалить зайві коми або пробіли та обробляє абревіатуру.

/**
 * Converts milliseconds to "x days, x hours, x mins, x secs"
 * 
 * @param millis
 *            The milliseconds
 * @param longFormat
 *            {@code true} to use "seconds" and "minutes" instead of "secs" and "mins"
 * @return A string representing how long in days/hours/minutes/seconds millis is.
 */
public static String millisToString(long millis, boolean longFormat) {
    if (millis < 1000) {
        return String.format("0 %s", longFormat ? "seconds" : "secs");
    }
    String[] units = {
            "day", "hour", longFormat ? "minute" : "min", longFormat ? "second" : "sec"
    };
    long[] times = new long[4];
    times[0] = TimeUnit.DAYS.convert(millis, TimeUnit.MILLISECONDS);
    millis -= TimeUnit.MILLISECONDS.convert(times[0], TimeUnit.DAYS);
    times[1] = TimeUnit.HOURS.convert(millis, TimeUnit.MILLISECONDS);
    millis -= TimeUnit.MILLISECONDS.convert(times[1], TimeUnit.HOURS);
    times[2] = TimeUnit.MINUTES.convert(millis, TimeUnit.MILLISECONDS);
    millis -= TimeUnit.MILLISECONDS.convert(times[2], TimeUnit.MINUTES);
    times[3] = TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS);
    StringBuilder s = new StringBuilder();
    for (int i = 0; i < 4; i++) {
        if (times[i] > 0) {
            s.append(String.format("%d %s%s, ", times[i], units[i], times[i] == 1 ? "" : "s"));
        }
    }
    return s.toString().substring(0, s.length() - 2);
}

/**
 * Converts milliseconds to "x days, x hours, x mins, x secs"
 * 
 * @param millis
 *            The milliseconds
 * @return A string representing how long in days/hours/mins/secs millis is.
 */
public static String millisToString(long millis) {
    return millisToString(millis, false);
}

3

Є проблема. Коли мілісекунди - 59999, насправді це 1 хвилина, але вона буде обчислена як 59 секунд і 999 мілісекунд втрачено.

Ось модифікована версія на основі попередніх відповідей, яка може вирішити цю втрату:

public static String formatTime(long millis) {
    long seconds = Math.round((double) millis / 1000);
    long hours = TimeUnit.SECONDS.toHours(seconds);
    if (hours > 0)
        seconds -= TimeUnit.HOURS.toSeconds(hours);
    long minutes = seconds > 0 ? TimeUnit.SECONDS.toMinutes(seconds) : 0;
    if (minutes > 0)
        seconds -= TimeUnit.MINUTES.toSeconds(minutes);
    return hours > 0 ? String.format("%02d:%02d:%02d", hours, minutes, seconds) : String.format("%02d:%02d", minutes, seconds);
}

2

У Java 9 це простіше:

    Duration elapsedTime = Duration.ofMillis(millisDiff );
    String humanReadableElapsedTime = String.format(
            "%d hours, %d mins, %d seconds",
            elapsedTime.toHours(),
            elapsedTime.toMinutesPart(),
            elapsedTime.toSecondsPart());

Це створює подібний рядок 0 hours, 39 mins, 9 seconds.

Якщо ви хочете округлити цілі секунди перед форматуванням:

    elapsedTime = elapsedTime.plusMillis(500).truncatedTo(ChronoUnit.SECONDS);

Не залишати годин, якщо вони дорівнюють 0:

    long hours = elapsedTime.toHours();
    String humanReadableElapsedTime;
    if (hours == 0) {
        humanReadableElapsedTime = String.format(
                "%d mins, %d seconds",
                elapsedTime.toMinutesPart(),
                elapsedTime.toSecondsPart());

    } else {
        humanReadableElapsedTime = String.format(
                "%d hours, %d mins, %d seconds",
                hours,
                elapsedTime.toMinutesPart(),
                elapsedTime.toSecondsPart());
    }

Тепер ми можемо мати, наприклад 39 mins, 9 seconds.

Щоб надрукувати хвилини та секунди з нульовим 02початковим значенням, щоб вони завжди були двозначними, просто вставте у відповідні специфікатори формату, таким чином:

    String humanReadableElapsedTime = String.format(
            "%d hours, %02d mins, %02d seconds",
            elapsedTime.toHours(),
            elapsedTime.toMinutesPart(),
            elapsedTime.toSecondsPart());

Тепер ми можемо мати, наприклад 0 hours, 39 mins, 09 seconds.


Будь-яке форматування для видалення годин / хвилин / секунд, коли попереднє число дорівнює 0? Я маю на увазі, що це можливо з умовою, якщо інакше, але як щодо існування такого String-форматування чи чогось близького, чи є таке?
Фарид

1
Ні, вибачте, @FARID, потрібно if- elseтам.
Оле ВВ

1

для правильних рядків ("1 година, 3 сек", "3 хв", але не "0 годин, 0 хв., 3 сек.") я пишу цей код:

int seconds = (int)(millis / 1000) % 60 ;
int minutes = (int)((millis / (1000*60)) % 60);
int hours = (int)((millis / (1000*60*60)) % 24);
int days = (int)((millis / (1000*60*60*24)) % 365);
int years = (int)(millis / 1000*60*60*24*365);

ArrayList<String> timeArray = new ArrayList<String>();

if(years > 0)   
    timeArray.add(String.valueOf(years)   + "y");

if(days > 0)    
    timeArray.add(String.valueOf(days) + "d");

if(hours>0)   
    timeArray.add(String.valueOf(hours) + "h");

if(minutes>0) 
    timeArray.add(String.valueOf(minutes) + "min");

if(seconds>0) 
    timeArray.add(String.valueOf(seconds) + "sec");

String time = "";
for (int i = 0; i < timeArray.size(); i++) 
{
    time = time + timeArray.get(i);
    if (i != timeArray.size() - 1)
        time = time + ", ";
}

if (time == "")
  time = "0 sec";

1

Я змінив відповідь @MyKuLLSKI і додав підтримку розширення. Я вийняв секунди, тому що вони мені не потрібні, хоча сміливо повторно додайте їх, якщо вам це потрібно.

public static String intervalToHumanReadableTime(int intervalMins) {

    if(intervalMins <= 0) {
        return "0";
    } else {

        long intervalMs = intervalMins * 60 * 1000;

        long days = TimeUnit.MILLISECONDS.toDays(intervalMs);
        intervalMs -= TimeUnit.DAYS.toMillis(days);
        long hours = TimeUnit.MILLISECONDS.toHours(intervalMs);
        intervalMs -= TimeUnit.HOURS.toMillis(hours);
        long minutes = TimeUnit.MILLISECONDS.toMinutes(intervalMs);

        StringBuilder sb = new StringBuilder(12);

        if (days >= 1) {
            sb.append(days).append(" day").append(pluralize(days)).append(", ");
        }

        if (hours >= 1) {
            sb.append(hours).append(" hour").append(pluralize(hours)).append(", ");
        }

        if (minutes >= 1) {
            sb.append(minutes).append(" minute").append(pluralize(minutes));
        } else {
            sb.delete(sb.length()-2, sb.length()-1);
        }

        return(sb.toString());          

    }

}

public static String pluralize(long val) {
    return (Math.round(val) > 1 ? "s" : "");
}

int intervalMins vs long millis
Кікенет

1

Я висвітлював це в іншій відповіді, але ви можете:

public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {
    long diffInMillies = date2.getTime() - date1.getTime();
    List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
    Collections.reverse(units);
    Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
    long milliesRest = diffInMillies;
    for ( TimeUnit unit : units ) {
        long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
        long diffInMilliesForUnit = unit.toMillis(diff);
        milliesRest = milliesRest - diffInMilliesForUnit;
        result.put(unit,diff);
    }
    return result;
}

Вихід щось подібний Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0} , з упорядкованими одиницями.

Вам належить розібратися, як інтернаціоналізувати ці дані відповідно до цільової мови.


1

Використовуйте java.util.concurrent.TimeUnit і використовуйте цей простий метод:

private static long timeDiff(Date date, Date date2, TimeUnit unit) {
    long milliDiff=date2.getTime()-date.getTime();
    long unitDiff = unit.convert(milliDiff, TimeUnit.MILLISECONDS);
    return unitDiff; 
}

Наприклад:

SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd HH:mm:ss");  
Date firstDate = sdf.parse("06/24/2017 04:30:00");
Date secondDate = sdf.parse("07/24/2017 05:00:15");
Date thirdDate = sdf.parse("06/24/2017 06:00:15");

System.out.println("days difference: "+timeDiff(firstDate,secondDate,TimeUnit.DAYS));
System.out.println("hours difference: "+timeDiff(firstDate,thirdDate,TimeUnit.HOURS));
System.out.println("minutes difference: "+timeDiff(firstDate,thirdDate,TimeUnit.MINUTES));
System.out.println("seconds difference: "+timeDiff(firstDate,thirdDate,TimeUnit.SECONDS));

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.