Nasıl milisaniye Java için "X dakika, x saniye" dönüştürmek için?


572

System.currentTimeMillis()Bir kullanıcının programımda bir şey başlattığında zamanını kaydetmek istiyorum . O tamamlandığında, ben akımı düşeriz System.currentTimeMillis()gelen startdeğişken ve ben zaman böyle "XX saat XX dakika, XX saniye", hatta "XX dakika, XX saniye" olarak, bir insan okunabilir biçimi kullanarak geçen onlara göstermek istiyorum çünkü onun saat başı birini alması muhtemel değil.

Bunu yapmanın en iyi yolu nedir?


5
Bir saatten fazla sürüyorsa yine de şöyle bir şey yazdırabilirsiniz; 90 dk, 53 sn.
Peter Lawrey

1
cevabım 6 yıl geç geldi ama bence kabul edilenlerden daha genel: stackoverflow.com/a/35082080/82609
Sebastien Lorber

Yanıtlar:


1228

java.util.concurrent.TimeUnitSınıfı kullanın :

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

Not: TimeUnitJava 1.5 spesifikasyonunun bir parçasıdır, ancak toMinutesJava 1.6'dan itibaren eklenmiştir.

0-9 arasındaki değerlere sıfır eklemek için yapmanız gerekenler:

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

Eğer TimeUnityoksa toMinutes(API sürümü 9 Android'de daha önce olduğu gibi), aşağıdaki denklemleri kullanın desteklenmez:

int seconds = (int) (milliseconds / 1000) % 60 ;
int minutes = (int) ((milliseconds / (1000*60)) % 60);
int hours   = (int) ((milliseconds / (1000*60*60)) % 24);
//etc...

5
int ay = (int) ((float) gün / 30.4368499f); int yıl = (int) ((float) gün / 365.242199f);
Nathan Schwermann

7
Ben dakika çıkarmak yerine mod 60 kullanmanızı öneririz, daha temiz görünüyor. Ancak, bunu yapmak için 1 dakika = 60 saniye olduğunu bilmek gerekir ... =)
Per Alexandersson

2
@AndreasDietrich SimpleDateFormat, sadece çağdan itibaren tarihi döndürdüğü için zaman farklılıkları için çalışmaz!
Muhammed Babar

5
int hours = (int) ((milliseconds / (1000*60*60)) % 24)bu işe yaramıyor! bunun yerine böyle olmalıint hours = (int) (milliseconds / (1000*60*60)) ;
Muhammed Babar

5
Birisi video dosyaları için bir biçim istiyorsa ( s: dd: ss ):String.format("%01d:%02d:%02d", hours, minutes, seconds);
kazy

124

@ Siddhadev'in cevabına dayanarak, milisaniyeyi biçimlendirilmiş bir dizeye dönüştüren bir fonksiyon yazdım:

   /**
     * 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
Bu tür bir durumdan kaçınmak için orada tek / çoklu için bir kontrol yapmalısınız:1 Days 1 Hours 1 Minutes 1 Seconds
Daniel

7
Çıkarma yerine modül işlevi kullanabiliriz: 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; ve ayrıca String.format yöntemi:return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds", days, hours, minutes, seconds, milliseconds);
Jose Tepedino

78
long time = 1536259;

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

Baskılar:

25: 36: 259


1
Ben başka bir şey için sadeliği eğer yukarıdaki yaklaşım en iyi gibi! Zaman ve sürelerle uğraştığımız için tipik olarak Joda kullanıyorum. İki DateTimes'ınız varsa, sırasıyla başlayın ve bitirin:Duration dur = new Duration(start, end); long millis = dur.getMillis();
TechTrip

1
Joda formatlayıcılarını kullanmanın 2 yolunu belirtmeliydim. Temanızdaki ilk varyasyon: DateTimeFormat.forPattern("mm:ss:SSS").print(new DateTime(time)); Veya Süreyi bir Joda kullanılarak otomatik olarak yazdırılabilen bir Döneme dönüştürün PeriodFormatter. ISO kronolojisi dışında dönüşümün hassasiyet kaybı olabilir. Değişkenin temsil ettiği bir Süre olduğunu varsayalım duration. Period period = duration.toPeriod().normalizedStandard(PeriodType.time()); PeriodFormat.getDefault().print(period)) Çıktı harika: 1 saniye ve 581 milisaniye, yukarıdaki ana soruyu cevaplıyor.
TechTrip

2
Biraz geç buraya :) Ama gerçek saat diliminiz olmadıkça buraya simpleDateFormat.setTimezone (TimeZone.getTimeZone ("GMT")) koymanız gerekmez mi?
Olle Söderström

@ OlleSöderström Gerçekten burada saat dilimi ile ilgili bir sorun var. Ancak GMT veya UTC'ye ayarlamak, 1 saatten kısa tüm süreler için saat bölümünün 0 yerine 12 olmasına neden olur.
Episodex

2
Buradaki tek sorun Timezone değil ... Bu cevap yanıltıcıdır ve Java yeni başlayanlarını ciddi şekilde şaşırtabilir. Yedek dış köşeli parantezleri görmezden gelse bile, OP bir sürenin nasıl gösterileceğini sordu (ms cinsinden ölçülen iki zaman noktası arasındaki fark). Bu süreyi "zaman" olarak adlandırmak ve sadece daha küçük bileşenlerini biçimlendirmek uğruna 1 Ocak 1970'ten beri bir mahsup olarak muamele etmek sadece ... yanlış imo. Dahası, aynı yaklaşım 3 yıl önce bu cevap tarafından önerilmişti (saat dilimi sorunları hakkında daha fazla bilgi için oradaki yorumlara bakın).
Amos M. Carpenter

36

Hmm ... Saniyede kaç milisaniye var? Ve bir dakika içinde? Bölünme o kadar da zor değil.

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

Saat, gün, hafta, ay, yıl, onlarca yıl boyunca böyle devam edin.


2
Aslında, bunu bir saatten uzun bir süre için yapmak iyi bir fikir değildir, çünkü gün ışığından yararlanma saati (23 veya 24 saat günler) veya artık yıllar söz konusu olduğunda sonuçlar yanlış / sezgisel olmayabilir. "X 1 yıl / ay içinde" yazacak olursam, aynı tarih ve saat olmasını beklerdim.
Michael Borgwardt

5
System.currentTimeMillis (), DST'ye karşı bağışıktır, bu nedenle ek veya eksik saatlerle karıştırılmayacaktır. İki belirli tarih arasındaki farkı göstermeniz gerekiyorsa, belirli bir tarihe sahip Date nesneleri oluşturmak ve bu ikisi arasındaki farkı göstermek daha iyidir.
Bomba

1
Hafta uzunluğu değişmez, çünkü ay uzunluğu değişkendir. Bu nedenle, belirli bir zaman referansına göre hesaplamanız gerekir.
PhiLho

31

Java 8'de java.time paketini kullanma :

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

Çıktı ISO 8601 Süre biçimindedir : PT1M3.553S(1 dakika ve 3.553 saniye).



1
(ANDROID) API düzeyi 26 Gerektirir
Birisi Somewhere

1
@SomeoneSomewhere API düzeyi 26 altındaki Android için backport'u kullanın, bkz . Android Project'te ThreeTenABP nasıl kullanılır .
Ole VV

1
Bu harika :) heads-up için teşekkürler!
Birisi

27

Ben sadece bunun için ekstra bağımlılık çekmek olmaz (her şeyden önce bölümü o kadar da zor değil), ama yine de Commons Lang kullanıyorsanız, DurationFormatUtils vardır .

Örnek Kullanım ( buradan uyarlanmıştır ):

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

Misal:

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

//Output: 2s

Not : İki LocalDateTime nesnesinden milis almak için şunları kullanabilirsiniz:

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

1
Harika, kendime bu tür şeyleri içeren sağlam bir kütüphane olup olmadığını soruyordum.
Lajcik

Bir bağlantı genellikle çok kullanışlı olmadığından, nasıl kullanılabileceğine dair bir örnek ekledim.
lepe

26

El bölümleri ya da SimpleDateFormat API'sini kullanın .

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

Bombe ile Düzenle : Yorumlarda bu yaklaşımın sadece daha küçük sürelerde (yani bir günden az) işe yaradığı gösterilmiştir.


Vay. Bu kötü, zaman dilimine bağımlı bir saldırı. 60 dakikanın katı olmayan bir saat dilimi ofsetiniz olduğunda (ve dünyadaki 30 dakikalık bu sinir bozucu ofset saat dilimlerinden bir kaçına sahip olduğumuzda) acımasızca kırılacaktır.
Bombe

Ayrıca, format dizesine saat eklediğinizde ve GMT + 0'da değil, aynı nedenlerle en kısa sürede bozulur.
Bombe

Yaparız? Gerçekten mi? Nerede? Seni şüphe değil, daha önce hiç duymadım - dikkate alınması gereken yeni bir tuzak ;-)
Treb

Evet. Wikipedia'da “Zaman dilimlerinin listesi” ni kontrol edin, örneğin Nepal GMT + 05: 45'te.
Bomba

2
cadrian, şimdi sadece bir günden daha kısa sürelerde çalışacak. Saat sayısı her zaman dahil 0 ile 23 arasında olacaktır.
Bomba

21

Şu şekilde biçimlendirmek istiyorsanız daha fazla bilgi eklemek için: SS: dd: ss

0 <= HH <= sonsuz

0 <= mm <60

0 <= ss <60

bunu kullan:

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

Şimdi bu sorunu yaşadım ve anladım


1
En iyi cevap burada. Neden herkes işleri bu kadar karmaşık hale getirmek istiyor? Bu basit matematik, millet.
Lambart

11

Bence en iyi yol:

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

dakikalarca TimeUnit.MILLISECONDS.toMinutes (uzunluk)
EminenT

11

En kısa çözüm:

İşte muhtemelen zaman dilimleriyle de ilgili olan en kısa olanı.

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

Hangi çıktılar örneğin:

00:18:32

Açıklama:

%tT24 saatlik zaman biçimi olarak biçimlendirilen zamandır %tH:%tM:%tS.

%tTayrıca uzun özleri girdi olarak kabul eder, bu yüzden bir oluşturmaya gerek yoktur Date. printf()milisaniye cinsinden belirtilen zamanı yazdıracaktır, ancak geçerli saat diliminde geçerli saat diliminin ham ofsetini çıkarmalıyız, böylece 0 milisaniye 0 saat olacaktır, geçerli saat diliminin zaman ofseti değeri değil.

Not # 1: Sonuca a olarak ihtiyacınız varsa String, bunu şu şekilde alabilirsiniz:

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

Not # 2: Bu, yalnızca millisgün bölümü çıktıya dahil edilmediğinden bir günden azsa doğru sonuç verir .


Bu harika bir kısa yol, ama kullandığımda beklenen sonuçları elde edemiyorum. Bende var: long millis = 8398;ve bunu String.format("%tT", millis)çıktıma geçirdiğimde 19:00:08. 19 nereden geliyor?
Nelda.techspiress

1
@ Nelda.techspiress Saat diliminizin farkı bu. Sen çıkarmak zorunda TimeZone.getDefault().getRawOffset(): cevap yazılmış tam olarak, ondanString.format("%tT", millis-TimeZone.getDefault().getRawOffset())
icza

onunla ilgileniyordu. Açıklama için teşekkür ederim.
Nelda.techspiress

8

Joda-Time

Joda-Time'ı kullanma :

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
PeriodFormatSon satırda buna gerek yok . Varsayılan olarak Period::toStringbir ISO 8601 Süre dizesi almak için arayın .
Basil Bourque

8

@ Brent-nash katkısını tekrar gözden geçirerek, çıkarma yerine modül işlevi kullanabilir ve sonuç dizesi için String.format yöntemini kullanabiliriz:

  /**
   * 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 için API 9'un altında

(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

Küçük zamanlar için, bir saatten az, tercih ederim:

long millis = ...

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

daha uzun aralıklar için:

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

Bu değerli bir ipucu, Java Formatter API ile tarih ve saat için pek çok olasılık var ( docs.oracle.com/javase/8/docs/api/java/util/Formatter.html )! Şununla başka koşul sonucu da alabilirsiniz: System.out.printf ("% 1 $ tH:% 1 $ tM:% 1 $ tS% n", milis); hatta System.out.printf ("% 1 $ tT% n", milis);
Jose Tepedino

@JoseTepedino ama %tH sadece 0'dan 23 saate kadar gösterildiğinin farkında mısınız? Bu, örneğin, 24 saatin 00, 25 gün boyunca 01aynı %tTgün olarak görüntüleneceği anlamına gelir . Elbette, günler de görüntülenebilir, ancak bu yazarken yaşadığım sorun için bir aşırıya kaçma olurdu (geri 2011'de) [:-)
user85421

Anlıyorum ... bu gerçekten sadece bir günden daha az süreler (24 saat) işe yarar. Teşekkür ederim.
Jose Tepedino

5

Basit hesabım:

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

Mutlu kodlama :)


System.currentTimeMillis () uzun bir değer döndürdüğü için uzun bu işlev için daha uygun olduğunu varsayalım.
aprodan

Bu doğru değil, çıktıyı kontrol ettiniz mi?
Jorgesys

4

İşte Brent Nash cevabına dayanan bir cevap, Umarım yardımcı olur!

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. satırdaki formül yanlış. diff=diff-(hours*60*1000);olmalı diff=diff-(hours*60*60*1000);. Düzenlemeyi denedim ama StackOverflow'un can sıkıcı düzenleme politikası bir düzenleme için yeterli karakter olmadığını söylüyor.
quux00

4

İlk olarak System.currentTimeMillis()ve Instant.now()zamanlama için ideal değildir. Her ikisi de bilgisayarın tam olarak bilmediği ve düzensiz bir şekilde hareket edebilen, örneğin NTP arka plan programı sistem saatini düzeltirse geri gitmek de dahil olmak üzere duvar saati süresini bildirir . Zamanlamanız tek bir makinede gerçekleşiyorsa bunun yerine System.nanoTime () öğesini kullanmalısınız .

İkinci olarak, Java 8'den itibaren java.time.Duration , bir süreyi temsil etmenin en iyi yoludur:

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

Zaman farkının bir saatten az olacağını biliyorsanız, aşağıdaki kodu kullanabilirsiniz:

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

Sonuç: 51:00


3

Bu cevap yukarıdaki bazı cevaplara benzer. Ancak, bunun yararlı olacağını hissediyorum, çünkü diğer cevapların aksine, bu ek virgül veya boşluk kaldıracak ve kısaltmayı kaldıracaktır.

/**
 * 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

Bir sorun var. Milisaniye 59999 olduğunda, aslında 1 dakikadır ancak 59 saniye olarak hesaplanacak ve 999 milisaniye kaybedilecektir.

İşte bu kaybı çözebilecek önceki cevaplara dayanan değiştirilmiş bir versiyon:

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'da bu daha kolaydır:

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

Bu gibi bir dize üretir 0 hours, 39 mins, 9 seconds.

Biçimlendirmeden önce tam saniyeye yuvarlamak istiyorsanız:

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

0 ise saatleri dışında bırakmak için:

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

Şimdi örnek olabiliriz 39 mins, 9 seconds.

Dakika ve saniye önde sıfır ile her zaman iki basamak yapmak için yazdırmak için 02, ilgili format belirleyicilerine eklemeniz yeterlidir :

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

Şimdi örnek olabiliriz 0 hours, 39 mins, 09 seconds.


Önceki sayı 0 olduğunda saat / dakika / saniye kaldırmak için herhangi bir biçimlendirme? Başka bir koşulla elde edilebilir demek, ama böyle Dize biçimlendirme veya yakın bir şey varlığı hakkında, herhangi bir var mı?
Farid

1
Hayır, üzgünüm @FARID, ihtiyacın var if- elseorada.
Ole VV

1

doğru dizeler için ("1saat, 3sn", "3 dk" ancak "0 saat, 0 dk, 3 sn" değil) bu kodu yazıyorum:

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'nin cevabını değiştirdim ve plurlizasyon desteği ekledim. İhtiyacım olursa yeniden eklemekten çekinmeyin.

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
Kiquenet

1

Bunu başka bir cevapta ele aldım ama şunları yapabilirsiniz:

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

Çıktı, Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}sipariş edilen birimlerle benzer bir şeydir .

Bu verilerin hedef yerel ayara göre nasıl uluslararasılaştırılacağını bulmak size bağlıdır.


1

Java.util.concurrent.TimeUnit kullanın ve şu basit yöntemi kullanın:

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

Örneğin:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.