Kotlin:如何迭代 Joda 间隔内的所有日期?
Kotlin: How to iterate all dates within a Joda Interval?
我想在给定的 Joda 间隔内迭代所有日期:
val interval = Interval(DateTime.now().minusDays(42), DateTime.now())
如何在 Kotlin 中做到这一点?
以下扩展函数从给定 Interval
中给出 Sequence
个 LocalDate
个对象,可用于迭代这些日期。
fun Interval.toLocalDates(): Sequence<LocalDate> = generateSequence(start) { d ->
d.plusDays(1).takeIf { it < end }
}.map(DateTime::toLocalDate)
用法:
val interval = Interval(DateTime.now().minusDays(42), DateTime.now())
interval.toLocalDates().forEach {
println(it)
}
在此解决方案中,最后一天 DateTime.now()
未包含在 Sequence
中,因为这也是 Interval
的实现方式:
"A time interval represents a period of time between two instants. Intervals are inclusive of the start instant and exclusive of the end."
如果您出于任何原因想让它包括最后一天,只需将 takeIf
条件更改为 it <= end
。
深受您当前解决方案的启发:
fun Interval.toDateTimes() = generateSequence(start) { it.plusDays(1) }
.takeWhile(::contains)
用法:
interval.toDateTimes()
.forEach { println(it) }
如果您需要 LocalDate
,您仍然可以执行以下操作:
interval.toDateTimes()
.map(DateTime::toLocalDate)
.forEach { println(it) }
或再次作为 Interval
的扩展函数:
fun Interval.toLocalDates() = toDateTimes().map(DateTime::toLocalDate)
如果您希望包含结束日期,请改用 takeWhile { it <= end }
。
我想如果你不止一次需要它,最好重载 rangeTo 运算符以允许这种语法
for (i in LocalDate.now() .. LocalDate.now().plusWeeks(1)) {
System.out.print(i) // 2018-08-30 2018-08-31 2018-09-01
}
运算符扩展代码如下:
operator fun LocalDate.rangeTo(other: LocalDate): LocalDateRange {
return LocalDateRange(this, other)
}
并且必要类:
class LocalDateRange(override val start: LocalDate, override val endInclusive: LocalDate)
: ClosedRange<LocalDate>, Iterable<LocalDate> {
override fun iterator(): Iterator<LocalDate> {
return DateIterator(start, endInclusive)
}
}
class DateIterator(start: LocalDate, private val endInclusive: LocalDate)
: Iterator<LocalDate> {
private var current = start
override fun hasNext(): Boolean {
return current <= endInclusive
}
override fun next(): LocalDate {
current = current.plusDays(1)
return current
}
}
LocalDate
现在更受欢迎,所以我们可以简单地用 day 作为数字进行迭代:
for (day in minDate.toEpochDay()..maxDate.toEpochDay()) {
// ...
}
或:
(minDate.toEpochDay()..maxDate.toEpochDay()).forEach {
// ...
}
以日期作为日期进行迭代:
generateSequence(minDate) { it.plusDays(1) }.takeWhile { it < maxDate }.forEach {
// it ...
}
或:
var day = minDate;
while (day < maxDate) {
day = day.plusDays(1);
// ...
}
我想在给定的 Joda 间隔内迭代所有日期:
val interval = Interval(DateTime.now().minusDays(42), DateTime.now())
如何在 Kotlin 中做到这一点?
以下扩展函数从给定 Interval
中给出 Sequence
个 LocalDate
个对象,可用于迭代这些日期。
fun Interval.toLocalDates(): Sequence<LocalDate> = generateSequence(start) { d ->
d.plusDays(1).takeIf { it < end }
}.map(DateTime::toLocalDate)
用法:
val interval = Interval(DateTime.now().minusDays(42), DateTime.now())
interval.toLocalDates().forEach {
println(it)
}
在此解决方案中,最后一天 DateTime.now()
未包含在 Sequence
中,因为这也是 Interval
的实现方式:
"A time interval represents a period of time between two instants. Intervals are inclusive of the start instant and exclusive of the end."
如果您出于任何原因想让它包括最后一天,只需将 takeIf
条件更改为 it <= end
。
深受您当前解决方案的启发:
fun Interval.toDateTimes() = generateSequence(start) { it.plusDays(1) }
.takeWhile(::contains)
用法:
interval.toDateTimes()
.forEach { println(it) }
如果您需要 LocalDate
,您仍然可以执行以下操作:
interval.toDateTimes()
.map(DateTime::toLocalDate)
.forEach { println(it) }
或再次作为 Interval
的扩展函数:
fun Interval.toLocalDates() = toDateTimes().map(DateTime::toLocalDate)
如果您希望包含结束日期,请改用 takeWhile { it <= end }
。
我想如果你不止一次需要它,最好重载 rangeTo 运算符以允许这种语法
for (i in LocalDate.now() .. LocalDate.now().plusWeeks(1)) {
System.out.print(i) // 2018-08-30 2018-08-31 2018-09-01
}
运算符扩展代码如下:
operator fun LocalDate.rangeTo(other: LocalDate): LocalDateRange {
return LocalDateRange(this, other)
}
并且必要类:
class LocalDateRange(override val start: LocalDate, override val endInclusive: LocalDate)
: ClosedRange<LocalDate>, Iterable<LocalDate> {
override fun iterator(): Iterator<LocalDate> {
return DateIterator(start, endInclusive)
}
}
class DateIterator(start: LocalDate, private val endInclusive: LocalDate)
: Iterator<LocalDate> {
private var current = start
override fun hasNext(): Boolean {
return current <= endInclusive
}
override fun next(): LocalDate {
current = current.plusDays(1)
return current
}
}
LocalDate
现在更受欢迎,所以我们可以简单地用 day 作为数字进行迭代:
for (day in minDate.toEpochDay()..maxDate.toEpochDay()) {
// ...
}
或:
(minDate.toEpochDay()..maxDate.toEpochDay()).forEach {
// ...
}
以日期作为日期进行迭代:
generateSequence(minDate) { it.plusDays(1) }.takeWhile { it < maxDate }.forEach {
// it ...
}
或:
var day = minDate;
while (day < maxDate) {
day = day.plusDays(1);
// ...
}