This is a contrived example to illustrate the point. I know I could use LocalDate and LocalTime to help here in place of DateTime, but that would miss the point of the question which is how generally to process the field values in some way before writing them out.
case class Test(
id: Long, dateOnly: DateTime, timeOnly: DateTime, comments: Option[String])
To write this as JSON I start with this:
implicit val testWrites: Writes[Test] = (
(__ \ "id" ).write[Long] and
(__ \ "dateOnly" ).write[DateTime] and
(__ \ "timeOnly" ).write[DateTime] and
(__ \ "comments" ).write[Option[String]]
)(unlift(Test.unapply))
Also, assume an object instance where there are no comments.
This will output something like:
{"id": 123,
"dateOnly": "1409952730536",
"timeOnly": "1409953948034",
"comments": null}
There is a default Writes implementation for DateTime that outputs the value as milliseconds.
What I want to output is something like this:
{"id": 123,
"dateOnly": "2014-03-08",
"timeOnly": "15:24",
"comments": ""}
So I figure I need to process the dateOnly, timeOnly and comments field values via a function invocation to get exactly what I want before the final JSON value is written out.
I need at least a custom Writes with a pattern for DateTime, something like this:
def dateTimeWrites(pattern: String): Writes[DateTime] = new Writes[DateTime] {
def writes(d: DateTime): JsValue = JsString(d.toString(pattern))
}
I can not see how I am supposed to incorporate this custom Writes implementation into the Test Writes implementation, nor can I see how I would specify the two different patterns for the two different date/time fields.
I also can not see how to emit an empty string rather than null for the comments - writeNullable would omit the comments field entirely and I don't want that.
Given that after much searching I can't seem to find any comprehensible examples of what I'm trying to do, I suspect my approach is wrong.