如何使用Java将时间段(10:00:00 PM-20:30:00 PM)划分为小时间隔,以获得以下结果?
10:00:00 - 11:00:00
11:00:00 - 12:00:00
12:00:00 - 13:00:00
13:00:00 - 14:00:00
15:00:00 - 16:00:00
16:00:00 - 17:00:00
17:00:00 - 18:00:00
19:00:00 - 20:00:00
20:00:00 - 20:30:00
最佳答案
对开始和结束进行LocalTime
。
首先增加一个小时。
LocalTime lt = start.plusHours( 1 ) ;
注意不可变的对象。我们没有更改原始对象,而是获得了一个新的
LocalTime
对象。通过调用
isBefore
,isAfter
和isEqual
方法与停靠点进行比较。如果还没有过去,请再增加一个小时。如果经过停靠站,则使用停靠站本身,而不是下一个小时。收集到
List < LocalTime>
中。如果要将每个条目作为一对
LocalTime
对象进行跟踪,请使用一对TimeSlot
成员字段定义一个名为LocalTime
之类的类。 Java 14中预览的新Records功能在这里可以很好地完成。所有这些都已经在Stack Overflow上讨论过很多次了。搜索以了解更多信息。
示例应用
这是一个工作示例应用程序。它使用在JEP 359: Records (Preview) 2020.1 IDE中工作的,在Java 14中预览的IntelliJ中定义的新
Records
功能。package work.basil.example;
import java.time.Duration;
import java.time.LocalTime;
public record LocalTimeRange(LocalTime start , LocalTime stop)
{
}
我们可以想象一下。
我们重写
toString
以产生四种标准ISO 8601格式之一的文本:HH:MM / HH:MM。我们为ISO 8601 for time intervals指定的四种格式定义一个枚举。我们的format
方法采用这些标志之一来产生四种标准格式之一的文本。如果要求,我们产生一个
Duration
对象。此类表示未附加到时间轴的时间跨度,以小时-分钟-秒为单位。因为这是一个
record
,所以我们不必覆盖equals
和hashCode
。对于开始和结束LocalTime
对象的部分,我们也不需要getter方法。package work.basil.example;
import java.time.Duration;
import java.time.LocalTime;
public record LocalTimeRange(LocalTime start , LocalTime end)
{
public enum Format
{ START_AND_END, START_AND_DURATION, DURATION_AND_END, DURATION_ONLY } // Per ISO 8601 standard.
@Override
public String toString ( ) { return this.format( Format.START_AND_END ); } // Per ISO 8601 standard.
public Duration toDuration ( ) { return Duration.between( this.start , this.end ); }
public String format ( LocalTimeRange.Format format )
{
return switch ( format )
{
case START_AND_END -> this.start + "/" + this.end;
case START_AND_DURATION -> this.start.toString() + "/" + this.toDuration().toString();
case DURATION_AND_END -> this.toDuration().toString() + "/" + this.end.toString();
case DURATION_ONLY -> this.toDuration().toString();
};
}
}
我们需要一种创建小时时间范围的方法。
private List < LocalTimeRange > hourlyRanges ( final LocalTime start , final LocalTime stop )
{
// Verify arguments
Objects.requireNonNull( start , "Received null time-of-day for start. Message # 51521a5c-5f49-4c74-98e3-fce2587edf77." );
Objects.requireNonNull( stop , "Received null time-of-day for stop. Message # 41b98429-4edb-4209-a12f-e266dcae4a90." );
// Logic
int initialCapacity = java.lang.Math.toIntExact( Duration.between( start , stop ).toHours() + 1 ); // Returns the value of the long argument; throwing an exception if the value overflows an int.
ArrayList < LocalTimeRange > ranges = new ArrayList <>( initialCapacity );
LocalTime localTime = start;
while ( ! localTime.isAfter( stop ) )
{
LocalTimeRange range = null;
LocalTime hourLater = localTime.plusHours( 1 );
if ( ! hourLater.isAfter( stop ) )
{
range = new LocalTimeRange( localTime , hourLater );
} else
{
range = new LocalTimeRange( localTime , stop );
}
Objects.requireNonNull( range );
ranges.add( range );
// Prepare for next loop.
localTime = hourLater;
}
ranges.trimToSize();
return Objects.requireNonNull( ranges );
}
以及一些执行它的代码。
LocalTime start = LocalTime.parse( "10:00:00" );
LocalTime end = LocalTime.parse( "20:30:00" );
List < LocalTimeRange > ranges = this.hourlyRanges( start , end );
System.out.println( "ranges = " + ranges );
System.out.println( ranges.stream().map( range -> range.toDuration() ).collect( Collectors.toList() ) );
System.out.println( ranges.stream().map( range -> range.format( LocalTimeRange.Format.START_AND_END ) ).collect( Collectors.toList() ) );
System.out.println( ranges.stream().map( range -> range.format( LocalTimeRange.Format.START_AND_DURATION ) ).collect( Collectors.toList() ) );
System.out.println( ranges.stream().map( range -> range.format( LocalTimeRange.Format.DURATION_AND_END ) ).collect( Collectors.toList() ) );
System.out.println( ranges.stream().map( range -> range.format( LocalTimeRange.Format.DURATION_ONLY ) ).collect( Collectors.toList() ) );
运行时:
范围= [10:00/11:00、11:00/12:00、12:00/13:00、13:00/14:00、14:00/15:00、15:00/16:00 ,16:00/17:00、17:00/18:00、18:00/19:00、19:00/20:00、20:00/20:30]
[PT1H,PT1H,PT1H,PT1H,PT1H,PT1H,PT1H,PT1H,PT1H,PT1H,PT30M]
[10:00/11:00、11:00/12:00、12:00/13:00、13:00/14:00、14:00/15:00、15:00/16:00、16 :00/17:00、17:00/18:00、18:00/19:00、19:00/20:00、20:00/20:30]
[10:00 / PT1H,11:00 / PT1H,12:00 / PT1H,13:00 / PT1H,14:00 / PT1H,15:00 / PT1H,16:00 / PT1H,17:00 / PT1H,18 :00 / PT1H,19:00 / PT1H,20:00 / PT30M]
[PT1H / 11:00,PT1H / 12:00,PT1H / 13:00,PT1H / 14:00,PT1H / 15:00,PT1H / 16:00,PT1H / 17:00,PT1H / 18:00,PT1H / 19:00,PT1H / 20:00,PT30M / 20:30]
[PT1H,PT1H,PT1H,PT1H,PT1H,PT1H,PT1H,PT1H,PT1H,PT1H,PT30M]
关于java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如
java.util.Date
,Calendar
和SimpleDateFormat
。要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
现在位于Joda-Time中的maintenance mode项目建议迁移到java.time类。
您可以直接与数据库交换java.time对象。使用与JDBC driver或更高版本兼容的JDBC 4.2。不需要字符串,不需要
java.sql.*
类。 Hibernate 5和JPA 2.2支持java.time。在哪里获取java.time类?
Java SE 8,Java SE 9,Java SE 10,Java SE 11和更高版本-具有捆绑实现的标准Java API的一部分。
Java 9添加了一些次要功能和修复。
Java SE 6和Java SE 7
大多数java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。
Android
更高版本的Android捆绑了java.time类的实现。
对于较早的Android(<26),ThreeTenABP项目改编为ThreeTen-Backport(如上所述)。请参见How to use ThreeTenABP…。

关于java - 将时间段分成小时间隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61432702/