我正在将一个项目从 Joda-Time 转换到 java8 的本地时间库,但遇到了障碍。
我一直找不到 Duration 的格式化程序。我想要一个自定义字符串格式,例如HHH+MM,其中 75 小时 15 分钟的 Duration 格式为"75+15"。
这很容易通过转换为句点并使用 PeriodFormatter 来使用 Joda-Time 完成,但我在 Java8 中找不到这种类型的类。我错过了什么吗?
Duration::to…Part
方法在 Java 9 中,Duration
该类获得了to…Part
用于返回天、小时、分钟、秒、毫秒/纳秒的各个部分的新方法。请参阅此预发布 OpenJDK 源代码。
给定 49H30M20.123S 的持续时间……</p>
toNanosPart()
= 123000000toMillisPart()
= 123toSecondsPart()
= 20toMinutesPart()
= 30toHoursPart()
= 1toDaysPart()
= 2请记住,这里的“天”是指 24 小时的大块,忽略日历上的日期。如果您关心日期,请改用Period
class。
我不知道是否添加了任何其他格式化程序功能。但至少您将能够更方便地从通过这些新的 getter 方法获得的数字生成自己的字符串。
奇怪的是,Java 8 中 java.time 的第一版中没有包含这些值的方便的 getter 方法。在java.time框架的其他出色设计中,这是极少数的疏忽之一。
请参阅相关问题:为什么我无法在 java.time 中获得以分钟或小时为单位的持续时间?.
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(仅小时、分钟、秒和小数秒)。
没有内置方法,但您可以访问小时/分钟数,而无需手动计算它们。您的特定格式可能如下所示:
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"));
您可以使用 commons-lang3-time 中的DurationFormatUtils(几分钟内您必须使用“mm”,因为格式与 in 中的格式相同SimpleDateFormat
):
DurationFormatUtils.formatDuration(interval.toMillis(), "HHH+mm")
可悲的是,我发现没有办法排除空白部分,比如在我的情况下,天数或小时数可能为 0,所以我仍然不得不自己动手。
更新:我在 Apache commons.lang.time.DurationFormatUtils JIRA 上为此打开了一个问题。
我知道这是一个老问题,但我最近遇到了同样的事情。确实应该有比这更好的解决方案,但这对我有用:
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());
}