Nasıl milisaniye "ss: dd: ss" biçimine dönüştürmek için?


184

Kafam karıştı. Bu iş parçacığı üzerine tökezledikten sonra , biçimi olan bir geri sayım zamanlayıcı nasıl biçimlendirmek anlamaya çalıştım hh:mm:ss.

İşte benim girişimim -

//hh:mm:ss
String.format("%02d:%02d:%02d", 
    TimeUnit.MILLISECONDS.toHours(millis),
    TimeUnit.MILLISECONDS.toMinutes(millis) - 
    TimeUnit.MINUTES.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
    TimeUnit.MILLISECONDS.toSeconds(millis) - 
    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));   

Yani, böyle bir değeri denediğimde 3600000ms, anladım 01:59:00, olması gerektiği için yanlış 01:00:00. Açıkçası mantığımda bir sorun var, ama şu anda ne olduğunu göremiyorum!

Biri yardım edebilir mi?

Düzenle -

Onu düzeltti. Milisaniyeyi formatlamak için doğru yolu aşağıda bulabilirsiniz hh:mm:ss-

//hh:mm:ss
String.format("%02d:%02d:%02d", 
    TimeUnit.MILLISECONDS.toHours(millis),
    TimeUnit.MILLISECONDS.toMinutes(millis) - 
    TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
    TimeUnit.MILLISECONDS.toSeconds(millis) - 
    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))));

Sorun buydu TimeUnit.MINUTES.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)). Bunun TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))yerine bu olmalıydı .


1
3.600.000 milisaniye 3.600 saniye veya 60 dakika veya 1 saattir. Olmamalı 00:59:59, olmalı 01:00:00.
Borealid

Yanıtlar:


355

Sen orada gerçekten yakın:

String.format("%02d:%02d:%02d", 
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) -  
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), // The change is in this line
TimeUnit.MILLISECONDS.toSeconds(millis) - 
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));   

Sen kullanarak millisseconds saat dönüştürme edildi dakika yerine saat .

BTW, TimeUnitAPI kullanımınızı seviyorum :)

İşte bazı test kodu:

public static void main(String[] args) throws ParseException {
    long millis = 3600000;
    String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
            TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
            TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
    System.out.println(hms);
}

Çıktı:

01:00:00

Yukarıdaki kodum çıkarma yerine bir modül bölümü kullanılarak büyük ölçüde basitleştirilebilir olduğunu fark ettim:

String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
    TimeUnit.MILLISECONDS.toMinutes(millis) % TimeUnit.HOURS.toMinutes(1),
    TimeUnit.MILLISECONDS.toSeconds(millis) % TimeUnit.MINUTES.toSeconds(1));

Hala TimeUnittüm sihirli değerler için API kullanıyor ve tam olarak aynı çıktıyı veriyor.


2
Amin, TimeUnit API'sini kullanma şekliniz gibi
Dheeraj Bhaskar

2
Tekerleği yeniden icat etmek iyi bir fikir değil! Triton Man'ın cevabı daha iyi bir çözümdür.
محمدباقر

5
@ محمدباقر Ancak diğer cevap harici bir kütüphane, benim kod sadece çekirdek JDK kullanır. Bu, gereksinimlerinizin ne olduğuna bağlıdır - örneğin, harici bir kitaplık kullanamayabilirsiniz. Diğer cevap ise iyi.
Bohemya

2
@Ozuf ekleyin .replaceAll("^00:", "")veya .replaceAll("^00:(00:)?", "")her ikisi de sıfır ise dakika yanı sıra saat kaldırmak.
Bohemian

2
@ Ozuf alırsınız "15:00"ve "10:00:23"sırasıyla; Sadece gelen sıfır sebebi ile husule gelen girişin başlaması bağlantılı olarak maç için kaldırılır ^.
Bohemya

77

Bunun için genel yöntem oldukça basittir:

public static String convertSecondsToHMmSs(long seconds) {
    long s = seconds % 60;
    long m = (seconds / 60) % 60;
    long h = (seconds / (60 * 60)) % 24;
    return String.format("%d:%02d:%02d", h,m,s);
}

1
@ Javaman59, demek istediniz: String.format("% 02 d:%02d:%02d", h,m,s) ?
KarenAnne

2
@KarenAnne. Bu, örneğin "03:59:59" veya "3:59:59" isteyip istemediğinize bağlıdır.
Stephen Hosking

2
Zaman milisaniye cinsinden, saniyeyi 1000 ile çarpmanız gerekir
Apurva

5
yazar saniye değil, milisaniye hakkında sordu!
user924

59

Apache ortak müşterileri kullanıyorsanız:

DurationFormatUtils.formatDuration(timeInMS, "HH:mm:ss,SSS");

4
Kısayol:DurationFormatUtils.formatDurationHMS(timeInMS);
Aroniaina

@Jorgesys Neden eskimişler?
Piovezan

eski değiller.
Triton Man

26

Bunu kullandım:

String.format("%1$tH:%1$tM:%1$tS.%1$tL", millis);

Sınıf açıklamasına bakın Formatter .

2400 ms'lik girişi kullanan çalıştırılabilir örneğe bakın .


Çalışmıyor gibi görünüyor , 100, 1000, 1200 geçişi ile test ediyorum ve 05:30:00 , 05:30:01 , 05:30:01 olarak cevap veriyor .
CoDe

2
@CoDe, saat diliminiz için çalışır. UTC'den farklı bir saat diliminde olmalısınız. String.format()zaman dilimine bağlıdır . Bununla birlikte, ideal doğru cevap zaman diliminden bağımsız olmalıdır .
Derek Mahar

@CoDe, saat diliminize karşılık gelen ve UTC'den farklı olması gereken süreleri gösterir. String.format()zaman dilimine bağlıdır . Bununla birlikte, ideal doğru cevap zaman diliminden bağımsız olmalıdır .
Derek Mahar

25
// New date object from millis
Date date = new Date(millis);
// formattter 
SimpleDateFormat formatter= new SimpleDateFormat("HH:mm:ss.SSS");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
// Pass date object
String formatted = formatter.format(date );

1200 ms'lik girişi kullanan çalıştırılabilir örneğe bakın .


3
Bu, bir günden fazla süre için yanlış sonuçlar doğuracaktır. Saat sayısını 23'ten 0'a kaydırır, ki bu muhtemelen burada istenmez.
Kenster

Dostum yok ... Bence yine de aynı şekilde çalışır. bugün deneyin denemek
Vinay Lodha

1
SimpleDateFormat sdf = yeni SimpleDateFormat ("ss: dd aa"); birisi saat
12:00


10

4 uygulama için test sonuçları

Büyük veriler için çok fazla biçimlendirme yapmak zorunda kalmak, en iyi performansa ihtiyaç duyduğundan, (şaşırtıcı) sonuçlar şunlardır:

için (int i = 0; i <1000000; i ++) {FUNCTION_CALL}

süreler:

  • kombinasyon Biçimlendirici: 196 Biçimlendirici milis
  • formatSüre: 272 milis
  • apacheFormat: 754 milis
  • formatTimeUnit: 2216 milis

    public static String apacheFormat(long millis) throws ParseException {
        return DurationFormatUtils.formatDuration(millis, "HH:mm:ss");
    }
    
    public static String formatTimeUnit(long millis) throws ParseException {
    String formatted = String.format(
            "%02d:%02d:%02d",
            TimeUnit.MILLISECONDS.toHours(millis),
            TimeUnit.MILLISECONDS.toMinutes(millis)
                    - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
            TimeUnit.MILLISECONDS.toSeconds(millis)
                    - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
        return formatted;
    }
    
    public static String formatDuration(final long millis) {
        long seconds = (millis / 1000) % 60;
        long minutes = (millis / (1000 * 60)) % 60;
        long hours = millis / (1000 * 60 * 60);
    
        StringBuilder b = new StringBuilder();
        b.append(hours == 0 ? "00" : hours < 10 ? String.valueOf("0" + hours) : 
        String.valueOf(hours));
        b.append(":");
        b.append(minutes == 0 ? "00" : minutes < 10 ? String.valueOf("0" + minutes) :     
        String.valueOf(minutes));
        b.append(":");
        b.append(seconds == 0 ? "00" : seconds < 10 ? String.valueOf("0" + seconds) : 
        String.valueOf(seconds));
        return b.toString();
    }
    
    public static String combinationFormatter(final long millis) {
        long seconds = TimeUnit.MILLISECONDS.toSeconds(millis)
                - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis));
        long minutes = TimeUnit.MILLISECONDS.toMinutes(millis)
                - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis));
        long hours = TimeUnit.MILLISECONDS.toHours(millis);
    
        StringBuilder b = new StringBuilder();
        b.append(hours == 0 ? "00" : hours < 10 ? String.valueOf("0" + hours) : 
        String.valueOf(hours));
        b.append(":");
        b.append(minutes == 0 ? "00" : minutes < 10 ? String.valueOf("0" + minutes) : 
        String.valueOf(minutes));
            b.append(":");
        b.append(seconds == 0 ? "00" : seconds < 10 ? String.valueOf("0" + seconds) : 
        String.valueOf(seconds));
        return b.toString(); 
     }

bu gibi metrikler ne kadar güvenilir? Süreci gerçekten hiç anlamadım.
mre

Arka arkaya binlerce nesnenin yaratıldığı durumumda, bu testin oldukça faydalı olduğunu düşünüyorum. Tamam, yalnızca bazı dizeler ayarlamakla kalmaz, aynı zamanda bir alanı biçimlendirilmiş dize içeren nesneler oluşturur.
MariusA

marius kullanmak için belaya gittim StringBuildersonra "0" + "tür" harabeleri "kullanarak hata yapmak. @mre JVM'nin GC'si, çok sayıda kısa ömürlü nesne tahsis etme ve toplama konusunda son derece iyidir, orada endişelenmenize gerek yoktur. String.formatBaşa çıkmak için hiçbir sıfır sıfır mantığı olmadan gittim .
escape-llc

7

bu benim için çalıştı, kotlin ile

fun formatToDigitalClock(miliSeconds: Long): String {
        val hours = TimeUnit.MILLISECONDS.toHours(miliSeconds).toInt() % 24
        val minutes = TimeUnit.MILLISECONDS.toMinutes(miliSeconds).toInt() % 60
        val seconds = TimeUnit.MILLISECONDS.toSeconds(miliSeconds).toInt() % 60
        return when {
            hours > 0 -> String.format("%d:%02d:%02d", hours, minutes, seconds)
            minutes > 0 -> String.format("%02d:%02d", minutes, seconds)
            seconds > 0 -> String.format("00:%02d", seconds)
            else -> {
                "00:00"
            }
        }
    }

Benim için mükemmel çalıştı. Sıfır saat işlediğinden bu en iyi yanıt olmalıdır
vNext

6

Bohemian'ın cevabına göre, bilinen bir değeri bulmak için TimeUnit kullanmamız gerekmiyor. Çok daha uygun kod

String hms = String.format("%02d:%02d:%02d", millisLeft/(3600*1000),
                    millisLeft/(60*1000) % 60,
                    millisLeft/1000 % 60);

Umarım yardımcı olur


Cevabınızı en çok beğenin! Sadece basit matematik. Btw benim durumumda milisaniyeyi sonuna ekledim, millisLeft%1000/10böylece formatı aldıkhour:minutes:seconds:milliseconds
Lê Quang Duy

@ LêQuang 01: 24: 51,123 gibi 3 basamaklı milisaniyeye ihtiyacım var ama sonunda 3'ü doğracak ne yapmalıyım?
naanu

@naanu sadece kullanınmillisLeft%1000
Lê Quang Duy

6
 public String millsToDateFormat(long mills) {

    Date date = new Date(mills);
    DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
    String dateFormatted = formatter.format(date);
    return dateFormatted; //note that it will give you the time in GMT+0
}

Yanıt saat dilimine bağlıdır; bu, farklı saat dilimlerinde çalıştırıldığında sonucun farklı olacağı anlamına gelir.
Derek Mahar

6

Java 9

    Duration timeLeft = Duration.ofMillis(3600000);
    String hhmmss = String.format("%02d:%02d:%02d", 
            timeLeft.toHours(), timeLeft.toMinutesPart(), timeLeft.toSecondsPart());
    System.out.println(hhmmss);

Bu yazdırır:

01:00:00

Kütüphane yöntemlerinin sizin için gereken dönüşümleri yapmasına izin veriyorsunuz. java.time, modern Java tarih ve saat API'sı veya daha doğrusu, Durationsınıfı bunu daha zarif ve hataya daha az eğilimli bir şekilde yaparTimeUnit .

toMinutesPartvetoSecondsPart yöntemleri Java 9'da tanıtıldı.

Java 6, 7 ve 8

    long hours = timeLeft.toHours();
    timeLeft = timeLeft.minusHours(hours);
    long minutes = timeLeft.toMinutes();
    timeLeft = timeLeft.minusMinutes(minutes);
    long seconds = timeLeft.toSeconds();
    String hhmmss = String.format("%02d:%02d:%02d", hours, minutes, seconds);
    System.out.println(hhmmss);

Çıktı yukarıdaki ile aynıdır.

Soru: Java 6 ve 7'de bu nasıl çalışır?

  • Java 8 ve sonraki sürümlerde ve daha yeni Android cihazlarda (API düzey 26'dan söylendi) java.time yerleşik olarak gelir.
  • Java 6 ve 7'de modern sınıfların backport'u ThreeTen Backport'u edinin (JSR 310 için ThreeTen; alttaki bağlantılara bakın).
  • (Daha eski) Android cihazlarında ThreeTen Backport'un Android sürümünü kullanın. Buna ThreeTenABP deniyor. Ve tarih ve saat sınıflarını org.threeten.bpalt paketlerle aldığınızdan emin olun .

Bağlantılar


5

Aşağıdaki kod dönüşümü her iki şekilde de yapıyor

23: 59: 58: 999 ila 86398999

ve sonra

86398999 ila 23: 59: 58: 999


import java.util.concurrent.TimeUnit;

public class TimeUtility {

    public static void main(String[] args) {

        long currentDateTime = System.currentTimeMillis();

        String strTest = "23:59:58:999";
        System.out.println(strTest);

        long l = strToMilli(strTest);
        System.out.println(l);
        l += 1;
        String str = milliToString(l);
        System.out.println(str);
    }

    /**
     * convert a time string into the equivalent long milliseconds
     *
     * @param strTime string fomratted as HH:MM:SS:MSMS i.e. "23:59:59:999"
     * @return long integer like 86399999
     */
    public static long strToMilli(String strTime) {
        long retVal = 0;
        String hour = strTime.substring(0, 2);
        String min = strTime.substring(3, 5);
        String sec = strTime.substring(6, 8);
        String milli = strTime.substring(9, 12);
        int h = Integer.parseInt(hour);
        int m = Integer.parseInt(min);
        int s = Integer.parseInt(sec);
        int ms = Integer.parseInt(milli);

        String strDebug = String.format("%02d:%02d:%02d:%03d", h, m, s, ms);
        //System.out.println(strDebug);
        long lH = h * 60 * 60 * 1000;
        long lM = m * 60 * 1000;
        long lS = s * 1000;

        retVal = lH + lM + lS + ms;
        return retVal;
    }

    /**
     * convert time in milliseconds to the corresponding string, in case of day
     * rollover start from scratch 23:59:59:999 + 1 = 00:00:00:000
     *
     * @param millis the number of milliseconds corresponding to tim i.e.
     *               34137999 that can be obtained as follows;
     *               <p>
     *               long lH = h * 60 * 60 * 1000; //hour to milli
     *               <p>
     *               long lM = m * 60 * 1000; // minute to milli
     *               <p>
     *               long lS = s * 1000; //seconds to milli
     *               <p>
     *               millis = lH + lM + lS + ms;
     * @return a string formatted as HH:MM:SS:MSMS i.e. "23:59:59:999"
     */
    private static String milliToString(long millis) {

        long hrs = TimeUnit.MILLISECONDS.toHours(millis) % 24;
        long min = TimeUnit.MILLISECONDS.toMinutes(millis) % 60;
        long sec = TimeUnit.MILLISECONDS.toSeconds(millis) % 60;
        //millis = millis - (hrs * 60 * 60 * 1000); //alternative way
        //millis = millis - (min * 60 * 1000);
        //millis = millis - (sec * 1000);
        //long mls = millis ;
        long mls = millis % 1000;
        String toRet = String.format("%02d:%02d:%02d:%03d", hrs, min, sec, mls);
        //System.out.println(toRet);
        return toRet;
    }
}

Bu çözümü iptal ettim. Sn ve mls arasına bir nokta koymanız yeterli. Ve Java'da zaman ve tarih işlemenin neden çok zor olduğunu bilmiyorum. En çok kullanılan fonksiyonlar zaten mevcut olmalı ve sınıfın bir parçası olmalıdır.
Baruch Atta

5
        String string = String.format("%02d:%02d:%02d.%03d",
            TimeUnit.MILLISECONDS.toHours(millisecend), TimeUnit.MILLISECONDS.toMinutes(millisecend) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisecend)),
            TimeUnit.MILLISECONDS.toSeconds(millisecend) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisecend)), millisecend - TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(millisecend)));

Biçim: 00: 00: 00.000

Örnek: 615605 Millisecend

00: 10: 15,605


5

Doğru olarak işaretlenen cevabın küçük bir hatası var,

String myTime = String.format("%02d:%02d:%02d",
            TimeUnit.MILLISECONDS.toHours(millis),
            TimeUnit.MILLISECONDS.toMinutes(millis) -
                    TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), // The change is in this line
            TimeUnit.MILLISECONDS.toSeconds(millis) -
                    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));

örneğin bu elde edeceğim değerin bir örneğidir:

417474:44:19

Bu doğru formatı almak için bir çözümdür:

String myTime =  String.format("%02d:%02d:%02d",
                //Hours
                TimeUnit.MILLISECONDS.toHours(millis) -
                        TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(millis)),
                //Minutes
                TimeUnit.MILLISECONDS.toMinutes(millis) -
                        TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
                //Seconds
                TimeUnit.MILLISECONDS.toSeconds(millis) -
                        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));

sonuç olarak doğru bir biçim elde etmek:

18:44:19

biçimi almak için diğer seçenek hh:mm:sssadece:

   Date myDate = new Date(timeinMillis);
   SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
   String myTime = formatter.format(myDate);

4

İlk cevapta gösterildiği gibi denedim. İşe yarıyor ama eksi beni karışıklığa soktu. Groovy tarafından cevabım:

import static java.util.concurrent.TimeUnit.*

...

private static String formatElapsedTime(long millis) {

    int hrs = MILLISECONDS.toHours(millis) % 24
    int min = MILLISECONDS.toMinutes(millis) % 60
    int sec = MILLISECONDS.toSeconds(millis) % 60
    int mls = millis % 1000

    sprintf( '%02d:%02d:%02d (%03d)', [hrs, min, sec, mls])
}

3

Kotlin için

val hours = String.format("%02d", TimeUnit.MILLISECONDS.toHours(milSecs))
val minutes = String.format("%02d",
                        TimeUnit.MILLISECONDS.toMinutes(milSecs) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(milSecs)))
val seconds = String.format("%02d",
                        TimeUnit.MILLISECONDS.toSeconds(milSecs) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milSecs)))

nerede, milSecsmilisaniye


1

Bunun gibi bir şey deneyebilirsiniz:

public String getElapsedTimeHoursMinutesSecondsString() {       
     long elapsedTime = getElapsedTime();  
     String format = String.format("%%0%dd", 2);  
     elapsedTime = elapsedTime / 1000;  
     String seconds = String.format(format, elapsedTime % 60);  
     String minutes = String.format(format, (elapsedTime % 3600) / 60);  
     String hours = String.format(format, elapsedTime / 3600);  
     String time =  hours + ":" + minutes + ":" + seconds;  
     return time;  
 }  

milisaniyeyi bir zaman değerine dönüştürmek için

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.