Removing implicit definitions of Reads/Writes[org.joda.time.DateTime] from play-json

365 views
Skip to first unread message

Dave Stevens

unread,
Mar 11, 2015, 10:34:28 PM3/11/15
to play-fr...@googlegroups.com
The existence of implicit definitions, Reads[org.joda.time.DateTime] and Writes[org.joda.time.DateTime] in play-json have caused bugs for me at two different companies now. I forsee encountering more bugs caused by these implicit definitions in my future. I would like to propose they be deprecated and made non-implicit. A compromise would be to put the joda-time implicits in another scala object "Implicits", forcing users to import them explicitly and preventing them from being resolved by default. I would be very happy to submit a PR with this compromise if it would be accepted.

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))))))

The demonstration above uses "com.typesafe.play" %% "play-json" % "2.3.2", but this behavior exists in master.

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.

Dave Stevens

unread,
Jun 5, 2015, 6:10:37 PM6/5/15
to play-fr...@googlegroups.com
I would like to re-raise my previous suggestion to remove the implicit definitions for Reads[org.joda.time.DateTime] and Writes[org.joda.time.DateTime] from play-json. While going through commits in a local non-profit's project, I noticed one of their more recent commits was to fix a bug resulting from the existence of these implicit definitions.
Reply all
Reply to author
Forward
0 new messages