The provided default definitions are not acceptable in many circumstances because
1. The definition of Writes[org.joda.time.DateTime] is lossy
2. The definition of Reads[org.joda.time.DateTime] does not accept full ISO 8601 date and time
e.g.
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import play.api.libs.json._
import play.api.libs.json._
scala> import org.joda.time.{DateTime, DateTimeZone}
import org.joda.time.{DateTime, DateTimeZone}
scala> val a = new DateTime().withZone(DateTimeZone.UTC)
a: org.joda.time.DateTime = 2015-03-12T02:13:42.284Z
scala> Json.toJson(a)
res0: play.api.libs.json.JsValue = 1426126422284
scala> val b = Json.fromJson[DateTime](Json.toJson(a)).get
b: org.joda.time.DateTime = 2015-03-11T22:13:42.284-04:00
scala> a == b
res1: Boolean = false
scala> Json.fromJson[DateTime](Json.parse("\"2015-03-12\""))
res2: play.api.libs.json.JsResult[org.joda.time.DateTime] = JsSuccess(2015-03-12T00:00:00.000-04:00,)
scala> Json.fromJson[DateTime](Json.parse("\"2015-03-11T22:13:42.284-04:00\""))
res3: play.api.libs.json.JsResult[org.joda.time.DateTime] = JsError(List((,List(ValidationError(error.expected.jodadate.format,WrappedArray(yyyy-MM-dd))))))
Having existing knowledge of this issue, I typically wrap date times in new types such as "case class IsoDateTime(v: DateTime)" or "DateTime @@ IsoDateTime" in order to drive the json serialization format. Inevitably, a plain DateTime slips through an API definition because of time, inexperience or mistake.