How do I implement a custom JodaTime\'s DateTime serializer/deserializer for JSON? I\'m inclined to use the Play Framework\'s JSON library (2.1.1). There is a default DateTi
There is a default DateTime serializer, but it uses dt.getMillis instead of .toString which would return an ISO compliant String.
If you look at the source, Reads.jodaDateReads already handles both numbers and strings using DateTimeFormatter.forPattern. If you want to handle ISO8601 string, just replace it with ISODateTimeFormat:
implicit val jodaISODateReads: Reads[org.joda.time.DateTime] = new Reads[org.joda.time.DateTime] {
import org.joda.time.DateTime
val df = org.joda.time.format.ISODateTimeFormat.dateTime()
def reads(json: JsValue): JsResult[DateTime] = json match {
case JsNumber(d) => JsSuccess(new DateTime(d.toLong))
case JsString(s) => parseDate(s) match {
case Some(d) => JsSuccess(d)
case None => JsError(Seq(JsPath() -> Seq(ValidationError("validate.error.expected.date.isoformat", "ISO8601"))))
}
case _ => JsError(Seq(JsPath() -> Seq(ValidationError("validate.error.expected.date"))))
}
private def parseDate(input: String): Option[DateTime] =
scala.util.control.Exception.allCatch[DateTime] opt (DateTime.parse(input, df))
}
(simplify as desired, e.g. remove number handling)
implicit val jodaDateWrites: Writes[org.joda.time.DateTime] = new Writes[org.joda.time.DateTime] {
def writes(d: org.joda.time.DateTime): JsValue = JsString(d.toString())
}