0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

期間の重複チェック(LocalTime, LocalDate, LocalDateTime)

Posted at

毎回ロジックを考えている気がするのでメモしておく。

  • 期間の終了がnull (つまり開始からこの先ずっと対象期間) というパターンもよくあるので、それにも対応。
  • 「10:00 ~ 11:00」と「11:00 ~ 12:00」のような、期間1の終了と期間2の開始がぴったり一致している時も重複あり判定にしている。このパターンを重複なし判定にする場合は、 !start2.isAfter(end1)start2.isBefore(end1)に、 !end2.isBefore(start1)end2.isAfter(start1) にする。
 /**
   * 期間の重複チェック(LocalTime版)
   * 単一のポイントで期間が重なったときも重複したとみなす。
   * e.g.)
   *  期間1 => 10:00 ~ 11:00
   *  期間2 => 11:00 ~ 12:00
   *  結果 => 重複あり(true)
   *
   * @param start1 期間1の開始
   * @param end1 期間1の終了
   * @param start2 期間2の開始
   * @param end2 期間2の終了
   * @return 重複してたらtrue
   */
  def isOverlapped(start1: LocalTime, end1: LocalTime, start2: LocalTime, end2: LocalTime): Boolean =
    !start2.isAfter(end1) && !end2.isBefore(start1)

  /**
   * 期間の重複チェック(LocalTime版, 期間終了Option可)
   * 単一のポイントで期間が重なったときも重複したとみなす。
   * e.g.)
   *  期間1 => 10:00 ~ 11:00
   *  期間2 => 11:00 ~ 12:00
   *  結果 => 重複あり(true)
   *
   * @param start1 期間1の開始
   * @param end1Opt 期間1の終了 (Noneなら開始以降ずっと対象期間)
   * @param start2 期間2の開始
   * @param end2Opt 期間2の終了 (Noneなら開始以降ずっと対象期間)
   * @return 重複してたらtrue
   */
  def isOverlapped(start1: LocalTime, end1Opt: Option[LocalTime], start2: LocalTime, end2Opt: Option[LocalTime]): Boolean =
    end1Opt.fold(true)(!start2.isAfter(_)) && end2Opt.fold(true)(!_.isBefore(start1))

  /**
   * 期間の重複チェック(LocalDate版)
   * 単一のポイントで期間が重なったときも重複したとみなす。
   * e.g.)
   *  期間1 => 2020-10-01 ~ 2020-10-10
   *  期間2 => 2020-10-10 ~ 2020-10-20
   *  結果 => 重複あり(true)
   *
   * @param start1 期間1の開始
   * @param end1 期間1の終了
   * @param start2 期間2の開始
   * @param end2 期間2の終了
   * @return 重複してたらtrue
   */
  def isOverlapped(start1: LocalDate, end1: LocalDate, start2: LocalDate, end2: LocalDate): Boolean =
    !start2.isAfter(end1) && !end2.isBefore(start1)

  /**
   * 期間の重複チェック(LocalDate版, 期間終了Option可)
   * 単一のポイントで期間が重なったときも重複したとみなす。
   * e.g.)
   *  期間1 => 2020-10-01 ~ 2020-10-10
   *  期間2 => 2020-10-10 ~ 2020-10-20
   *  結果 => 重複あり(true)
   *
   * @param start1 期間1の開始
   * @param end1Opt 期間1の終了 (Noneなら開始以降ずっと対象期間)
   * @param start2 期間2の開始
   * @param end2Opt 期間2の終了 (Noneなら開始以降ずっと対象期間)
   * @return 重複してたらtrue
   */
  def isOverlapped(start1: LocalDate, end1Opt: Option[LocalDate], start2: LocalDate, end2Opt: Option[LocalDate]): Boolean =
    end1Opt.fold(true)(!start2.isAfter(_)) && end2Opt.fold(true)(!_.isBefore(start1))

  /**
   * 期間の重複チェック(LocalDateTime版)
   * 単一のポイントで期間が重なったときも重複したとみなす。
   * e.g.)
   *  期間1 => 2020-10-01 10:00:00 ~ 2020-10-10 20:00:00
   *  期間2 => 2020-10-10 20:00:00 ~ 2020-10-20 20:00:00
   *  結果 => 重複あり(true)
   *
   * @param start1 期間1の開始
   * @param end1 期間1の終了
   * @param start2 期間2の開始
   * @param end2 期間2の終了
   * @return 重複してたらtrue
   */
  def isOverlapped(start1: LocalDateTime, end1: LocalDateTime, start2: LocalDateTime, end2: LocalDateTime): Boolean =
    !start2.isAfter(end1) && !end2.isBefore(start1)

  /**
   * 期間の重複チェック(LocalDateTime版, 期間終了Option可)
   * 単一のポイントで期間が重なったときも重複したとみなす。
   * e.g.)
   *  期間1 => 2020-10-01 10:00:00 ~ 2020-10-10 20:00:00
   *  期間2 => 2020-10-10 20:00:00 ~ 2020-10-20 20:00:00
   *  結果 => 重複あり(true)
   *
   * @param start1 期間1の開始
   * @param end1Opt 期間1の終了 (Noneなら開始以降ずっと対象期間)
   * @param start2 期間2の開始
   * @param end2Opt 期間2の終了 (Noneなら開始以降ずっと対象期間)
   * @return 重複してたらtrue
   */
  def isOverlapped(start1: LocalDateTime, end1Opt: Option[LocalDateTime], start2: LocalDateTime, end2Opt: Option[LocalDateTime]): Boolean =
    end1Opt.fold(true)(!start2.isAfter(_)) && end2Opt.fold(true)(!_.isBefore(start1))
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?