Milap Jhumkhawala
Milap Jhumkhawala

Reputation: 327

Extract Dates and compare them from string in Scala

I am trying to extract date from string and compare them. I am new to Scala. The string : Some(Date: Tue, 14 Aug 2018 20:57:42 GMT)Some(Last-Modified: Tue, 14 Aug 2018 20:57:24 GMT) I wish to comapare Date and Last Modified

Upvotes: 1

Views: 1307

Answers (2)

jacks
jacks

Reputation: 4783

Extract the Dates if working with Option

There are several Scala wrappers for the Java Time API but the example below just uses the Java API directly.

val someDate: Option[String] = Some("Date: Tue, 14 Aug 2018 20:57:42 GMT")
val someLastMod: Option[String] = Some("Last-Modified: Tue, 14 Aug 2018 20:57:24 GMT")

The we extract the meaningful date substrings ie. we remove the "Date: "

val dateStr = someDate.get.split("^[\\w\\-]+:")(1).trim
val lastModStr = someLastMod.get.split("^[\\w\\-]+:")(1).trim

You should note that the above uses get() which assumes you can guarantee you will always have a Some and never a None. You should read up on working with Option in Scala if you don't understand this point.

Extract the Dates if working with a String

val data = "Some(Date: Tue, 14 Aug 2018 20:57:42 GMT)Some(Last-Modified: Tue, 14 Aug 2018 20:57:24 GMT)"

First we extract just the string dates we are interested in. The following expression uses split to create an array of strings, which we filter over to remove any empty strings before finally mapping over whats left and using take to remove the trailing parenthesis )

val dates = data.split("Some\\([\\w\\-]+:*\\s").filter(_.nonEmpty).map(_.take(29))

// dates: Array[String] = Array(Tue, 14 Aug 2018 20:57:42 GMT, Tue, 14 Aug 2018 20:57:24 GMT)

Now we extract each date string from the array.

val dateStr = dates(0)
val lastModStr = dates(1)

Now use the Java Time API to do comparisons.

Now we start to use the Java time API. First you need to import the Java packages.

import java.time._
import java.time.format._

Now create a formatter to match your DateTime pattern in order to convert the Strings to LocalDateTime instances.

val formatter = DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss z")    

val date = LocalDateTime.parse(dateStr, formatter)
val lastMod = LocalDateTime.parse(lastModStr, formatter)

Do some comparisons using the LocalDateTime API.

date.isBefore(lastMod)
date.isAfter(lastMod)

Check out the LocalDateTime docs for more ways to compare them.

Consider this

Will the format for the Dates always be in the same pattern? If not, you will need to think about how you will handle different patterns otherwise you will run into runtime exceptions (DateTimeParseException). Read more in the docs

Upvotes: 2

jwvh
jwvh

Reputation: 51271

Are you really trying to parse data that looks like this?

val badString = "Some(Date: Tue, 14 Aug 2018 20:57:42 GMT)Some(Last-Modified: Tue, 14 Aug 2018 20:57:24 GMT)"

Whoever thought that might be a reasonable way to represent data should go back to school (grade school). But it can be done. First let's try to segregate the data elements we're interested in, and remove some of the cruft along the way.

val inArray :Array[String] = badString.split("Some[^:]+: ")
//inArray: Array[String] = Array("", "Tue, 14 Aug 2018 20:57:42 GMT)", "Tue, 14 Aug 2018 20:57:24 GMT)")

Next we need to describe the date/time format that we're dealing with. Note that we have to account for a trailing paren ) in the data.

import java.time.format.DateTimeFormatter
val dtFormatter = DateTimeFormatter.ofPattern("E, dd MMM yyyy HH:mm:ss z)")

Now we can turn all the good data into Java LocalDateTime elements. Any Array elements that don't match the DateTimeFormatter pattern are removed.

import util.Try
import java.time.LocalDateTime
val dates :Array[LocalDateTime] = inArray.flatMap{ dateStr =>
  Try(LocalDateTime.parse(dateStr.trim, dtFormatter)).toOption
}

So now you can extract the dates, if any, from the dates array and compare them using the LocalDateTime API.

Upvotes: 1

Related Questions