在Play 2.3.7框架中使用DateTime

时间:2014-12-12 09:01:57

标签: json scala datetime playframework-2.0

我正在寻找一个干净的解决方案来在Play框架中使用datetime。具体来说,我需要在数据库中保留datetime,将该datetime转换为Scala对象,并将该datetime转换为Json和从Json转换。

例如,我正在制作像eBay这样的竞价服务,所以我希望保持创建项目的时间,以及竞标时间结束的时间。我有一个这样的简单模型:

case class Item(name: String, description: String, start: DateTime, end: DateTime)

由于Slick不支持Joda DateTime,我使用MappedColumnType在java.sql.Timestamp和Joda DateTime之间进行转换。这是微不足道的,但如果有更好的解决方案我会很感激。

我之所以使用Joda DateTime而不是java.sql.Timestamp是因为Play现在知道如何将时间戳写入Json,而我在网上找到的所有解决方案都需要大量修补代码。

随着Joda DateTime到位,我又遇到了另一个问题。播放将DateTime写为长号,这很好,但首选完整格式日期。问题是客户端只能在没有时间和时区的情况下将DateTime提交为“yyyy-MM-dd”。

到目前为止,这是我的尝试:

 implicit val itemFormatter = (
    (__ \ "ean").format[Long] and
      (__ \ "description").format[String] and
      (__ \ "start").format[DateTime] and
      (__ \ "end").format[DateTime]
    )(Item.apply _, unlift(Item.unapply))

  val userDateFormatter = "dd/MM/yyyy HH:mm:ss"
  implicit val jodaDateTimeReads = Reads.jodaDateReads(userDateFormatter)
  implicit val jodaDateTimeWrites = Writes.jodaDateWrites(userDateFormatter)
  implicit val jodaDateTimeFormats = Format(jodaDateTimeReads, jodaDateTimeWrites)

尝试使用上述格式发布时间时收到的错误消息是:

error.expected.jodadate.format,WrappedArray(yyyy-MM-dd)

这在Ruby / Rails等其他langs /框架中似乎是一件微不足道的事情,但我觉得Scala严重缺乏日期和时间支持。

1 个答案:

答案 0 :(得分:3)

我找到了一个简单的解决方案。基本上我必须覆盖DateTime的默认读取和写入,如下所示:

# If you use Timestamp
implicit val tsreads: Reads[Timestamp] = Reads.of[Long] map (new Timestamp(_))
implicit val tswrites: Writes[Timestamp] = Writes { (ts: Timestamp) => JsString(ts.toString)}

# If you use DateTime
implicit val tsreads: Reads[DateTime] = Reads.of[String] map (new DateTime(_))
implicit val tswrites: Writes[DateTime] = Writes { (dt: DateTime) => JsString(dt.toString)}