41

我正在将一个项目从 Joda-Time 转换到 java8 的本地时间库,但遇到了障碍。

我一直找不到 Duration 的格式化程序。我想要一个自定义字符串格式,例如HHH+MM,其中 75 小时 15 分钟的 Duration 格式为"75+15"

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

4

5 回答 5

38

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

在 Java 9 中,Duration该类获得了to…Part用于返回天、小时、分钟、秒、毫秒/纳秒的各个部分的新方法。请参阅此预发布 OpenJDK 源代码

给定 49H30M20.123S 的持续时间……</p>

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

请记住,这里的“天”是指 24 小时的大块,忽略日历上的日期。如果您关心日期,请改用Periodclass。

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

爪哇 8

奇怪的是,Java 8 中 java.time 的第一版中没有包含这些值的方便的 getter 方法。在java.time框架的其他出色设计中,这是极少数的疏忽之一。

请参阅相关问题:为什么我无法在 java.time 中获得以分钟或小时为单位的持续时间?.

于 2016-04-02T21:41:12.370 回答
24

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

Java 9 可能会引入某种内置的句点格式(从 S. Colebourne 阅读有关此的内容)。

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

附加说明:您还应该知道,joda period(包括从年到秒的所有单位)与 jsr310-period(仅年、月、日)或 jsr310-duration(仅小时、分钟、秒和小数秒)。

于 2013-12-29T16:07:26.733 回答
20

没有内置方法,但您可以访问小时/分钟数,而无需手动计算它们。您的特定格式可能如下所示:

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"));
于 2013-12-29T17:49:29.967 回答
11

您可以使用 commons-lang3-time 中的DurationFormatUtils(几分钟内您必须使用“mm”,因为格式与 in 中的格式相同SimpleDateFormat): DurationFormatUtils.formatDuration(interval.toMillis(), "HHH+mm")

可悲的是,我发现没有办法排除空白部分,比如在我的情况下,天数或小时数可能为 0,所以我仍然不得不自己动手。

更新:我在 Apache commons.lang.time.DurationFormatUtils JIRA 上为此打开了一个问题

于 2017-07-04T09:53:46.917 回答
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());
}
于 2016-02-09T17:04:53.907 回答