如何格式化Java中的时间间隔?

时间:2012-04-13 15:47:01

标签: java format intervals

我创建了J2SE应用程序,这个应用程序需要在几毫秒内格式化为一个字符串,表示这两次之间的间隔。

long time1 = 1334331041677L; //Fri Apr 13 17:30:41 CEST 2012
long time2 = time1+1000*60*2; //Fri Apr 13 17:32:41 CEST 2012

我希望得到类似“00:02:00”的内容。这很简单,但我需要格式化从几秒到几年很长的间隔 - 所以库应该处理它。理想情况下,这个库是否可以根据国家的habbits(如果有的话)格式化间隔。

我已经搜索了问题和答案,我的解决方案可能是来自Apache Commons的Jodatime或Lang库。你能否提供一些建议,哪些图书馆以更好的方式解决了我的要求?提前谢谢。

5 个答案:

答案 0 :(得分:1)

PeriodFormat中的{p> Joda Time 可能你想要什么 - 但你需要仔细考虑非常关于如何格式化值超过一天。请记住,数月和数年的长度各不相同 - 如果您愿意将最大的单位作为一天,那么这可能会让事情变得简单。

您还应该了解Joda Time在Period(可能包括“月”之类)和Duration之间的差异,这是一个固定的毫秒数。两个触摸之间的标准化恰好是上面提到的问题:)基本上,你应该弄清楚你是否对两个瞬间之间的经过时间差异感兴趣,或者“日历”的差异两个本地日期/时间值之间的时间。例如,在特定时区的特定日期的午夜和凌晨2点之间可能是1小时,2小时或3小时的经过时间......

答案 1 :(得分:1)

您可以使用标准Java Calendar,间隔最多一天(24小时)。尽管......不可能在更长的时期(天,年)使用这个技巧。

long start = System.currentTimeMillis();
/*
 * perform the measured activity here,
 * let's say it will take 2 minutes 5 seconds => 125 seconds => 125000ms
 */
Thread.sleep(125 * 1000);
long stop = System.currentTimeMillis();
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
c.setTimeInMillis(c.getTimeInMillis() + (stop - start));
DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS");
System.out.println(df.format(c.getTime()));

答案 2 :(得分:0)

如果我理解正确,以下(使用Joda Time)应该有帮助

import org.joda.time.DateTime;
import org.joda.time.Period;

private String formatDuration(DateTime dt1, DateTime dt2) {
  Period period = new Period(dt1, dt2);
  String str = String.format("%s:%02d:%02d:%02d:%02d:%02d", 
    period.getYears(), period.getMonths(), period.getDays(), 
    period.getHours(), period.getMinutes(), period.getSeconds());
    // Ignoring milliseconds

  String[] tokens = str.split(":");
  boolean currNonZero = false, flag = false, isFirst = true;
  int ctr = 0, pos = 0;
  StringBuilder sb = new StringBuilder();
  for (String token : tokens) {
    pos++;
    int val = Integer.parseInt(token);
    currNonZero = (val > 0);
    if ((ctr < 3 && (flag || currNonZero)) || (ctr == 0 && pos > 3)) {
      if (isFirst) { isFirst = false; }
      else { sb.append(":"); }
      sb.append(token);
      flag = (++ctr < 3);
    }
  }

  return sb.toString();  
}

一些测试,

DateTime dt1 = new DateTime(2012, 1, 1, 8, 3, 5, 0);
DateTime dt2 = new DateTime(2012, 1, 2, 9, 5, 6, 0);
DateTime dt3 = new DateTime(2012, 2, 3, 11, 3, 5, 0);
DateTime dt4 = new DateTime(2012, 2, 3, 11, 3, 10, 0);
DateTime dt5 = new DateTime(2012, 2, 3, 11, 3, 10, 5); //5 millis away from dt4

formatDuration(dt1, dt2); // Returns "01:01:01"
formatDuration(dt1, dt3); // Returns "01:02:03"
formatDuration(dt3, dt4); // Returns "00:00:05"
formatDuration(dt4, dt5); // Returns "00:00:00"

答案 3 :(得分:0)

根据this answer,这是格式化已用时间的最有效方法:

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

答案 4 :(得分:0)

详细答案:https://stackoverflow.com/a/39600534/5330578

经过时间少于24小时的简单格式。超过24小时,代码将仅显示第二天的小时数,并且不会将经过的日期添加到小时。

public static String formatElapsedTime(long milliseconds) {

    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

    return sdf.format(milliseconds);
}