I need to obtain a collection that should be filled with datetime intervals between some input and LocalDatetime.now
.
Example:
If I would to build a interval based on every 30 minutes, it should be something like 2017-06-12 00:30, 2017-06-12 01:00, 2017-06-12 01:30, 2017-06-12 02:00..and go on
.
I've wrote a code that does my requirement but it looks like Java using Scala syntax - not a functional and cleaner way.
val now = LocalDateTime.now
val dates = if (interval.toInt > 0) {
var tempDate = LocalDate.now.atStartOfDay()
val allDates = scala.collection.mutable.ListBuffer[String]()
while (tempDate.isBefore(now)) {
allDates += tempDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
tempDate = tempDate.plusMinutes(interval.toInt)
}
allDates
} else {
var initialDay = LocalDate.now.minusDays(30)
val allDates = scala.collection.mutable.ListBuffer[String]()
while (initialDay.isBefore(LocalDate.now)) {
allDates += initialDay.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
initialDay = initialDay.plusDays(1)
}
allDates
}
How can I refactor this code to looks like functional style or at least remove that mutable variable?
答案 0 :(得分:6)
You should use Scala's Stream
type to build a lazy stream from the start date in half-hour increments, and then lazily take only as many dates from that which are earlier than the stop date. E.g.:
def halfHoursFrom(start: LocalDateTime): Seq[LocalDateTime] =
Stream
.iterate(start)(_.plusMinutes(30))
.takeWhile(_.isBefore(LocalDateTime.now))
You will find the documentation for the Stream
type in the standard library reference. The two notable methods we're using here are:
Stream.iterate
(in the Stream
companion object): builds an infinite stream lazily from a starting value and an increment functionStream#takeWhile
(in the Stream
class): takes only as many elements from the given stream as match the given predicate (function which tests each element and returns true
/false
).Note that I'm upcasting the return type to Seq[LocalDateTime]
to hide the implementation details from the caller.