Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate over dates range (the scala way)

Given a start and an end date I would like to iterate on it by day using a foreach, map or similar function. Something like

(DateTime.now to DateTime.now + 5.day by 1.day).foreach(println)

I am using https://github.com/nscala-time/nscala-time, but I get returned a joda Interval object if I use the syntax above, which I suspect is also not a range of dates, but a sort of range of milliseconds.

EDIT: The question is obsolete. As advised on the joda homepage, if you are using java 8 you should start with or migrate to java.time.

like image 984
Gismo Ranas Avatar asked May 11 '15 11:05

Gismo Ranas


2 Answers

For just iterating by day, I do:

Iterator.iterate(start) { _ + 1.day }.takeWhile(_.isBefore(end))

This has proven to be useful enough that I have a small helper object to provide an implicit and allow for a type transformation:

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)
  }
}

Sample usage:

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
like image 187
hayden.sikh Avatar answered Nov 14 '22 16:11

hayden.sikh


You may use plusDays:

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

Given start and end dates:

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)
like image 30
Shyamendra Solanki Avatar answered Nov 14 '22 16:11

Shyamendra Solanki