【问题标题】:How to check if the given time is in between the timelimit如何检查给定时间是否在时限之间
【发布时间】:2019-11-18 10:22:28
【问题描述】:

以下是交易列表,我需要每 15 分钟,00:01 到 00:15、00:16 到 00:30、00:31 到 00:45 完成交易的计数... 23:45(直到一天结束),如果在该特定时间没有完成交易,则需要填充 0.00,

样本数据:

124385 20191029001650
124385 20191029002050
124385 20191029102050
124391 20191029135007
124391 20191029135507 
124392 20191029144229

预期的输出应该是0.00,2,0.00,0.00,0.00 ....

我们需要发送数据,例如在 00:15 到 00:30 “2”事务已完成,从 10:16 到 10:30 “1”事务。

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 我建议您查看 Java Time API,特别是 Instant 类。 docs.oracle.com/javase/8/docs/api/java/time/Instant.html。它提供了一种方便的方法来检查一个时间戳是否在其他时间戳之前或之后或之间。
  • 您的示例列表是否正确?您有多个 txn id 值,以及重复的 txn 和时间戳对。

标签: java date timestamp


【解决方案1】:

定义一个具有两个成员字段的 event 类:一个用于事务编号的 Long 整数对象,以及一个 LocalDateTime for the date-time value (orInstant (如果您知道预期的时区或与 UTC 的偏移量)。

package work.basil.example;

import java.time.LocalDateTime;
import java.util.Objects;

final public class Event implements Comparable < Event >
{
    // -------|  Members  |-----------------------------------
    final private Integer transactionId;
    final private LocalDateTime when;

    // -------|  Constructors  |-----------------------------------
    public Event ( Integer transactionId , LocalDateTime when )
    {
        this.transactionId = Objects.requireNonNull( transactionId );
        this.when = Objects.requireNonNull( when );
    }

    // -------|  Accessors  |-----------------------------------
    // Immutable, read-only. So getters only, no setters.
    public Integer getTransactionId ( )
    {
        return transactionId;
    }

    public LocalDateTime getWhen ( )
    {
        return when;
    }

    // -------|  Object  |-----------------------------------

    @Override
    public boolean equals ( Object o )
    {
        if ( this == o ) return true;
        if ( o == null || getClass() != o.getClass() ) return false;
        Event event = ( Event ) o;
        return getTransactionId().equals( event.getTransactionId() ) &&
                getWhen().equals( event.getWhen() );
    }

    @Override
    public int hashCode ( )
    {
        return Objects.hash( getTransactionId() , getWhen() );
    }

    @Override
    public String toString ( )
    {
        return "Event{ " +
                "transactionId=" + transactionId +
                " | when=" + when +
                " }";
    }
}

解析您的传入数据。

ID号使用Integer类解析。

Integer transactionId = Integer.valueOf( input ) ;

对于日期时间,定义格式模式。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMddHHmmss" ) ;

解析每个字符串。

LocalDateTime ldt = LocalDateTime.parse( input , f ) ;

按每个LocalDateTime 对对象进行排序。要么实现Comparable,要么创建一个Comparator 对象。两者都在 Stack Overflow 中被多次介绍过,因此请搜索以了解更多信息。

// --------|  Comparator  |-----------------------
/**
 * Comparator by `when`
 */
public static Comparator <Event> WhenComparator = new Comparator<Event>() {

    @Override
    public int compare(Event e1, Event e2) {
        return e1.getWhen().compareTo( e2.getWhen() );
    }
};

从第一个对象开始。取它的LocalDateTime 对象。通过调用with 并传递LocalTime.MIN 创建一个新的。没有区域或偏移量,我们知道每天和每小时是一个通用长度,60 分钟,24 小时。

如此循环,一次增加 15 分钟。使用Duration 定义不附加到时间线的时间跨度,以小时-分钟-秒为单位。

Duration d = Duration.ofMinutes( 15 ) ;

这为您提供了开始和停止时间。

  • 如果您要将这些LocalDateTime 对象调整到偏移量或时区,请为开始和停止提取Instant。然后在将ThreeTen-Extra 库添加到您的项目后,将它们包含为Interval 对象。 Interval 类提供了方便的比较方法,例如contains
  • 如果使用LocalDateTime,请考虑创建自己的LocalDateTimeRange 类来保存一对LocalDateTime 对象,并实现contains( LocalDateTime ) 方法。

您自己的LocalDateTimeRange 可能看起来像这个粗略的、完全未经测试的源代码:

package work.basil.example;

import java.time.LocalDateTime;
import java.util.Objects;

public class LocalDateTimeRange
{
    final private LocalDateTime start, end;

    public LocalDateTimeRange ( LocalDateTime start , LocalDateTime end )
    {
        this.start = Objects.requireNonNull( start );
        this.end = Objects.requireNonNull( end );
    }

    public LocalDateTime getStart ( )
    {
        return this.start;
    }

    public LocalDateTime getEnd ( )
    {
        return this.end;
    }

    public boolean contains ( LocalDateTime ldt )
    {
        // Contains is true if the target is greater-than-or-equal-to (not before) the start, and is less-than (before) the ending. 
        // This approach is known as Half-Open, where the beginning is inclusive while the ending is exclusive. 
        return ( ! ldt.isBefore( this.getStart() ) ) && ldt.isBefore( this.getEnd() );
    }

    @Override
    public boolean equals ( Object o )
    {
        if ( this == o ) return true;
        if ( o == null || getClass() != o.getClass() ) return false;
        LocalDateTimeRange that = ( LocalDateTimeRange ) o;
        return getStart().equals( that.getStart() ) &&
                getEnd().equals( that.getEnd() );
    }

    @Override
    public int hashCode ( )
    {
        return Objects.hash( getStart() , getEnd() );
    }

    @Override
    public String toString ( )
    {
        return start + "/" + end; // Return string in standard ISO 8601 format. 
    }


    static public LocalDateTimeRange parse ( )
    {
        // Parse a string in standard ISO 8601 format. 
        …
    }
}

比较手中的物体,看它是否不小于起点,小于终点。这种定义时间跨度的半开放方法通常是最好的,其中开始是包容性的,而结束是排斥性的。

继续循环,直到找到包含手头对象的日期时间的日期时间范围。找到后,添加到Map,或者:

  • Map &lt; LocalDateTimeRange , &lt; Integer &gt; &gt; 用于增加计数。
  • Map &lt; LocalDateTimeRange , &lt; List&lt; Event &gt; &gt; &gt;,您可以在其中将Event 对象添加到ListSet

如果在该特定时间没有完成交易,则需要填充 0.0

要么将这样的值添加到映射中,要么将映射的 保留为空 LocalDateRangekey

循环到下一个对象。

完成后,分析您的地图。

提示:教育发布该数据的人员:

  • ISO 8601 序列化为文本的日期时间值的标准格式。
  • 始终指示时区或与 UTC 的偏移量的重要性。

上面讨论的所有这些主题都已在 Stack Overflow 上多次讨论过。因此,搜索以了解更多信息。并在发布前彻底搜索 Stack Overflow。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 2016-10-23
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 2017-11-22
    相关资源
    最近更新 更多