2015-05-11 4 views
5

Учитывая начальную и конечную дату, я хотел бы перебирать ее по дням, используя карту foreach, карту или аналогичную функцию. Что-то вродеИтерация по датам (путь scala)

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

Я использую https://github.com/nscala-time/nscala-time, но я получаю возвратил объект Joda Interval, если я использую выше синтаксис, который я подозреваю, тоже не диапазон дат, а своего рода диапазон миллисекунд.

EDIT: вопрос устарел. Как указано на домашней странице joda, если вы используете java 8, вы должны начать с или перейти на java.time.

+0

Просто добавил 'nscala-time' (DateTime.now - DateTime.now + (5 дней) на (1 день)). foreach (println) '. Работает как магия – Odomontois

+0

Я получаю: значение не является членом org.joda.time.Interval –

+1

Это в значительной степени мой код https://gist.github.com/Odomontois/ea73f9bbfcb4cdc5f1b6 – Odomontois

ответ

17

Вы можете использовать plusDays:

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

С учетом даты начала и окончания:

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

спасибо, но дело в том, что у меня есть дата начала и окончания –

+0

@ GismoRanas соответственно обновил ответ. –

1

вы можете использовать что-то вроде этого:

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

Для только итерация днем, я do:

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

Это оказалось достаточно, что у меня есть небольшой вспомогательный объект для обеспечения неявной и позволяют типа преобразования полезно: Использование

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

Пример:

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

Solution с API java.time с использованием Scala

Необходимый импорт и инициализация

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

val now = LocalDate.now 

Создание списка LocalDate для продолжительности выборки

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

перебрать конкретных дат между началом и концом

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

Пожалуйста, нет, не 'java.util.Date' снова ... Мы уже в scala. Но 'java.util.Date' умер даже в Java несколько лет назад, и уже есть принятый ответ с' DateTime'. –

Смежные вопросы