Combining datetime ranges at the end of the day and the beginning of the next day

Here is my input

case class DateRange(sd:DateTime,ed:DateTime) val sd1 = DateTime.parse("2016-04-04T20:00:00.000Z") val ed1 = DateTime.parse("2016-04-04T23:59:59.999Z") val sd2 = DateTime.parse("2016-04-05T00:00:00.000Z") val ed2 = DateTime.parse("2016-04-05T05:00:00.000Z") val sd3 = DateTime.parse("2016-04-05T20:00:00.000Z") val ed3 = DateTime.parse("2016-04-05T23:59:59.999Z") val sd4 = DateTime.parse("2016-04-06T00:00:00.000Z") val ed4 = DateTime.parse("2016-04-06T05:00:00.000Z") val sd5 = DateTime.parse("2016-04-07T10:00:00.000Z") val ed5 = DateTime.parse("2016-04-07T15:00:00.000Z") val drList = List(DateRange(sd1,ed1),DateRange(sd2,ed2),DateRange(sd3,ed3),DateRange(sd4,ed4),DateRange(sd5,ed5)) 

The desired result I'm looking for is

 val res = List(DateRange(sd1,ed2),DateRange(sd3,ed4),DateRange(sd5,ed5)) 

Here ed1, ed3 is the end of the day, and sd1, sd3 is the beginning of the day for the corresponding dates. I want to combine such ranges as we can see in the desired output above.

I tried partitioning as follows

  val result = drList.partition(x => x.sd.isEqual(x.sd.withTimeAtStartOfDay()) || x.ed.isEqual(x.ed.withTime(LocalTime.parse("23:59:59"))))) 

But it doesnโ€™t work out how to combine the result. Thanks in advance.

+5
source share
1 answer

You can use zip to get the result:

 val res = if(drList.size < 2 ) { drList } else { drList zip drList.drop(1) map { case (prevRes, nexRes) => if (prevRes.ed.plusMillis(1) == nexRes.sd) prevRes.copy(ed = nexRes.ed) else DateRange(sd1, sd1) } res.filter(x => x.sd != x.ed) } 

Here sd1 is any datetime that the else part should have and filtered for the last time.

+2
source

Source: https://habr.com/ru/post/1247576/


All Articles