【问题标题】:How to generate dynamic daterange for n days in Scala如何在Scala中生成n天的动态日期范围
【发布时间】:2020-09-04 06:13:56
【问题描述】:

我希望使用 Scala 将过去 'n' 天的日期范围作为字符串。以下是我的输入

输入

开始日期 = "2020-08-20"

范围 = 30(天)

预期输出:

"2020-08-20,2020-08-19,2020-08-18,2020-08-17,2020-08-16,2020-08-15,2020-08-14,2020-08-13,2020-08-12,2020-08-11,2020-08-10,2020-08-19,2020-08-09,2020-08-08,2020-08-07,2020-08-06,2020-08-05,2020-08-04,2020-08-03,2020-08-02,2020-08-01,2020-07-31,2020-07-30,2020-07-29,2020-07-28,2020-07-27,2020-07-26,2020-07-25,2020-07-24,2020-07-23,2020-07-22"

【问题讨论】:

  • 显示一些代码,显示你的问题。这不是一个“请给我代码”的网站。

标签: scala


【解决方案1】:

我建议使用Iterator.iterate 来生成延迟的日期序列:

import java.time.LocalDate

def days(start: LocalDate, step: Int): Iterator[LocalDate] =
  Iterator.iterate(start)(_.plusDays(step))

您可以使用 step > 0 让该迭代器前进或使用 step < 0 后退(或使用 step == 0 保持静止,但您不太可能想要这样)。

在您的情况下,您可以让 step = -1 为迭代器中的每个项目一次向后移动一天,然后将 .take(30) 项目和 mkString 从它们中移出:

val startingDate = LocalDate.parse("2020-08-20")

val output = days(start = startingDate, step = -1).take(30).mkString(",")

// output is 2020-08-20,2020-08-19,2020-08-18,2020-08-17,...

您可以使用此代码here on Scastie

请注意,Iterators 是可变的,这意味着它们不能在您的代码中安全地共享。对于纯功能替代方案,您可以使用LazyList,如this Scastie snippet 所示。

现在,这种方法的问题在于您可能会无意中导致无限循环:如果您不这样做,.take(30)mkString 的调用将永远不会终止。如果您喜欢严格收集,您可以使用range 方法,该方法在Lists 上定义,首先生成一个整数范围,然后将范围中的每个项目添加到您的开始日期,如以下替代示例中所示:

import java.time.LocalDate

def days(start: LocalDate, end: Long): List[LocalDate] =
  List.range(0, end, step = if (end < 0) -1 else 1).map(start.plusDays)

val startingDate = LocalDate.parse("2020-08-20")

val output = days(start = startingDate, end = -30).mkString(",")

// output is the same as in the previous example

在这里您可以找到List.range 的文档(您会很容易理解为什么我通过了step,因为我在阅读文档时可能会玩弄this snippet on Scastie)。

请注意,您可以对 Iterators 和其他惰性序列使用相同的方法(range 方法)。

关于惰性集合与严格集合、可变集合与不可变集合的一些资源:

【讨论】:

    【解决方案2】:
    import java.time.LocalDate
    
    def previousDatesStr(startingDateStr: String, range: Int): String = {
        val startingDate = LocalDate.parse(startingDateStr)
        Range(0, range).map(d => startingDate.minusDays(d)).mkString(", ")
    }
    
    

    其他答案很棒。但尽量少用 java 库。因为您使用的是scala。

    【讨论】:

      猜你喜欢
      • 2011-01-10
      • 2016-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多