Kotlin:如何在Joda间隔内迭代所有日期?

时间:2018-08-29 12:14:57

标签: kotlin jodatime intervals

我想迭代给定Joda间隔内的所有日期:

var workItem: DispatchWorkItem?

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    // Cancel any outstanding search
    self.workItem?.cancel() 

    guard let text = textField.text, let textRange = Range(range, in: text) else {
        return true
    }

    let updatedText = text.replacingCharacters(in: textRange, with: string)

    guard updatedText.count >= 3 else { 
        return true
    }

    // Set up a DispatchWorkItem to perform the search
    let workItem = DispatchWorkItem { [weak self] in
        self?.performSearch(updatedText)
    }

    // Run this block after 0.5 seconds
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: workItem)

    // Keep a reference to it so it can be cancelled
    self.workItem = workItem 

    return true   
}

func performSearch(_ text: String) {

} 

如何在Kotlin中做到这一点?

4 个答案:

答案 0 :(得分:3)

以下扩展功能从给定的Sequence中提供了LocalDate个对象中的Interval个对象,可用于迭代这些日期。

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的实现方式:

  

“时间间隔表示两个时刻之间的时间段。间隔包括开始时刻和结束时刻。”

如果出于任何原因要使其包含最后一天,只需将takeIf条件更改为it <= end

答案 1 :(得分:3)

深受您当前解决方案的启发:

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 }

答案 2 :(得分:3)

我想如果您需要多次,最好重载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
    }
}

答案 3 :(得分:0)

LocalDate如今是首选,因此我们可以简单地将天作为数字进行迭代:

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);
    // ...
}