Java에서 밀리 초를 "X 분, x 초"로 변환하는 방법은 무엇입니까?


572

System.currentTimeMillis()사용자가 프로그램에서 무언가를 시작할 때 사용하는 시간을 기록하고 싶습니다 . 완료되면 변수 에서 전류 System.currentTimeMillis()를 빼고 start"XX 시간, XX 분, XX 초"또는 "XX 분, XX 초"와 같은 사람이 읽을 수있는 형식을 사용하여 경과 된 시간을 보여주고 싶습니다. 한 시간 동안 누군가를 데려 가지 않을 것입니다.

가장 좋은 방법은 무엇입니까?


5
한 시간 이상 걸리더라도 여전히 다음과 같은 것을 인쇄 할 수 있습니다. 90 분, 53 초
피터 로리

1
내 대답은 육년 늦게 온다하지만 난 그것을 허용 것보다 더 일반적인 생각 : stackoverflow.com/a/35082080/82609
세바스티앙 Lorber

답변:


1228

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

참고 : TimeUnitJava 1.5 사양의 일부이지만 toMinutesJava 1.6부터 추가되었습니다.

값 0-9에 선행 0을 추가하려면 다음을 수행하십시오.

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

지원되지 TimeUnit않거나 toMinutes지원되지 않는 경우 (예 : API 버전 9 이전의 Android에서) 다음 방정식을 사용하십시오.

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

7
분을 빼는 대신 mod 60을 사용하는 것이 좋습니다. 더 깨끗해 보입니다. 그러나, 그렇게하려면 1 분 = 60 초임을 알아야합니다 ... =)
Per Alexandersson Per

2
@AndreasDietrich SimpleDateFormat은 시대에서 날짜 만 반환하므로 시차에 대해서는 작동하지 않습니다!
Muhammad Babar

5
int hours = (int) ((milliseconds / (1000*60*60)) % 24)이 작동하지 않습니다! 대신 다음과 같이되어야합니다int hours = (int) (milliseconds / (1000*60*60)) ;
Muhammad Babar

5
누군가 비디오 파일 형식을 원한다면 ( h : mm : ss ) :String.format("%01d:%02d:%02d", hours, minutes, seconds);
kazy

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
Daniel

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

78
long time = 1536259;

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

인쇄물:

25 : 36 : 259


1
나는 단순함이 없다면 위의 접근법이 가장 좋습니다! 우리는 시간과 기간을 다루기 때문에 일반적으로 Joda를 사용합니다. 예를 들어 두 개의 DateTime이있는 경우 각각 시작 및 종료하십시오.Duration dur = new Duration(start, end); long millis = dur.getMillis();
TechTrip

1
Joda 포맷터를 사용하는 두 가지 방법에 주목해야합니다. 테마의 첫 변형 : DateTimeFormat.forPattern("mm:ss:SSS").print(new DateTime(time)); 또는 지속 시간을 Joda를 사용하여 자동으로 인쇄 할 수있는 기간으로 변환하십시오 PeriodFormatter. ISO 연대기가 아닌 경우 변환의 정밀도가 떨어질 수 있습니다. 변수가 나타내는 Duration을 가정합니다 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로 설정하면 1 시간보다 짧은 모든 지속 시간에서 시간 부분이 0 대신 12가됩니다.
Episodex

2
시간대가 유일한 문제는 아닙니다.이 답변은 오도의 소지가 있으며 Java 초보자를 심각하게 혼란스럽게 할 수 있습니다. 중복 외부 브래킷을 무시하더라도 OP는 지속 시간 (ms 단위로 측정 된 두 시점 간의 차이) 을 제시하는 방법을 묻습니다 . 그 지속 시간을 "시간"이라고 부르고 1970 년 1 월 1 일 이후로 작은 구성 요소를 포맷하기 위해 오프셋으로 취급하는 것은 단지 잘못된 imo입니다. 또한 이 답변으로 3 년 전에 이미 동일한 접근 방식이 제안되었습니다 (표준 시간대 문제에 대한 자세한 내용은 주석 참조).
Amos M. Carpenter

36

음 ... 1 초에 몇 밀리 초입니까? 그리고 잠시 후에? 사단은 그렇게 어렵지 않습니다.

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

시간, 일, 주, 월, 년, 수십 년 동안 계속하십시오.


2
실제로, 일광 절약 시간 (23 시간 또는 24 시간) 또는 윤년이 포함 된 경우 결과가 잘못되거나 직관적이지 않을 수 있으므로 1 시간 이상이 작업을 수행하는 것은 좋지 않습니다. "X는 1 년 / 월에 발생합니다"라는 메시지가 표시되면 날짜와 시간이 동일 할 것으로 예상됩니다.
Michael Borgwardt

5
System.currentTimeMillis ()는 DST에 영향을받지 않으므로 추가 또는 누락 된 시간으로 인해 혼동되지 않습니다. 두 특정 날짜 사이의 차이를 표시해야하는 경우 지정된 시간으로 Date 객체를 구성하고이 두 날짜 사이의 차이를 표시하는 것이 좋습니다.
Bombe

1
몇 주가 지나면 월 길이가 가변적이므로 정의되지 않습니다. 실제로 주어진 시간 기준을 기준으로 계산해야합니다.
PhiLho

31

Java 8에서 java.time 패키지 사용 :

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



1
(ANDROID) API 레벨 26 필요
누군가 어딘가에

