Java의 지속 시간을 포맷하는 방법은 무엇입니까? (예 : 형식 H : MM : SS)

StackOverflow https://stackoverflow.com/questions/266825

  •  06-07-2019
  •  | 
  •  

문제

h : mm : ss와 같은 패턴을 사용하여 몇 초 만에 지속 시간을 포맷하고 싶습니다. Java의 현재 유틸리티는 시간을 형성하지만 지속 시간을 형성하도록 설계되었습니다.

도움이 되었습니까?

해결책

8 세 이전에 Java 버전을 사용하는 경우 사용할 수 있습니다. 조다 시간 그리고 PeriodFormatter. 실제로 지속 시간이 있다면 (예 : 달력 시스템을 참조하지 않고 시간이 지남에 따라) 사용해야합니다. Duration 대부분의 경우 - 전화 할 수 있습니다 toPeriod (무엇이든 지정합니다 PeriodType 25 시간이 1 일, 1 시간이되는지 여부를 반영하고 싶습니다. Period 포맷 할 수 있습니다.

Java 8 이상을 사용하는 경우 : 일반적으로 사용하는 것이 좋습니다. java.time.Duration 지속 시간을 나타냅니다. 그런 다음 전화 할 수 있습니다 getSeconds() 또는 필요한 경우 Bobince의 답변에 따라 표준 문자열 서식에 대한 정수를 얻는 것과 같습니다. 하나의 출력 문자열의 음수 부호. 그래서 :

public static String formatDuration(Duration duration) {
    long seconds = duration.getSeconds();
    long absSeconds = Math.abs(seconds);
    String positive = String.format(
        "%d:%02d:%02d",
        absSeconds / 3600,
        (absSeconds % 3600) / 60,
        absSeconds % 60);
    return seconds < 0 ? "-" + positive : positive;
}

이 방법으로 포맷합니다 합리적으로 성가신 매뉴얼이라면 간단합니다. 을 위한 구문 분석 일반적으로 더 어려운 문제가됩니다 ... 물론 원한다면 Java 8에서도 Joda Time을 사용할 수 있습니다.

다른 팁

라이브러리에서 드래그하고 싶지 않다면 포피터 또는 관련 단축키를 사용하여 스스로를 수행 할 수있을만큼 간단합니다. 주어진 정수 수의 초 S :

  String.format("%d:%02d:%02d", s / 3600, (s % 3600) / 60, (s % 60));

나는 Apache Common 's를 사용합니다 durationformatutils 그렇게 :

DurationFormatUtils.formatDuration(millis, "**H:mm:ss**", true);
long duration = 4 * 60 * 60 * 1000;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault());
log.info("Duration: " + sdf.format(new Date(duration - TimeZone.getDefault().getRawOffset())));

Java 9에서는 더 쉬울 것입니다. a Duration 여전히 형성 할 수는 없지만 (내가 아는 것), 시간, 몇 분 및 초를 얻는 방법이 추가되어 작업을 좀 더 간단하게 만듭니다.

        Duration diff = // ...;
        String hms = String.format("%d:%02d:%02d", 
                                   diff.toHoursPart(),
                                   diff.toMinutesPart(), 
                                   diff.toSecondsPart());

이것은 일종의 해킹 일지 모르지만 Java 8 's를 사용하여 이것을 달성하는 데 구부러진다면 좋은 해결책입니다. java.time:

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.UnsupportedTemporalTypeException;

public class TemporalDuration implements TemporalAccessor {
    private static final Temporal BASE_TEMPORAL = LocalDateTime.of(0, 1, 1, 0, 0);

    private final Duration duration;
    private final Temporal temporal;

    public TemporalDuration(Duration duration) {
        this.duration = duration;
        this.temporal = duration.addTo(BASE_TEMPORAL);
    }

    @Override
    public boolean isSupported(TemporalField field) {
        if(!temporal.isSupported(field)) return false;
        long value = temporal.getLong(field)-BASE_TEMPORAL.getLong(field);
        return value!=0L;
    }

    @Override
    public long getLong(TemporalField field) {
        if(!isSupported(field)) throw new UnsupportedTemporalTypeException(new StringBuilder().append(field.toString()).toString());
        return temporal.getLong(field)-BASE_TEMPORAL.getLong(field);
    }

    public Duration getDuration() {
        return duration;
    }

