迭代日期范围(scala方式)

Gis*_*nas 10 iteration datetime scala nscala-time

鉴于开始日期和结束日期,我希望白天使用foreach,map或类似函数对其进行迭代.就像是

(DateTime.now to DateTime.now + 5.day by 1.day).foreach(println)
Run Code Online (Sandbox Code Playgroud)

我正在使用https://github.com/nscala-time/nscala-time,但如果我使用上面的语法,我会返回一个joda Interval对象,我怀疑它也不是一系列日期,而是一种范围毫秒.

编辑:这个问题已经过时了.正如joda主页上所建议的那样,如果你使用的是java 8,你应该从java.time开始或者迁移到java.time.

Shy*_*nki 24

你可以使用plusDays:

val now = DateTime.now
(0 until 5).map(now.plusDays(_)).foreach(println)
Run Code Online (Sandbox Code Playgroud)

给定开始和结束日期:

import org.joda.time.Days

val start = DateTime.now.minusDays(5)
val end   = DateTime.now.plusDays(5)    

val daysCount = Days.daysBetween(start, end).getDays()
(0 until daysCount).map(start.plusDays(_)).foreach(println)
Run Code Online (Sandbox Code Playgroud)


hay*_*ikh 20

对于白天迭代,我做:

Iterator.iterate(start) { _ + 1.day }.takeWhile(_.isBefore(end))
Run Code Online (Sandbox Code Playgroud)

这已被证明是足够有用的,我有一个小的辅助对象来提供隐式和允许类型转换:

object IntervalIterators {
  implicit class ImplicitIterator(val interval: Interval) extends AnyVal {
    def iterateBy(step: Period): Iterator[DateTime] = Iterator.iterate(interval.start) { _ + step }
        .takeWhile(_.isBefore(interval.end))

    def iterateBy[A](step: Period, transform: DateTime => A): Iterator[A] = iterateBy(step).map(transform)

    def iterateByDay: Iterator[LocalDate] = iterateBy(1.day, { _.toLocalDate })

    def iterateByHour: Iterator[DateTime] = iterateBy(1.hour)
  }
}
Run Code Online (Sandbox Code Playgroud)

样品用法:

import IntervalIterators._

(DateTime.now to 5.day.from(DateTime.now)).iterateByDay // Iterator[LocalDate]

(30.minutes.ago to 1.hour.from(DateTime.now)).iterateBy(1.second)  // Iterator[DateTime], broken down by second
Run Code Online (Sandbox Code Playgroud)


mrs*_*vas 5

使用 Scala 的 java.time API 解决方案

必要的导入和初始化

import java.time.temporal.ChronoUnit
import java.time.temporal.ChronoField.EPOCH_DAY
import java.time.{LocalDate, Period}

val now = LocalDate.now
val daysTill = 5
Run Code Online (Sandbox Code Playgroud)

LocalDate创建样本持续时间列表

(0 to daysTill)
  .map(days => now.plusDays(days))
  .foreach(println)
Run Code Online (Sandbox Code Playgroud)

toEpochDay使用或迭代开始和结束之间的特定日期getLong(ChronoField.EPOCH_DAY)

//Extract the duration
val endDay = now.plusDays(daysTill)
val startDay = now

val duration = endDay.getLong(EPOCH_DAY) - startDay.getLong(EPOCH_DAY)

/* This code does not give desired results as trudolf pointed
val duration = Period
  .between(now, now.plusDays(daysTill))
  .get(ChronoUnit.DAYS)
*/

//Create list for the duration
(0 to duration)
  .map(days => now.plusDays(days))
  .foreach(println)
Run Code Online (Sandbox Code Playgroud)