1
@SomeoneSomewhere API 레벨 26 이하의 Android의 경우 백 포트 를 사용하려면 Android 프로젝트에서 ThreeTenABP를 사용하는 방법을 참조하십시오 .
Ole VV

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
나는 이런 종류의 것들을 포함하는 강력한 라이브러리가 있는지 스스로에게 물었다.
Lajcik

링크는 일반적으로 그다지 유용하지 않으므로 링크 사용 방법에 대한 예를 추가했습니다.
lepe

26

손으로 나누거나 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)));

Bombe에 의해 편집 :이 접근법은 작은 기간 (즉, 하루 미만) 동안 만 작동한다는 의견에 표시되었습니다.


와. 그것은 시간대에 의존하는 악의적 인 해킹입니다. 60 분의 배수가 아닌 시간대 오프셋이있을 때 무자비하게 중단 될 것입니다 (그리고 세계에서 성가신 30 분 오프셋 시간대가 몇 개 있습니다).
Bombe

또한 같은 이유로 형식 문자열에 시간을 포함하고 GMT + 0이 아닌 즉시 나쁜 상태가됩니다.
Bombe

우리는하다? 정말? 어디? 의심의 여지없이, 전에는 들어 본 적이 없습니다-고려할 새로운 함정 ;-)
Treb

예. Wikipedia에서“시간대 목록”을 확인하십시오 (예 : 네팔은 GMT + 05 : 45).
Bombe

2
cadrian, 이제 하루 미만의 기간 동안 만 작동합니다. 시간 수는 항상 0에서 23 사이입니다.
Bombe

21

HH : mm : ss와 같은 형식을 지정하려면 더 많은 정보를 추가하십시오.

0 <= HH <= 무한

0 <= mm <60

0 <= ss <60

이것을 사용하십시오 :

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

방금이 문제가 있었고 이것을 알아 냈습니다.


1
가장 좋은 답변은 여기입니다. 왜 모든 사람들이 일을 그렇게 복잡하게 만들고 싶어합니까? 이것은 간단한 수학입니다.
Lambart

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

설명:

%tT24 시간제 형식의 시간은 %tH:%tM:%tS입니다.

%tT또한 long을 입력으로 허용하므로을 만들 필요가 없습니다 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.

1
@ Nelda.techspiress 시간대의 오프셋입니다. TimeZone.getDefault().getRawOffset()답에 쓰여진대로 정확히 빼야 합니다.String.format("%tT", millis-TimeZone.getDefault().getRawOffset())
icza

그것을 처리했다. 설명해 주셔서 감사합니다.
Nelda.

8

조다 타임

사용 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마지막 줄에는 필요하지 않습니다 . 기본적으로 ISO 8601 Duration 문자열 Period::toString을 얻으려면 전화하십시오 .
Basil Bourque

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

API 9 이하의 Android

(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

짧은 시간 동안, 1 시간 미만인 것을 선호합니다 :

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

Java Formatter API ( docs.oracle.com/javase/8/docs/api/java/util/Formatter.html ) 를 사용하면 날짜 및 시간에 대한 많은 가능성이 있습니다 . 다음과 같은 경우 else 조건 결과를 얻을 수 있습니다. System.out.printf ( "% 1 $ tH : % 1 $ tM : % 1 $ tS % n", millis); 또는 System.out.printf ( "% 1 $ tT % n", millis);
호세 테페 디노

@JoseTepedino 그러나 당신은 0에서 23 시간 %tH 까지만 보여줍니다. 즉, 예를 들어 24 시간은 00, 25 시간으로 표시 되고 01... 일 동안 유효한 동일한 %tT날짜는 자동으로 삭제됩니다. 물론, 또한 일을 표시 할 수 있지만 내가 (다시 2011 년)이 쓴 내가 가진 문제에 대한 잔인한 [:-) 것
user85421

나는 그것이 실제로 하루 (24h)보다 적은 시간 동안 만 작동한다는 것을 알았습니다. 감사합니다.
호세 테페 디노

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

행복한 코딩 :)


System.currentTimeMillis ()가 long 값을 반환하므로 long 이이 함수에 더 적합하다고 가정합니다.
aprodan 2016 년

이것은 정확하지 않습니다. 출력을 확인 했습니까?
Jorgesys

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.Duration 이 지속 시간을 나타내는 가장 좋은 방법입니다.

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

시차가 1 시간 미만임을 알고 있다면 다음 코드를 사용할 수 있습니다.

    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.

항상 0을 사용하여 분과 초를 인쇄하여 항상 두 자리 숫자로 만들 02려면 관련 형식 지정자에 삽입 하십시오.

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

이제 우리는 예를 들어 가질 수 있습니다 0 hours, 39 mins, 09 seconds.


앞의 숫자가 0 일 때 시간 / 분 / 초를 제거하는 서식은 무엇입니까? 다른 조건으로 달성 할 수는 있지만 그러한 문자열 형식의 존재 또는 가까운 것이 무엇입니까?
Farid

1
아니, 미안, @FARID, 당신이 필요합니다 if- else가.
Ole VV

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의 답변을 수정하고 plurlization 지원을 추가했습니다. 필요하지 않기 때문에 몇 초가 걸렸지 만 필요한 경우 다시 추가해도됩니다.

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

나는 이것을 다른 대답으로 다루었 지만 당신은 할 수 있습니다 :

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

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