開始日と終了日を考慮して、foreach、map、または同様の関数を使用して、日ごとに繰り返したいと思います。何かのようなもの
(DateTime.now to DateTime.now + 5.day by 1.day).foreach(println)
https://github.com/nscala-time/nscala-time を使用していますが、上記の構文を使用するとjoda Intervalオブジェクトが返されます。日付ですが、一種のミリ秒の範囲です。
編集:質問は時代遅れです。 joda ホームページでアドバイスされているように、Java 8を使用している場合は、 Java.time から始めるか移行する必要があります。
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)
日ごとに繰り返すために、私はします:
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
Scalaを使用したJava.time APIのソリューション
必要なインポートと初期化
_import Java.time.temporal.ChronoUnit
import Java.time.temporal.ChronoField.Epoch_DAY
import Java.time.{LocalDate, Period}
val now = LocalDate.now
val daysTill = 5
_
サンプル期間のLocalDate
のリストを作成
_(0 to daysTill)
.map(days => now.plusDays(days))
.foreach(println)
_
toEpochDay
またはgetLong(ChronoField.Epoch_DAY)
を使用して、開始と終了の間の特定の日付を反復します
_//Extract the duration
val endDay = now.plusDays(daysTill)
val startDay = now
val duration = endDay.getLong(Epoch_DAY) - startDay.getLong(Epoch_DAY)
/* This code does not give desired results as trudolf pointed
val duration = Period
.between(now, now.plusDays(daysTill))
.get(ChronoUnit.DAYS)
*/
//Create list for the duration
(0 to duration)
.map(days => now.plusDays(days))
.foreach(println)
_
この回答は、mrsrinivas回答の問題を修正します。.get(ChronoUnits.DAYS)
は、期間の日部分のみを返し、合計日数は返しません。
必要なインポートと初期化
import Java.time.temporal.ChronoUnit
import Java.time.{LocalDate, Period}
上記の答えが間違った結果につながる方法に注意してください(合計日数は117です)
scala> Period.between(start, end)
res6: Java.time.Period = P3M26D
scala> Period.between(start, end).get(ChronoUnit.DAYS)
res7: Long = 26
開始と終了の間の特定の日付を反復します
val start = LocalDate.of(2018, 1, 5)
val end = LocalDate.of(2018, 5, 1)
// Create List of `LocalDate` for the period between start and end date
val dates: IndexedSeq[LocalDate] = (0L to (end.toEpochDay - start.toEpochDay))
.map(days => start.plusDays(days))
dates.foreach(println)
あなたはそのようなものを使うことができます:
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)))
}
この場合、Scala way
はJava way
です。
Java 9+
でScala
を実行する場合、 Java.time.LocalDate::datesUntil
を使用できます。
import Java.time.LocalDate
import collection.JavaConverters._
// val start = LocalDate.of(2019, 1, 29)
// val end = LocalDate.of(2018, 2, 2)
start.datesUntil(end).iterator.asScala
// Iterator[Java.time.LocalDate] = <iterator> (2019-01-29, 2019-01-30, 2019-01-31, 2019-02-01)
最後の日付を含める場合:
start.datesUntil(end.plusDays(1)).iterator.asScala
// 2019-01-29, 2019-01-30, 2019-01-31, 2019-02-01, 2019-02-02
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
}