tl;博士
Duration.between (
LocalTime.MIN ,
LocalTime.parse ( "08:30:00" )
).toString()
PT8H30M
持续时间与时间戳
如果字符串08:30:00 的意思是“八个半小时”的时间跨度,则不要使用术语“时间戳”。 “持续时间”这个词是正确且常用的。并避免使用 HH:MM:SS 的格式,因为它是如此模棱两可,看起来像是一天中的时间。而是使用下面讨论的标准格式。
如果字符串08:30:00 的意思是“早上八点半”,则使用“时间戳”一词并避免使用“持续时间”一词。
这是两个截然不同的概念。您必须弄清楚它们,每个都应该在您的脑海中是不同的。使用 HH:MM:SS 的模棱两可的格式使区分变得更加困难(所以避免使用这种格式!)。
java.time
现代方法是使用 java.time 类。
LocalTime
正如 Sharma 评论中提到的,首先将您的字符串解析为LocalTime。此类表示没有日期和时区的时间。没有时区意味着这些对象基于通用 24 小时制,而不考虑 Daylight Saving Time (DST) 等异常情况。
我们并不真正想要LocalTime,因为您的输入字符串代表时间跨度而不是一天中的某个时间。但这只是第一步。
LocalTime lt = LocalTime.parse ( "08:30:00" );
Duration
为了表示所需的时间跨度,我们需要 Duration 类。此类适用于未附加到时间线的时间跨度。我们可以通过转换LocalTime 来创建一个,方法是获取从时钟开始的时间量00:00:00.0 或LocalTime.MIN,以及我们刚刚实例化的lt。
Duration d = Duration.between ( LocalTime.MIN , lt );
ISO 8601
我们可以通过调用Duration::toString 以标准ISO 8601 format for durations 生成一个字符串来查看结果。 java.time 类在解析/生成字符串时默认使用 ISO 8601。对于持续时间,标准格式为PnYnMnDTnHnMnS,其中P 标记开始,T 将年-月-日部分与小时-分钟-秒部分分开。因此,我们的八个半小时将显示为PT8H30M。
System.out.println("d.toString():" + d);
d.toString(): PT8H30M
日期时间值避免使用小数
为了处理此类持续时间值,我强烈建议在您的 Java 代码中使用 Duration 对象,并在序列化为文本时使用 ISO 8601 格式。
- 在代码中使用对象可提供类型安全性,使您的代码更具自记录性,并确保有效值。
- 对文本使用 ISO 8601 格式可生成易于解析的值,是一种易于人类阅读的格式,并且其含义明确,而
08:30:00 可能会被误读为一天中的时间。李>
您想要的十进制数格式(如 8.5)不明确(容易忘记其含义)。此外,在使用 floating-point 类型(float、Float、double、Double)时,十进制数字很尴尬并且经常不正确,因为这些类型会在小数部分的远端生成无关的不正确数字。浮点技术故意牺牲准确性以提高执行速度。
BigDecimal
如果您必须使用小数,并且想要准确,请使用BigDecimal 类。
在此示例中,我假设您在截断任何小数分钟时需要小时和分钟。所以我打电话给toMinutesDuration。
BigDecimal minutesPerHour = new BigDecimal ( 60L ); // Use var/constant for clarity of your intent.
BigDecimal minutes = new BigDecimal ( d.toMinutes () );
BigDecimal fractionalHours = minutes.divide ( minutesPerHour );
fractionalHours.toString(): 8.5
请参阅此示例code live in IdeOne.com。
如果您坚持使用这些小数而不是 Duration 对象和 ISO 8601 文本,您可能希望使用 BigDecimal 工具进行舍入。
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。