[kotlin 메모] [LocalDate] 기간이 연속적인지 여부를 결정하고 싶습니다.
9246 단어 Kotlin
2021/07/14 추가
↑ 꽤 스마트하게 정리된 개선안이 있으므로,
부디 그쪽을 봐 주세요.
소개
기간 목록에 대해 목록의 개별 기간을 결합했을 때 치아가 나오지 않는지 확인합니다.
리스트내의 기간의 중첩은 허용하는 것으로 합니다.
예 1:
1/1~1/15
와 1/16~1/30
는 연속되어 있으므로 OK로 한다예 2:
1/1~1/15
와 1/12~1/30
는 일부 겹쳐져 있지만 OK로 한다예 3:
1/1~1/15
와 1/17~1/30
는 잇몸(1/16)이 있으므로 NG로 한다용어 정의
java.time.LocalDate
형식의 시작일과 종료일의 쌍 // 例
// String->LocalDate変換を逐一書くのが面倒なので拡張関数化します
val formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd")
val String.toLocalDate(): LocalDate = LocalDate.parse(
this, formatter.withResolverStyle(ResolverStyle.STRICT)
)
// 期間のリスト
val ranges = listOf(
"2020-01-01".toLocalDate() to "2020-01-02".toLocalDate(),
"2020-01-03".toLocalDate() to "2020-01-04".toLocalDate(),
"2020-01-05".toLocalDate() to "2020-01-31".toLocalDate(),
"2020-02-01".toLocalDate() to "2020-02-28".toLocalDate()
)
코드
/** 複数の期間が重なるか連続する */
fun overlaps(vararg ranges: Pair<LocalDate, LocalDate>): Boolean {
if (ranges.size < 2) return true
ranges.sortBy { (start, _) -> start }
if (overlaps(ranges[0], ranges[1])) {
val (aStart, aEnd) = ranges[0]
val (_, bEnd) = ranges[1]
val laterEnd = if (aEnd.isAfter(bEnd)) aEnd else bEnd
return overlaps(
Pair(aStart, laterEnd),
*ranges.slice(2 until ranges.size)
.toTypedArray()
)
}
return false
}
/** 2つの期間が重なるか連続する */
fun overlaps(
aRange: Pair<LocalDate, LocalDate>, bRange: Pair<LocalDate, LocalDate>
): Boolean {
val (aStart, aEnd) = aRange
val (bStart, bEnd) = bRange
// 期間Aの開始日 <= 期間Bの終了日+1 && 期間Bの開始日 <= 期間Aの終了日+1
return aStart.isBefore(bEnd.plusDays(2))
&& bStart.isBefore(aEnd.plusDays(2))
}
사고방식
설명 잘못이므로 그림입니다.
색 차이의 띠가, 각각의 기간을 나타내고 있습니다.
밴드의 왼쪽 끝이 시작일, 오른쪽 끝이 종료일이라고 생각하십시오.
우선 시작일이 젊은 순서로 정렬합니다.
기간 목록에서 index0과 index1을 추출하여 연속 또는 중복되었는지 확인하고 결합합니다.
이 때 기간에 치아가 있으면 중단하고 false를 반환합니다.
병합 할 수 있으면 병합 된 기간과 index2 이후의 나머지 기간으로 목록을 다시 만들고,
해당 목록에 대해 위의 조인 작업을 목록 크기가 1이 될 때까지 계속합니다.
리스트 사이즈가 1 이 될 때까지 무사히 결합할 수 있으면, 연속하고 있는 것으로 간주해 true 를 돌려줍니다.
마지막으로
우선 확실히, 이것보다 좋은 수법이 존재한다고 생각합니다. 여러가지 이마이치입니다.
하지만, 찾은 범위에서는 발견되지 않았기 때문에, 스스로 조립했습니다.
원래 수요가 전혀 없을지도 모른다.
개량안・대체안등 있으면, 아무쪼록 잘 부탁드립니다.
Reference
이 문제에 관하여([kotlin 메모] [LocalDate] 기간이 연속적인지 여부를 결정하고 싶습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/akinosora/items/21501fa98252f570a293텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)