在Scala中,给定一个日期范围,如何获取该范围内的所有日期?

20

我需要在Scala中编写一个函数,给定日期范围,返回该范围内的列表。 我在Scala方面相对较新,无法想出如何编写正确的'for'循环。目前为止,我已经完成了以下工作:

def calculateDates(from: LocalDate, until: LocalDate): Seq[LocalDate] = {
  var dateArray = []
  //for (LocalDate date <- from; !date.isAfter(to); date <- date.plusDays(1)) 
  for(date <- from to until)
  {
        dateArray :+ date
  }
  return dateArray 
} 

我不知道如何遍历这个范围。

6个回答

31
如果您恰好使用 Java 1.8 的 DateTime API(或其三个 backport 版本之一),则可以编写以下代码:
def between(fromDate: LocalDate, toDate: LocalDate) = {
    fromDate.toEpochDay.until(toDate.toEpochDay).map(LocalDate.ofEpochDay)
} 

这不包括 todate 吗?我有一个场景,我想同时列出从和到日期? - venkat Ramanan VTR
我猜你可以使用 .to 而不是 .until(这应该是标准的 Scala),但我还没有测试过。 - sandris

20
val numberOfDays = Days.daysBetween(from, until).getDays()
for (f<- 0 to numberOfDays) yield from.plusDays(f)

2
“Days”是Scala中的一个类吗? - Core_Dumped
1
这是Joda-Time中的一个类,你似乎正在使用它: http://joda-time.sourceforge.net/apidocs/org/joda/time/Days.html - Ashalynd

7

试试这个

def dateRange(start: DateTime, end: DateTime, step: Period): Iterator[DateTime] =
Iterator.iterate(start)(_.plus(step)).takeWhile(!_.isAfter(end))

为了生成每一天的日期,您可以将步长设置为1天,如下所示:
val range = dateRange(
<yourstartdate>,
<yourenddate>,
Period.days(1))

1
这可能是一个不太好的解决方案,因为使用 start = new DateTime(2015, 1, 30, 0, 0), end = new DateTime(2015, 5, 2, 0, 0), step = Period.months(1) 会得到 "2015-01-30", "2015-02-28", "2015-03-28", "2015-04-28",而不是 "2015-01-30", "2015-02-28", "2015-03-30", "2015-04-30"。 - jbrown

6

在运行Scala时,可以利用新的java.time.LocalDate::datesUntil特性,该特性仅适用于Java 9+

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

// val start = LocalDate.of(2018, 9, 24)
// val end   = LocalDate.of(2018, 9, 28)
start.datesUntil(end).iterator.asScala.toList
// List[LocalDate] = List(2018-09-24, 2018-09-25, 2018-09-26, 2018-09-27)

要包含范围内的最后日期:

start.datesUntil(end.plusDays(1)).iterator.asScala.toList
// List[LocalDate] = List(2018-09-24, 2018-09-25, 2018-09-26, 2018-09-27, 2018-09-28)

3
使用Lamma Date
$ scala -cp lamma_2.11-1.1.2.jar 
Welcome to Scala version 2.11.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import io.lamma.Date
import io.lamma.Date

scala> Date(2015, 7, 7) to Date(2015, 7, 10) foreach println 
Date(2015,7,7)
Date(2015,7,8)
Date(2015,7,9)
Date(2015,7,10)

这个 DateRange 是以懒加载的方式评估的。随意构建一个5000年的日期范围。 :)

2

由于Scala是一种函数式语言,因此建议使用递归:

def calculateDates(from: LocalDate, until: LocalDate): Seq[LocalDate] = {
    if from.compareTo(until) > 1
        return[]
    else
        return from :: calculateDates(from.plusDays(1), until)
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接