迭代日期范围(scala方式)

时间:2015-05-11 11:29:47

标签: scala datetime iteration nscala-time

鉴于开始日期和结束日期,我希望白天使用foreach,map或类似函数迭代它。像

这样的东西
(DateTime.now to DateTime.now + 5.day by 1.day).foreach(println)

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

编辑:这个问题已经过时了。正如joda主页上所述,如果您使用的是Java 8,则应该从java.time开始或迁移到https://earthdata.nasa.gov/data/near-real-time-data/firms/active-fire-data

6 个答案:

答案 0 :(得分:24)

您可以使用plusDays

val now = DateTime.now
(0 until 5).map(now.plusDays(_)).foreach(println)

给定开始和结束日期:

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)

答案 1 :(得分:2)

  

使用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

为样本持续时间

创建LocalDate列表
(0 to daysTill)
  .map(days => now.plusDays(days))
  .foreach(println)

使用toEpochDaygetLong(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)

答案 2 :(得分:2)

此答案修复了mrsrinivas答案的问题,.get(ChronoUnits.DAYS)仅返回持续时间的天数部分,而不是总天数。

必要的导入和初始化

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

注意上述答案会导致错误的结果(总天数为117)

scala> Period.between(start, end)
res6: java.time.Period = P3M26D

scala> Period.between(start, end).get(ChronoUnit.DAYS)
res7: Long = 26

迭代开始和结束之间的特定日期

val start = LocalDate.of(2018, 1, 5)
val end   = LocalDate.of(2018, 5, 1)

// Create List of `LocalDate` for the period between start and end date

val dates: IndexedSeq[LocalDate] = (0L to (end.toEpochDay - start.toEpochDay))
  .map(days => start.plusDays(days))

dates.foreach(println)

答案 3 :(得分:1)

你可以使用类似的东西:

var frmP = Application.OpenForms.OfType<frm_Protection>().FirstOrDefault();

if (frmP != null)
{
    frmP.CanClose = true;
    frmP.Close();
}

答案 4 :(得分:0)

import java.util.{Calendar, Date}
import scala.annotation.tailrec

/** Gets date list between two dates
  *
  * @param startDate  Start date
  * @param endDate    End date
  * @return           List of dates from startDate to endDate
  */
def getDateRange(startDate: Date, endDate: Date): List[Date] = {
  @tailrec
  def addDate(acc: List[Date], startDate: Date, endDate: Date): List[Date] = {
    if (startDate.after(endDate)) acc
    else addDate(endDate :: acc, startDate, addDays(endDate, -1))
  }

  addDate(List(), startDate, endDate)
}

/** Adds a date offset to the given date
  *
  * @param date       ==> Date
  * @param amount     ==> Offset (can be negative)
  * @return           ==> New date
  */
def addDays(date: Date, amount: Int): Date = {
  val cal = Calendar.getInstance()
  cal.setTime(date)
  cal.add(Calendar.DATE, amount)
  cal.getTime
}

答案 5 :(得分:0)

在这种情况下,Scala wayJava way

Scala上运行Java 9+时,我们可以使用java.time.LocalDate::datesUntil

import java.time.LocalDate
import collection.JavaConverters._

// val start = LocalDate.of(2019, 1, 29)
// val end   = LocalDate.of(2018, 2,  2)
start.datesUntil(end).iterator.asScala
// Iterator[java.time.LocalDate] = <iterator> (2019-01-29, 2019-01-30, 2019-01-31, 2019-02-01)

如果要包含最后日期:

start.datesUntil(end.plusDays(1)).iterator.asScala
// 2019-01-29, 2019-01-30, 2019-01-31, 2019-02-01, 2019-02-02