java - 将时间段分成小时间隔

标签 java android

如何使用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对象。

通过调用isBeforeisAfterisEqual方法与停靠点进行比较。如果还没有过去,请再增加一个小时。如果经过停靠站,则使用停靠站本身,而不是下一个小时。

收集到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,所以我们不必覆盖equalshashCode。对于开始和结束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.DateCalendarSimpleDateFormat

要了解更多信息,请参见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 8Java SE 9Java SE 10Java SE 11和更高版本-具有捆绑实现的标准Java API的一部分。


Java 9添加了一些次要功能和修复。

Java SE 6Java SE 7


大多数java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。

Android


更高版本的Android捆绑了java.time类的实现。
对于较早的Android(<26),ThreeTenABP项目改编为ThreeTen-Backport(如上所述)。请参见How to use ThreeTenABP…



Table of which java.time library to use with which version of Java or Android

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

相关文章:

android - 更改图像颜色在 android 中花费太多时间

java - 从 Jenkins 或网站重启 Tomcat

java - File.list() 为目录返回 null

java - 使用来自 AD 服务器的身份验证时出错

android - 在android中关闭自动对焦

java - 在保存的 txt 文件中排列文本

java - 合并排序数组中的ArrayIndexOutOfBoundsException

java - 如何设置此gradle依赖关系?

android - getLastKnownLocation 仅在位置变化 ~50 m 时更新。为什么?

android - 使用函数在后台线程上使用 RxJava Observables 生成对象