2015-05-11 3 views
5

Gegeben ein Start- und ein Enddatum Ich möchte es am Tag mit einer Foreach-, Map- oder ähnlichen Funktion iterieren. So etwas wieIterate über Datumsbereich (der Scala-Weg)

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

Ich verwende https://github.com/nscala-time/nscala-time, aber ich erhalte ein joda Interval-Objekt zurückgegeben, wenn ich die Syntax oben verwenden, die ich vermute, ist auch nicht eine Reihe von Daten, sondern eine Art Millisekundenbereich.

EDIT: Die Frage ist obsolet. Wie auf der Homepage joda empfohlen, sollten Sie mit java 8 beginnen oder auf java.time migrieren.

+0

Just added 'nscala-Time' 's Abhängigkeit und geschrieben '(DateTime.now bis DateTime.now + (5 Tag) von (1 Tag)). foreach (println) '. Funktioniert wie Magie – Odomontois

+0

Ich bekomme: Wert von ist kein Mitglied von org.joda.time.Interval –

+1

Das ist so ziemlich mein Code https://gist.github.com/Odomontois/ea73f9bbfcb4cdc5f1b6 – Odomontois

Antwort

17

können Sie verwenden plusDays:

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

Da Start- und Enddaten:

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

danke, aber der Punkt ist, dass ich habe Start- und Enddatum –

+0

@GismoRanas hat die Antwort entsprechend aktualisiert. –

1

man so etwas verwenden:

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

Für nur von Tag zu iterieren, ich do:

Dies hat sich als nützlich genug sein, dass ich ein kleines Hilfsobjekt haben eine implizite und ermöglichen eine Art Transformation zu bieten:

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

Verwendungsbeispiel:

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

Lösung mit java.time API mit Scala

Notwendige Import und Initialisierung

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

val now = LocalDate.now 

erstellen Liste der LocalDate für die Probendauer

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

Iterate über spezifische Daten zwischen Anfang und Ende

//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

Bitte, nein, nicht 'java.util.Date' noch einmal ... Wir sind schon in scala. Aber 'java.util.Date' ist sogar in Java vor Jahren gestorben, und es gibt bereits eine akzeptierte Antwort mit' DateTime'. –