2015-05-11 11 views
5

Biorąc pod uwagę datę rozpoczęcia i datę końcową, chciałbym iterować ją w ciągu dnia za pomocą funkcji foreach, mapy lub podobnej funkcji. Coś jakIteracja w zakresie dat (droga scala)

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

Używam https://github.com/nscala-time/nscala-time, ale dostaję wróciła obiektu Joda Interval jeśli mogę użyć składni powyżej, które podejrzewam, nie jest również zakres dat, ale rodzajem zakresie milisekund.

EDYCJA: To pytanie jest przestarzałe. Zgodnie z zaleceniami na stronie głównej joda, jeśli używasz java 8, powinieneś zacząć od lub migrować do java.time.

+0

Wystarczy dodaje 'nscala-oddać porównywalnych towarów Zależność i napisane '(DateTime.now do DateTime.now + (5 dni) przez (1 dzień). foreach (println) '. Działa jak magia – Odomontois

+0

Otrzymuję: wartość przez nie jest członkiem org.joda.time.Interval –

+1

To prawie mój kod https://gist.github.com/Odomontois/ea73f9bbfcb4cdc5f1b6 – Odomontois

Odpowiedz

17

Można użyć plusDays:

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

Podane daty rozpoczęcia i zakończenia:

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) 
+0

dziękuję, ale chodzi o to, że mam data rozpoczęcia i zakończenia –

+0

@GismoRanas odpowiednio zaktualizował odpowiedź. –

1

można użyć coś takiego:

object Test extends App { 
    private val startDate: DateTime = DateTime.now() 
    private val endDate: DateTime = DateTime.now().plusDays(5) 
    private val interval: Interval = new Interval(startDate, endDate) 
    Stream.from(0,1) 
     .takeWhile(index => interval.contains(startDate.plusDays(index))) 
     .foreach(index => println(startDate.plusDays(index))) 
} 
10

Dla prostu iteracja przez dnia, do:

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

ta okazała się na tyle, że mam mały przedmiot pomocnika świadczenia niejawna i pozwalają na transformację typu przydatne: Wykorzystanie

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

Próbka:

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 
2

Rozwiązanie za pomocą interfejsu API języka Java za pomocą Scala

Niezbędne import i inicjalizacji

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

val now = LocalDate.now 

Tworzenie Lista LocalDate za okres próbkowania

(0 to 5) 
    .map(days => now.plusDays(days)) 
    .foreach(println) 

iteracyjnego dat między początkiem i końcem

//Extract the duration 
val duration = Period 
    .between(now, now.plusDays(5)) 
    .get(ChronoUnit.DAYS) 
//val duration = now.compareTo(now.plusDays(5)) 

//Create list for the duration 
(0 to duration) 
    .map(days => now.plusDays(days)) 
    .foreach(println) 
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 
} 
+0

Proszę, nie, nie 'java.util.Date' ponownie ... Jesteśmy już w scala. Ale 'java.util.Date' umarł nawet w Javie lata temu, i jest już zaakceptowana odpowiedź z' DateTime'. –