Similar to the previous post Reading Sequences of Scala classes in Play JSON, I found some issues when trying to parse and write Timestamp using the JSON module from Play Framework.

The objective

I want to be able to write and read Timestamp format. I have no requirement on how it has to be serialized.

The issue

I am using the code from the previous post, but changing slightly the type of a field. In accordance, I created a Format[Timestamp] as the logic would state.

case class Checkpoint(line: String, operador: String, lastStatusPubDate: Timestamp)
implicit val tsFormat: Format[Timestamp] = Json.format[Timestamp]
implicit val checkpointFormat = [...]

When executing the code, it raises a similar error I had with the sequences:

Error:(27, 59) No apply function found for java.sql.Timestamp
    implicit val tsFormat: Format[Timestamp] = Json.format[Timestamp]

The solution

This time, the way to solve it is a bit different. We shall provide a conversion from Timestamp to a more basic datatpe. For example Long. Another option could be to transform it to a SimpleDateFormat type and write the date as string. This is up to you. Adding somethin similar to the following code before declaring the Format[Checkpoint] implicit is enough for it to work.

def timestampToLong(t: Timestamp): Long = t.getTime
def longToTimestamp(dt: Long): Timestamp = new Timestamp(dt)

implicit val timestampFormat: Format[Timestamp] = new Format[Timestamp] {
  def writes(t: Timestamp): JsValue = Json.toJson(timestampToLong(t))
  def reads(json: JsValue): JsResult[Timestamp] = Json.fromJson[Long](json).map(longToTimestamp)
}

Result:

[{"line":"R8","operador":"Generalitat/Renfe","lastStatusPubDate":1535953200000},{"line":"R1","operador":"Generalitat/Renfe","lastStatusPubDate":1540744360000}]
List(Checkpoint(R8,Generalitat/Renfe,2018-09-03 07:40:00.0), Checkpoint(R1,Generalitat/Renfe,2018-10-28 17:32:40.0))