在Java 8 / jsr310中格式化持续时间

时间:2013-12-29 15:59:14

标签: java java-8 jodatime duration java-time

我正在将项目从Joda-Time过渡到java8的本地时间库,我遇到了麻烦。

我无法找到持续时间的格式化程序。我希望有一个自定义字符串格式,例如 HHH + MM ,其中75小时和15分钟的持续时间格式为“75 + 15”

通过转换为句点并使用PeriodFormatter,这很容易用Joda-Time,但我无法在Java8中找到这种类型的类。我错过了什么吗?

5 个答案:

答案 0 :(得分:25)

Java 9及更高版本:Duration::to…Part方法

在Java 9中,Durationgained new to…Part methods用于返回天,小时,分钟,秒,毫秒/纳秒的各个部分。请参阅此pre-release OpenJDK source code

鉴于持续时间为49H30M20.123S ......

  • toNanosPart() = 123000000
  • toMillisPart() = 123
  • toSecondsPart() = 20
  • toMinutesPart() = 30
  • toHoursPart() = 1
  • toDaysPart() = 2

请记住,“天”在这里意味着24小时的大块,忽略日历上的日期。如果您关心日期,请改用Period课程。

我不知道是否添加了任何其他格式化程序功能。但至少你可以通过这些新的getter方法获得的数字更方便地生成自己的字符串。

Java 8

奇怪的是,Java 8中java.time的第一版发行版中没有包含这些值的方便的getter方法。 java.time 的优秀设计中很少有疏忽之一框架。

参见相关问题:Why can't I get a duration in minutes or hours in java.time?

答案 1 :(得分:19)

jsr-310中没有句点/持续时间格式化程序,与JodaTime不同。并非JodaTime的每个功能都移植到JSR-310(例如也不是PeriodType)。反之,JSR-310有一些JodaTime中没有的功能(例如本地化的工作日数字或带有调整器的策略模式方法)。

Java 9可能会引入某种内置的格式化格式(从S. Colebourne读取一些内容)。

结论:JSR-310和JodaTime彼此不完全兼容,因此可能需要做很多工作。我不会那么热衷于移民。您是否需要JUDTime不提供的JSR-310的特殊功能?

补充说明:您还应该了解joda期间(包括所有单位从几年到几秒)与jsr310期间(仅年,月,日)或jsr310-持续时间(仅数小时)不完全兼容的事实,分钟,秒和分数秒。)

答案 2 :(得分:18)

没有内置方法,但您可以访问小时/分钟数,而无需手动计算。您的具体格式如下:

Duration d = Duration.of(75, HOURS).plusMinutes(15);
long hours = d.toHours(); //75
long minutes = d.minusHours(hours).toMinutes(); //15
String HH_PLUS_MM = hours + "+" + minutes; //75+15
System.out.println(HH_PLUS_MM);

如果保证持续时间少于24小时,您也可以使用此技巧:

String hhPlusMm = LocalTime.MIDNIGHT.plus(d).format(DateTimeFormatter.ofPattern("HH+mm"));

答案 3 :(得分:7)

你可以使用来自commons-lang3-time的DurationFormatUtils(你需要使用的时间为" mm"因为格式与SimpleDateFormat中的格式相同): DurationFormatUtils.formatDuration(interval.toMillis(), "HHH+mm")

可悲的是,我发现没有办法排除空白部分,就像在我的情况下,天或小时可能是0,所以我仍然需要自己动手。

更新:我已打开an issue for this on Apache commons.lang.time.DurationFormatUtils JIRA

答案 4 :(得分:1)

我知道这是一个老问题,但我最近遇到了同样的问题。确实 应该是比这更好的解决方案,但这对我有用:

public static String millisToElapsedTime(long millis){
    DateFormat fmt = new SimpleDateFormat(":mm:ss.SSS");
    fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
    return (millis/3600000/*hours*/)+fmt.format(new Date(millis));
}

然后,您可以添加:

public static String durationToElapsedTime(Duration d){
    return millisToElapsedTime(d.toMillis());
}