简体   繁体   English

在游戏中将Json转换为Joda DateTime! 斯卡拉2.5

[英]Convert Json to Joda DateTime in Play! scala 2.5

I have read this question (and the other ones on SO), but I still don't manage to convert a JsValue to a case class with a Joda DateTime. 我已经阅读了这个问题 (以及关于SO的其他问题),但是我仍然无法通过Joda DateTime将JsValue转换为案例类。

Here is the JSON I have: 这是我拥有的JSON:

val json = Json.parse(
    """
    {
        "message": "Bla bla bla",
        "updated_time": "2016-09-17T12:48:12+0000"
    }
    """
)

And the corresponding case class is: 相应的案例类是:

import org.joda.time.DateTime
final case class FacebookPost(message: String, updated_time: DateTime)

I also added this implicit DateTime reader (I tried some other as well): 我还添加了此隐式DateTime阅读器(我也尝试了其他方法):

 implicit val readsJodaLocalDateTime = Reads[DateTime](js =>
        js.validate[String].map[DateTime](dtString => new DateTime(dtString)))

But when I try to convert my json to the corresponding case class ( json.as[FacebookPost] ), I get this error: 但是,当我尝试将json转换为相应的case类( json.as[FacebookPost] )时,出现以下错误:

play.api.libs.json.JsResultException: `JsResultException(errors:List((/updated_time,List(ValidationError(List(error.expected.jodadate.format),WrappedArray(yyyy-MM-dd))))))`

What am I doing wrong? 我究竟做错了什么?

Your problem is the format of your datetime: 2016-09-17T12:48:12+0000 . 您的问题是日期时间的格式: 2016-09-17T12:48:12+0000

By default, Joda's DateTime class can't automatically figure out the format you're using, so you have to provide a hint using DateTimeFormat . 默认情况下,Joda的DateTime类无法自动确定您使用的格式,因此您必须使用DateTimeFormat提供提示。

Example for our custom Reads[DateTime] : 我们的自定义Reads[DateTime]示例:

import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._ 

val dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"

val customReads = Reads[DateTime](js =>
  js.validate[String].map[DateTime](dtString =>
    DateTime.parse(dtString, DateTimeFormat.forPattern(dateFormat))
  )
)

implicit val reads: Reads[FacebookPost] = (
  (__ \ "message").read[String] and
  (__ \ "updated_time").read[DateTime](customReads)
)(FacebookPost.apply _)

Then, it's possible to do the following: 然后,可以执行以下操作:

val json = Json.parse(
  """
    {
      "message": "Bla bla bla",
      "updated_time": "2016-09-17T12:48:12+0000"
    }
   """)

val post = json.validate[FacebookPost] 
// => JsSuccess(FacebookPost(Bla bla bla,2016-09-17T14:48:12.000+02:00))

edit: 编辑:

You don't need to create the Read[DateTime] from scratch, there is a predefined method in Play that helps you with that: 您无需从头开始创建Read[DateTime] ,Play中有一个预定义的方法可以帮助您:

object CustomReads /* or wherever you want to define it */ {
  val dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
  implicit val jodaDateReads = play.api.libs.json.Reads.jodaDateReads(dateFormat)
}

Done. 完成。 Just import whenever you need it, eg in the companion object of your model classes: 只需在需要时导入即可,例如在模型类的伴随对象中:

object FacebookPost {
  import utils.CustomReads._
  implicit val reads: Reads[FacebookPost] = Json.reads[FacebookPost]
}

You can "override" the implicit Read[DateTime] provided by Play by exluding it from your imports: 您可以通过从导入中删除它来“替代” Play提供的隐式Read[DateTime]

import play.api.libs.json.Reads.{DefaultJodaDateReads => _, _}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM