밀리 초를“hh : mm : ss”형식으로 변환하는 방법은 무엇입니까?


184

혼란 스러워요. 스레드를 우연히 만난 후 형식이있는 카운트 다운 타이머를 형식화하는 방법을 알아 내려고했습니다 hh:mm:ss.

여기 내 시도가 있습니다-

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

따라서와 같은 값을 시도하면 3600000ms얻을 수 01:59:00있습니다 01:00:00. 분명히 내 논리에 문제가 있지만 현재는 그것이 무엇인지 알 수 없습니다!

누구든지 도울 수 있습니까?

편집하다 -

고쳤다. 밀리 초를 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))));

문제는 이것이었다 TimeUnit.MINUTES.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)). 그것은이를 했어야 TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))대신.


1
3,600,000 밀리 초는 3,600 초 또는 60 분 또는 1 시간입니다. 그것은 안 00:59:59그것은해야한다, 01:00:00.
Borealid

답변:


355

당신은 정말 가까이 있었다 :

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

다음을 사용하여 millisseconds에 시간을 변환 한 대신 시간 .

BTW, 나는 당신의 TimeUnitAPI 사용을 좋아합니다 :)

테스트 코드는 다음과 같습니다.

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

산출:

01:00:00

빼기 대신 모듈러스 나누기를 사용하여 위의 코드를 크게 단순화 할 수 있음을 깨달았습니다.

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

TimeUnit모든 매직 값에 여전히 API를 사용하고 정확히 동일한 출력을 제공합니다.


2
Amen, 당신이 TimeUnit API를 사용하는 방식과 같은 :
Dheeraj Bhaskar

2
바퀴를 재발 명하는 것은 좋은 생각이 아닙니다! Triton Man의 답변이 더 나은 솔루션입니다.
محمدباقر

5
@ محمدباقر 그러나 다른 대답은 외부 라이브러리를 사용하는 반면 내 코드는 핵심 JDK 만 사용합니다. 요구 사항에 따라 다릅니다. 예를 들어 외부 라이브러리를 사용하지 못할 수도 있습니다. 다른 대답은 좋습니다.
보헤미안

2
@Ozuf 는 둘 다 0 일 경우 시간뿐만 아니라 분도 추가 .replaceAll("^00:", "")하거나 .replaceAll("^00:(00:)?", "")제거합니다.
보헤미안

2
당신이 얻을 @Ozuf "15:00""10:00:23"각각; 에 의해 입력 시작에 정합 된 일치로 인해 선행 0 만 제거됩니다 ^.
보헤미안

77

이를위한 일반적인 방법은 매우 간단합니다.

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, String.format("% 02 을 의미 d:%02d:%02d", h,m,s)했습니까?
KarenAnne

2
@KarenAnne. 예를 들어 "03:59:59"또는 "3:59:59"와 같이 원하는지 여부에 따라 다릅니다.
Stephen Hosking

2
시간은 밀리 초 단위입니다
Apurva

5
저자는 초가 아닌 밀리 초에 대해 물었습니다!
user924

59

아파치 커먼즈를 사용하는 경우 :

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

4
바로 가기 :DurationFormatUtils.formatDurationHMS(timeInMS);
Aroniaina

@Jorgesys 왜 쓸모 없습니까?
Piovezan

그들은 더 이상 사용되지 않습니다.
Triton Man

26

나는 이것을 사용했다 :

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

Formatter 클래스의 설명을 참조하십시오 .

2400ms의 입력을 사용하여 실행 가능한 예제 를 참조하십시오 .


작동하지 않는 것 같습니다 .100, 1000, 1200을 통과하여 테스트하고 05:30:00 , 05:30:01 , 05:30:01 응답 합니다.
CoDe

2
@CoDe, 시간대에 맞습니다. UTC와 다른 시간대에 있어야합니다. String.format()시간대에 따라 다릅니다 . 그러나 이상적인 정답은 표준 시간대와 독립적 이어야합니다 .
Derek Mahar

@CoDe, UTC와 다른 시간대에 해당하는 시간을 표시합니다. String.format()시간대에 따라 다릅니다 . 그러나 이상적인 정답은 표준 시간대와 독립적 이어야합니다 .
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 );

1200ms의 입력을 사용하여 실행 가능한 예제 를 참조하십시오 .


3
이것은 하루 이상의 시간에 대해 잘못된 결과를 생성합니다. 시간을 23에서 0으로 줄 바꿈하므로 바람직하지 않습니다.
Kenster 2016 년

친구 없음 ... 나는 여전히 똑같이 작동한다고 생각합니다. 오늘 날짜와 함께 시도
Vinay Lodha 2016 년

1
SimpleDateFormat sdf = 새로운 SimpleDateFormat ( "hh : mm aa"); 누군가 오전 / 오후 12시 형식으로 원하는 경우
Ajji


