在新Duration
日期API(JSR 310)的java.time package类的Java 8及更高版本中,javadoc中说:
这类车型在秒和纳秒项的数量或时间量。它可以使用其他基于持续时间的单位,例如分钟,hours.In另外被访问,天单元可直接或将被视为完全等于24小时,从而忽视夏令效果。
那么,为什么下面的代码会崩溃吗?
Duration duration = Duration.ofSeconds(3000);
System.out.println(duration.get(ChronoUnit.MINUTES));
这就提出了一个UnsupportedTemporalTypeException
:
java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Minutes
at java.time.Duration.get(Duration.java:537)
那么,什么是推荐的方式来提取的持续时间对象分钟和小时?难道我们要计算从自己的秒数?为什么它实现的呀?
“为什么是实现呀?”
其他答案应对toXxx()
方法,使要查询的小时/分钟。我会尽力处理原因。
加入该TemporalAmount
接口和get(TemporalUnit)
方法的过程中相当晚。我个人并不完全相信,我们不得不的工作在这方面的设计正道足够的证据,但略有手臂,扭到添加TemporalAmount
。我相信,在我们这样做稍微混淆了API。
现在回想起来,我相信TemporalAmount
包含正确的方法,但我相信,get(TemporalUnit)
应该有不同的方法名。其原因是,本质上get(TemporalUnit)
是一个框架级方法 - 它不适合日常使用。不幸的是,方法名get
并不意味着这一点,导致盲蝽象调用get(ChronoUnit.MINUTES)
上Duration
。
所以,想get(TemporalUnit)
的方式是想象一个低层次的框架观看量为Map<TemporalUnit, Long>
其中Duration
是大小两个与Map
和SECONDS
的密钥的NANOS
。
以相同的,这样,Period
从低级别的框架看作尺寸3的Map
- DAYS
,MONTHS
和YEARS
(其幸好具有较少错误的几率)。
总体而言,应用程序代码的最好的建议是忽略方法get(TemporalUnit)
。使用getSeconds()
,getNano()
,toHours()
和toMinutes()
代替。
最后一个办法让“HH:MM:SS”从Duration
是做:
LocalTime.MIDNIGHT.plus(duration).format(DateTimeFormatter.ofPattern("HH:mm:ss"))
不漂亮可言,但它的持续时间不超过一天的工作。
to…Part
methods in Java 9JDK-8142936问题现在在Java中实现9,添加下面的方法访问Duration
的每个部分。
toDaysPart
toHoursPart
toMinutesPart
toSecondsPart
toMillisPart
toNanosPart
我想补充到BIGT的答案(+1)中指出的有用toHours
,toMinutes
和其他转换方法。该Duration specification说:
这类车型在秒和纳秒项的数量或时间量。 [...]
的持续时间的范围需要许多比长更大的存储。为了实现这一点,类存储长表示秒数和表示纳秒的秒的int,这将始终为0和999,999,999之间。
有各种各样的getter方法,如getSeconds
,getNano
和get(TemporalUnit)
。鉴于持续时间被表示为(秒,毫微秒)对,为什么get(TemporalUnit)
被限制为秒和毫微秒很明显。这些getter方法直接从持续时间实例中提取数据和为无损的。
相比之下,有各种各样的对方法,包括toDays
,toHours
,toMillis
toMinutes
和toNanos
该做的持续时间值转换。这些转换是有损的,因为它们涉及到数据的截断,否则可能会引发异常,如果持续时间值不能按照要求的格式来表示。
这显然是一开始的方法,无需转换提取数据和对方法进行某种形式的转换设计的一部分。
为了得到一个“标准化”的方式时/分/秒组件,您需要手动计算它们 - 下面的代码基本上是从Duration#toString
方法复制:
Duration duration = Duration.ofSeconds(3000);
long hours = duration.toHours();
int minutes = (int) ((duration.getSeconds() % (60 * 60)) / 60);
int seconds = (int) (duration.getSeconds() % 60);
System.out.println(hours + ":" + minutes + ":" + seconds);
删除众议院再拿到分钟
long hours = attendanceDuration.toHours();
long minutes = attendanceDuration.minusHours(hours).toMinutes();
通过下面的代码我得到这个持续时间的输出:
1天,2小时,5分钟
代码例如:
private String getDurationAsString(Duration duration)
{
StringBuilder durationAsStringBuilder = new StringBuilder();
if (duration.toDays() > 0)
{
String postfix = duration.toDays() == 1 ? "" : "s";
durationAsStringBuilder.append(duration.toDays() + " day");
durationAsStringBuilder.append(postfix);
}
duration = duration.minusDays(duration.toDays());
long hours = duration.toHours();
if (hours > 0)
{
String prefix = Utils.isEmpty(durationAsStringBuilder.toString()) ? "" : ", ";
String postfix = hours == 1 ? "" : "s";
durationAsStringBuilder.append(prefix);
durationAsStringBuilder.append(hours + " hour");
durationAsStringBuilder.append(postfix);
}
duration = duration.minusHours(duration.toHours());
long minutes = duration.toMinutes();
if (minutes > 0)
{
String prefix = Utils.isEmpty(durationAsStringBuilder.toString()) ? "" : ", ";
String postfix = minutes == 1 ? "" : "s";
durationAsStringBuilder.append(prefix);
durationAsStringBuilder.append(minutes + " minute");
durationAsStringBuilder.append(postfix);
}
return durationAsStringBuilder.toString();
}
说明:
通过使用时间的界面,你可以很容易地找到你想要的确切字符串显示。你只需要从目前的持续时间减少更大TemporalUnit。
例如: