scala 如何在 Play Json 中使用 Joda DateTime

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31462673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 07:21:46  来源:igfitidea点击:

How to use Joda DateTime with Play Json

jsonscalaplayframework-2.0jodatime

提问by Guillaume

I'm developing a Play application, and I'm trying to use a Joda DateTime object into my case class.

我正在开发一个 Play 应用程序,我试图在我的案例类中使用一个 Joda DateTime 对象。

package model

import org.joda.time.DateTime
import play.api.libs.json._

case class User(name: String, created: DateTime)

object User {
  implicit val yourJodaDateReads = Reads.jodaDateReads("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
  implicit val yourJodaDateWrites = Writes.jodaDateWrites("yyyy-MM-dd'T'HH:mm:ss.SSSZ'")
  implicit val userFormat = Json.format[User]

  def main(args: Array[String]) {

  val value = Json.parse("{ \"name\" : \"hello\" , \"created\" : \"2015-07-16T20:32:04.046+02:00\" }")

  println(Json.toJson(new User("user", new DateTime())))
  println(Json.fromJson(value))
 }
}

Based on this solution, I'm getting this error:

基于此解决方案,我收到此错误:

Error:(18, -1) Play 2 Compiler: 
 /activator-1.3.2/notifier-app/app/model/Test.scala:18: ambiguous implicit    values:
 both value yourJodaDateReads in object User of type => play.api.libs.json.Reads[org.joda.time.DateTime]
    and value userFormat in object User of type => play.api.libs.json.OFormat[model.User]

I'm using Activator 1.3.2 and Play 2.3.8.

我正在使用 Activator 1.3.2 和 Play 2.3.8。

Could you please advice me ?

你能给我建议吗?

Thanks in advance.

提前致谢。

update

更新

I understand there is a conflict with the implicit value in play.api.libs.json.Reads

我知道与play.api.libs.json.Reads 中的隐含值存在冲突

implicit val DefaultJodaDateReads = jodaDateReads("yyyy-MM-dd") 

How can I resolve this issue ?

我该如何解决这个问题?

回答by Guillaume

Expecting a better alternative, here my workaround:

期待更好的选择,这里是我的解决方法:

val dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

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

val jodaDateWrites: Writes[DateTime] = new Writes[DateTime] {
  def writes(d: DateTime): JsValue = JsString(d.toString())
}

val userReads: Reads[User] = (
  (JsPath \ "name").read[String] and
    (JsPath \ "created").read[DateTime](jodaDateReads)
  )(User.apply _)

val userWrites: Writes[User] = (
  (JsPath \ "name").write[String] and
   (JsPath \ "created").write[DateTime](jodaDateWrites)
  )(unlift(User.unapply))

implicit val userFormat: Format[User] = Format(userReads, userWrites)

回答by Moebius

In play 2.6, the canonical way to serialize/deserialize joda DateTime json is by using the play-json-jodalibrary. Import the libraryby updating your build.sbt. Then create json reader and json writers like this :

在 play 2.6 中,序列化/反序列化 joda DateTime json 的规范方法是使用play-json-joda库。导入库的更新build.sbt。然后像这样创建 json reader 和 json writers:

import play.api.libs.json.JodaWrites
implicit val dateTimeWriter: Writes[DateTime] = JodaWrites.jodaDateWrites("dd/MM/yyyy HH:mm:ss")
import play.api.libs.json.JodaReads
implicit val dateTimeJsReader = JodaReads.jodaDateReads("yyyyMMddHHmmss")

回答by jakehschwartz

I know this question has been answered for a while, but I found a more concise answer

我知道这个问题已经回答了一段时间,但我找到了一个更简洁的答案

val pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
implicit val dateFormat = Format[DateTime](Reads.jodaDateReads(pattern), Writes.jodaDateWrites(pattern))
implicit val userFormat = Json.format[User]

回答by Evghenii Todorov

I think you should set the Usertype in Json.toJsonand Json.fromJsonfunctions. Instead of

我认为您应该设置User类型Json.toJsonJson.fromJson功能。代替

println(Json.toJson(new User("user", new DateTime())))
println(Json.fromJson(value))

try:

尝试:

println(Json.toJson[User](new User("user", new DateTime())))
println(Json.fromJson[User](value))

When you set the type explicitly framework will know what reads/writes to use.

当您显式设置类型时,框架将知道要使用的读/写。

Update:It is not necessarily to set type for Json.toJsonfunction because you pass Userobject as function argument and framework determines the type in runtime. But for Json.fromJson[User]you must set the type, otherwise framework doesn't know type of the object you want to read.

更新:不一定要为Json.toJson函数设置类型,因为您将User对象作为函数参数传递,框架在运行时确定类型。但是因为Json.fromJson[User]您必须设置类型,否则框架不知道您要读取的对象的类型。