tl;dr
不需要自己定义Duration
类,Java 提供了一个类。
Duration.between ( // Represent a span of time of hours, minutes, seconds.
LocalTime.MIN , // 00:00:00
LocalTime.parse ( "08:30:00" ) // Parse text as a time-of-day.
) // Returns a `Duration` object, a span-of-time.
.toString() // Generate a `String` with text in standard ISO 8601 format.
PT8H30M
并解析标准 ISO 8601 格式的文本。
Duration.parse( "PT8H30M" ) // Parse standard ISO 8601 text yo get a `Duration` object.
Avoid HH:MM:SS
format
如果通过字符串08:30:00
你的意思是“八个半小时”的时间跨度,而不是一天中的时间“早上八点半”,那么就避免这种格式HH:MM:SS
。这种格式模棱两可,似乎是一天中的某个时间。请改用下面讨论的标准 ISO 8601 格式。
持续时间和一天中的时间是两个截然不同的概念。你一定要清楚,每一个你心里都应该清楚。使用 HH:MM:SS 的模糊格式会使这种区分变得更加困难(因此请避免使用这种格式!)。
java.time
现代方法是使用 java.time 类。
LocalTime
首先将您的字符串解析为LocalTime。此类表示没有日期和时区的时间。没有时区意味着这些对象基于通用 24 小时时钟,而不考虑以下异常情况夏令时 (DST).
我们并不是真的想要一个LocalTime
因为您的输入字符串代表一段时间而不是一天中的某个时间。但这只是第一步。
LocalTime lt = LocalTime.parse ( "08:30:00" );
Duration
为了表示所需的时间跨度,我们想要Duration班级。此类适用于未附加到时间线的时间跨度。我们可以通过转换来创建一个LocalTime
通过获取从时钟开始算起的时间量,00:00:00.0
or LocalTime.MIN,以及lt
我们刚刚实例化了。
Duration d = Duration.between ( LocalTime.MIN , lt );
编辑输入字符串
上面的方法使用LocalTime
仅当您的输入字符串代表的持续时间少于 24 小时时才有效。如果超过24小时,您将自己解析输入字符串。
像下面的代码一样。当然,实际的解析取决于解决特定输入字符串的歧义。是50:00
应该是五十小时还是五十分钟? (这种模糊性是尽可能避免这种令人困惑的格式并坚持使用 ISO 8601 格式的一个重要原因。)
String input = "50:00"; // Or "50:00:00" (fifty hours, either way)
String[] parts = input.split ( ":" );
Duration d = Duration.ZERO;
if ( parts.length == 3 ) {
int hours = Integer.parseInt ( parts[ 0 ] );
int minutes = Integer.parseInt ( parts[ 1 ] );
int seconds = Integer.parseInt ( parts[ 2 ] );
d = d.plusHours ( hours ).plusMinutes ( minutes ).plusSeconds ( seconds );
} else if ( parts.length == 2 ) {
int hours = Integer.parseInt ( parts[ 0 ] );
int minutes = Integer.parseInt ( parts[ 1 ] );
d = d.plusHours ( hours ).plusMinutes ( minutes );
} else {
System.out.println ( "ERROR - Unexpected input." );
}
ISO 8601
我们可以通过生成标准字符串来查看结果ISO 8601 持续时间格式只需调用Duration::toString。 java.time 类在解析/生成字符串时默认使用 ISO 8601。对于持续时间,标准格式是PnYnMnDTnHnMnS
哪里的P
标志着开始和T
将年-月-日部分与时-分-秒部分分开。所以,我们的八个半小时将显示为PT8H30M
.
System.out.println("d.toString():" + d);
d.toString(): PT8H30M
收藏Duration
objects
你可以做一个List
保存类型的元素Duration
.
List<Duration> durations = new ArrayList<>( 3 ); // Initial capacity of 3 elements.
durations.add( d ) ;
durations.add( Duration.between ( LocalTime.MIN , LocalTime.parse ( "03:00:00" ) ) ) ;
durations.add( Duration.between ( LocalTime.MIN , LocalTime.parse ( "01:15:00" ) ) ) ;
持续时间.toString(): [PT8H30M, PT3H, PT1H15M]
请记住,您在该输出中看到的字符串如下PT8H30M
就是这样:生成的字符串的输出。这Duration
类型是not一个简单的字符串而是产生一个 String 对象toString method.
如果您坚持使用 ISO 8601 格式,您可以轻松解析并生成此类字符串。无需经过LocalTime
我们在这个答案的顶部执行了转换 rigamarole。
Duration d = Duration.parse( "PT8H30M" );
看这个例子代码位于 IdeOne.com.
关于 java.time
The java.time框架内置于 Java 8 及更高版本中。这些课程取代了麻烦的旧课程legacy日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat.
The 乔达时间项目,现在在维护模式,建议迁移到java.time类。
要了解更多信息,请参阅甲骨文教程。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310.
从哪里获取 java.time 类?
-
Java SE 8 and SE 9 and later
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
-
Java SE 6 and SE 7
- 许多 java.time 功能都向后移植到 Java 6 和 7三十后端口.
-
Android
- The 三十ABP项目适应三十后端口(如上所述)专门针对 Android。
- See 如何使用 ThreeTenABP....
The 三十额外项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如Interval, YearWeek, YearQuarter, and more.