    @Override
    public String toString() {
        return dtf.format(this);
    }

    private static final DateTimeFormatter dtf = new DateTimeFormatterBuilder()
            .optionalStart()//second
            .optionalStart()//minute
            .optionalStart()//hour
            .optionalStart()//day
            .optionalStart()//month
            .optionalStart()//year
            .appendValue(ChronoField.YEAR).appendLiteral(" Years ").optionalEnd()
            .appendValue(ChronoField.MONTH_OF_YEAR).appendLiteral(" Months ").optionalEnd()
            .appendValue(ChronoField.DAY_OF_MONTH).appendLiteral(" Days ").optionalEnd()
            .appendValue(ChronoField.HOUR_OF_DAY).appendLiteral(" Hours ").optionalEnd()
            .appendValue(ChronoField.MINUTE_OF_HOUR).appendLiteral(" Minutes ").optionalEnd()
            .appendValue(ChronoField.SECOND_OF_MINUTE).appendLiteral(" Seconds").optionalEnd()
            .toFormatter();

}

이것은 Java 7의 새로운 기능 중 하나가 될 것입니다.

JSR-310

다음은 지속 시간을 포맷하는 방법이 하나 더 있습니다. 이 샘플은 양의 지속 시간과 음성 지속 시간을 긍정적 인 기간으로 보여줍니다.

import static java.time.temporal.ChronoUnit.DAYS;
import static java.time.temporal.ChronoUnit.HOURS;
import static java.time.temporal.ChronoUnit.MINUTES;
import static java.time.temporal.ChronoUnit.SECONDS;

import java.time.Duration;

public class DurationSample {
    public static void main(String[] args) {
        //Let's say duration of 2days 3hours 12minutes and 46seconds
        Duration d = Duration.ZERO.plus(2, DAYS).plus(3, HOURS).plus(12, MINUTES).plus(46, SECONDS);

        //in case of negative duration
        if(d.isNegative()) d = d.negated();

        //format DAYS HOURS MINUTES SECONDS 
        System.out.printf("Total duration is %sdays %shrs %smin %ssec.\n", d.toDays(), d.toHours() % 24, d.toMinutes() % 60, d.getSeconds() % 60);

        //or format HOURS MINUTES SECONDS 
        System.out.printf("Or total duration is %shrs %smin %sec.\n", d.toHours(), d.toMinutes() % 60, d.getSeconds() % 60);

        //or format MINUTES SECONDS 
        System.out.printf("Or total duration is %smin %ssec.\n", d.toMinutes(), d.getSeconds() % 60);

        //or format SECONDS only 
        System.out.printf("Or total duration is %ssec.\n", d.getSeconds());
    }
}

이것은 작동 옵션입니다.

public static String showDuration(LocalTime otherTime){          
    DateTimeFormatter df = DateTimeFormatter.ISO_LOCAL_TIME;
    LocalTime now = LocalTime.now();
    System.out.println("now: " + now);
    System.out.println("otherTime: " + otherTime);
    System.out.println("otherTime: " + otherTime.format(df));

    Duration span = Duration.between(otherTime, now);
    LocalTime fTime = LocalTime.ofNanoOfDay(span.toNanos());
    String output = fTime.format(df);

    System.out.println(output);
    return output;
}

메소드를 호출하십시오

System.out.println(showDuration(LocalTime.of(9, 30, 0, 0)));

다음과 같은 것을 생성합니다.

otherTime: 09:30
otherTime: 09:30:00
11:31:27.463
11:31:27.463

+h : mm : ss 또는 +h : mm : ss.ssss를 반환하는 다음 함수는 어떻습니까?

public static String formatInterval(final long interval, boolean millisecs )
{
    final long hr = TimeUnit.MILLISECONDS.toHours(interval);
    final long min = TimeUnit.MILLISECONDS.toMinutes(interval) %60;
    final long sec = TimeUnit.MILLISECONDS.toSeconds(interval) %60;
    final long ms = TimeUnit.MILLISECONDS.toMillis(interval) %1000;
    if( millisecs ) {
        return String.format("%02d:%02d:%02d.%03d", hr, min, sec, ms);
    } else {
        return String.format("%02d:%02d:%02d", hr, min, sec );
    }
}
String duration(Temporal from, Temporal to) {
    final StringBuilder builder = new StringBuilder();
    for (ChronoUnit unit : new ChronoUnit[]{YEARS, MONTHS, WEEKS, DAYS, HOURS, MINUTES, SECONDS}) {
        long amount = unit.between(from, to);
        if (amount == 0) {
            continue;
        }
        builder.append(' ')
                .append(amount)
                .append(' ')
                .append(unit.name().toLowerCase());
        from = from.plus(amount, unit);
    }
    return builder.toString().trim();
}

이 답변은 만 사용합니다 Duration Java 8과 함께 방법과 작동 :

public static String format(Duration d) {
    long days = d.toDays();
    d = d.minusDays(days);
    long hours = d.toHours();
    d = d.minusHours(hours);
    long minutes = d.toMinutes();
    d = d.minusMinutes(minutes);
    long seconds = d.getSeconds() ;
    return 
            (days ==  0?"":days+" jours,")+ 
            (hours == 0?"":hours+" heures,")+ 
            (minutes ==  0?"":minutes+" minutes,")+ 
            (seconds == 0?"":seconds+" secondes,");
}

최소한 24 시간 미만의 지속 시간에 대해 상당히 간단하고 (IMO) 우아한 접근 방식이 있습니다.

DateTimeFormatter.ISO_LOCAL_TIME.format(value.addTo(LocalTime.of(0, 0)))

포맷터는 형식에 시간적 객체가 필요하므로 00:00 (예 : 자정)의 로컬 타임에 지속 시간을 추가하여 하나를 만들 수 있습니다. 이렇게하면 자정에서 그 시간까지의 지속 시간을 나타내는 로컬 타임이 제공되며, 이는 표준 HH : MM : SS 표기법에서 쉽게 형식화 할 수 있습니다. 이는 외부 라이브러리가 필요하지 않다는 장점이 있으며 Java.Time 라이브러리를 사용하여 시간, 분 및 초를 수동으로 계산하는 대신 계산을 수행합니다.

내 도서관 Time4J 패턴 기반 솔루션을 제공합니다 (유사 Apache DurationFormatUtils, 그러나 더 유연함) :

Duration<ClockUnit> duration =
    Duration.of(-573421, ClockUnit.SECONDS) // input in seconds only
    .with(Duration.STD_CLOCK_PERIOD); // performs normalization to h:mm:ss-structure
String fs = Duration.formatter(ClockUnit.class, "+##h:mm:ss").format(duration);
System.out.println(fs); // output => -159:17:01

이 코드는 시간 오버플로 및 부호 처리를 처리 할 수있는 기능을 보여줍니다. Duration-Formatter의 API도 참조하십시오. 패턴을 기반으로합니다.

Scala에서는 YourBestbet의 솔루션을 구축하지만 단순화했습니다.

def prettyDuration(seconds: Long): List[String] = seconds match {
  case t if t < 60      => List(s"${t} seconds")
  case t if t < 3600    => s"${t / 60} minutes" :: prettyDuration(t % 60)
  case t if t < 3600*24 => s"${t / 3600} hours" :: prettyDuration(t % 3600)
  case t                => s"${t / (3600*24)} days" :: prettyDuration(t % (3600*24))
}

val dur = prettyDuration(12345).mkString(", ") // => 3 hours, 25 minutes, 45 seconds

스칼라에서는 라이브러리가 필요하지 않습니다.

def prettyDuration(str:List[String],seconds:Long):List[String]={
  seconds match {
    case t if t < 60 => str:::List(s"${t} seconds")
    case t if (t >= 60 && t< 3600 ) => List(s"${t / 60} minutes"):::prettyDuration(str, t%60)
    case t if (t >= 3600 && t< 3600*24 ) => List(s"${t / 3600} hours"):::prettyDuration(str, t%3600)
    case t if (t>= 3600*24 ) => List(s"${t / (3600*24)} days"):::prettyDuration(str, t%(3600*24))
  }
}
val dur = prettyDuration(List.empty[String], 12345).mkString("")

나는 이것을 보지 못했기 때문에 그것을 추가 할 것이라고 생각했다.

Date started=new Date();
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
task
long duration=new Date().getTime()-started.getTime();
System.out.println(format.format(new Date(duration));

그것은 24 시간 동안 만 작동하지만 그것이 내가 보통 기간 동안 원하는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top