Alex Rivera | Logout

Scala/Lift check if date is correctly formatted

Asked 2011-05-12T18:16:48.550
9

I have a date input box in my lift application, and I want to check that a user-entered date is in correct format: dd/mm/yyyy.

How can I write a regex check for this in scala? I've looked at pattern matching examples - but that seems over-complicated.

PS: I don't have to use regex, any other alternatives are welcome!

Edit
Report

1 Answer

15

SimpleDateFormat is ugly and (more disturbingly) non-thread-safe. If you try to simultaneously use the same instance in 2 or more threads then expect things to blow up in a most unpleasant fashion.

JodaTime is far nicer:

import org.joda.time.format._
val fmt = DateTimeFormat forPattern "dd/MM/yyyy"
val input = "12/05/2009"
val output = fmt parseDateTime input

If it throws an IllegalArgumentException, then the date wasn't valid.

As I suspect you'll want to know the actual date if it was valid, you may want to return an Option[DateTime], with None if it was invalid.

def parseDate(input: String) = try {
  Some(fmt parseDateTime input)
} catch {
  case e: IllegalArgumentException => None
}

Alternatively, use an Either to capture the actual exception if formatting wasn't possible:

def parseDate(input: String) = try {
  Right(fmt parseDateTime input)
} catch {
  case e: IllegalArgumentException => Left(e)
}

UPDATE

To then use the Either, you have two main tactics:

map one of the two sides:

parseDate(input).left map (_.getMessage)
//will convert the Either[IllegalArgumentException, DateTime]
//to an Either[String, DateTime]

fold it:

parseDate(input) fold (
  _ => S.error(
    "birthdate",
    "Invalid date. Please enter date in the form dd/mm/yyyy."),
  dt => successFunc(dt)
)

Of course, the two can be composed:

parseDate(input).left map (_.getMessage) fold (
  errMsg => S.error("birthdate", errMsg), //if failure (Left by convention)
  dt => successFunc(dt) //if success (Right by convention)
)
answered 2011-05-17T16:01:24.510

Your Answer