10

4 가지 구현에 대한 테스트 결과

방대한 데이터를 위해 많은 형식을 지정해야한다면 최고의 성능이 필요했기 때문에 다음과 같은 놀라운 결과가 나왔습니다.

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

기간 :

  • 조합 포맷 : 196 밀리
  • formatDuration : 272 밀리
  • 아파치 포맷 : 754 millis
  • formatTime 단위 : 2216 밀리

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

이와 같은 지표는 얼마나 신뢰할 수 있습니까? 나는 과정을 실제로 이해하지 못했습니다.
mre

수천 개의 객체가 연속적으로 생성되는 상황 에서이 테스트는 매우 유용하다고 생각합니다. 문자열 만 설정하는 것이 아니라 하나의 필드에 서식이 지정된 문자열을 가진 객체를 만드는 것이 좋습니다.
MariusA

@marius 당신은 사용에 어려움을 겪고 StringBuilder"0"+ 숫자를 사용하는 실수를합니다 "파멸". @mre JVM의 GC는 단기간에 많은 객체를 할당하고 수집하는 데 매우 유용하며 걱정할 필요가 없습니다. 나는 String.format처리 할 논리 가 없습니다.
escape-llc

6

보헤미안의 대답에 따르면 알려진 값을 찾기 위해 TimeUnit을 사용할 필요는 없습니다. 훨씬 더 최적의 코드는

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

그것이 도움이되기를 바랍니다.


당신의 대답처럼 가장! 간단한 수학. 내 경우에 Btw 나는 끝에 밀리 초를 추가하여 millisLeft%1000/10우리는 형식을 얻습니다hour:minutes:seconds:milliseconds
Lê Quang Duy

@ LêQuangDuy 나는 01 : 24 : 51,123 같은 3 자리 숫자로 밀리 초가 필요하지만 당신은 무엇을 해야할지 마침내 3을 자르고 있습니까?
naanu

@naanu 사용millisLeft%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
}

답변은 시간대에 따라 다르므로 다른 시간대에서 실행하면 결과가 달라집니다.
Derek Mahar

6

이것은 kotlin과 함께 나를 위해 일했습니다.

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

나를 위해 완벽하게 일했습니다. 제로 시간 처리하기 때문에 이것은 최선의 해답이 될한다
vNext

6

자바 9

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

인쇄합니다 :

01:00:00

라이브러리 메소드가 관련된 변환을 수행하도록 올바르게 수행하고 있습니다. java.time, 최신 Java 날짜 및 시간 API 또는 더 정확하게는 Duration클래스가보다 우아하고 오류가 덜 발생하는 방식으로 수행 TimeUnit합니다.

toMinutesParttoSecondsPart내가 사용하는 방법은 자바 (9)에 소개되었다.

자바 6, 7 및 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);

출력은 위와 동일합니다.

질문 : Java 6 및 7에서 어떻게 작동합니까?

  • Java 8 이상 및 최신 Android 장치에서 (API 레벨 26부터) java.time 가 내장되어 있습니다.
  • Java 6 및 7에서는 최신 클래스의 백 포트 인 ThreeTen Backport를 가져옵니다 (JSR 310의 경우 ThreeTen; 하단의 링크 참조).
  • (구형) Android에서는 Android 버전의 ThreeTen Backport를 사용합니다. 이름이 ThreeTenABP입니다. org.threeten.bp하위 패키지 를 사용 하여 날짜 및 시간 클래스를 가져와야합니다 .

연결


5

아래 코드는 양방향으로 변환을 수행합니다.

23 : 59 : 58 : 999 ~ 86398999

그리고보다

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

이 솔루션을 찬성했습니다. sec와 ml 사이에 점을 넣으십시오. 그리고 Java에서 시간과 날짜 처리가 왜 어려운지 모르겠습니다. 가장 많이 사용되는 기능은 이미 사용 가능하고 클래스의 일부 여야합니다.
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)));

형식 : 00 : 00 : 00.000

예 : 615605 Millisecend

00 : 10 : 15.605


5

정답으로 표시된 답변에는 약간의 실수가 있습니다.

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

예를 들어 이것은 내가 얻는 값의 예입니다.

417474:44:19

이것이 올바른 형식을 얻는 솔루션입니다.

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

결과적으로 올바른 형식을 얻는 것 :

18:44:19

형식을 얻는 다른 옵션 hh:mm:ss은 다음과 같습니다.

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

4

첫 번째 답변에 표시된 것처럼 시도했습니다. 그것은 효과가 있지만 마이너스로 인해 혼란에 빠졌습니다. Groovy의 대답 :

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

코 틀린

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

여기서 milSecs밀리 초입니다


1

글쎄, 당신은 이런 식으로 시도 할 수 있습니다 :

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

밀리 초를 시간 값으로 변환

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.