简体   繁体   English

Play 2.6中的Joda DateTime格式无效

[英]Joda DateTime Format in Play 2.6 is not working

Trying to migrate my code to play 2.6 Everything is fine except the Format for DateTime type. 尝试迁移我的代码以播放2.6除了DateTime类型的格式外,一切都很好。

As part of the migration I did add the play-json-joda as dependency. 作为迁移的一部分,我确实添加了play-json-joda作为依赖。

However, something like this: 但是,这样的事情:

case class GeoArea(id: Option[Int] = None,
                   continentId: Option[Int] = None,
                   countryId: Option[Int] = None,
                   code: String,
                   name: String,
                   discr: Discriminator.Value,
                   createdAt: DateTime = DateTime.now,
                   updatedAt: DateTime = DateTime.now,
                   deletedAt: Option[DateTime] = None,
                   createdBy: Option[String] = None,
                   updatedBy: Option[String] = None)

With format object defined as: 格式对象定义为:

implicit lazy val geoAreaFormat: Format[GeoArea] = Json.format[GeoArea]

I am getting an error: 我收到一个错误:

No instance of play.api.libs.json.Format is available for org.joda.time.DateTime, org.joda.time.DateTime, scala.Option[org.joda.time.DateTime] in the implicit scope (Hint: if declared in the same file, make sure it's declared before) [error] 没有play.api.libs.json.Format的实例可用于隐式作用域中的org.joda.time.DateTime,org.joda.time.DateTime,scala.Option [org.joda.time.DateTime](提示:如果在同一个文件中声明,请确保它在之前声明)[错误]
implicit lazy val geoAreaFormat: Format[GeoArea] = Json.format[GeoArea] 隐式lazy val geoAreaFormat:格式[GeoArea] = Json.format [GeoArea]

What am I missing? 我错过了什么? What else do I need to have in scope to resolve that? 我还需要在范围内解决这个问题吗?

My imports look like this: 我的导入如下:

import driver.PGDriver.api._
import org.joda.time.DateTime
import play.api.libs.json._
import slick.lifted.Tag
import model.GeoAreas.Discriminator
import converters.{JsonEnumeration, SlickEnumeration}

And they didn't change as during the migration, but these ones were enough for everything to work. 并且它们在迁移过程中没有发生变化,但这些变化足以让一切顺利进行。

In your build.sbt add this: 在你的build.sbt中添加:

libraryDependencies += "com.typesafe.play" % "play-json-joda_2.12" % "2.6.0"

then in file with your model import this: 然后在你的模型文件中导入:

import play.api.libs.json.JodaWrites._
import play.api.libs.json.JodaReads._

I've run into this inconvenience as well moving to the new library. 我遇到了这种不便,也搬到了新的图书馆。 You can work around it by creating an implicit format based on their new defaults. 您可以通过基于新默认值创建隐式格式来解决此问题。

implicit val dateFormat = new OFormat[DateTime] {
    override def reads(json: JsValue): JsResult[DateTime] = JodaReads.DefaultJodaDateTimeReads.reads(json)
    override def writes(o: DateTime): JsValue = JodaWrites.JodaDateTimeWrites.writes(o)
}

Do note however that the above doesn't include the old default writes which used epoch millis . 请注意,上述内容不包括使用epoch millis的旧默认写入 To ensure your migration doesn't break existing functionality, you probably want to hold the old defaults: 为确保您的迁移不会破坏现有功能,您可能希望保留旧的默认值:

implicit val dateFormatDefault = new Format[DateTime] {
    override def reads(json: JsValue): JsResult[DateTime] = JodaReads.DefaultJodaDateTimeReads.reads(json)
    override def writes(o: DateTime): JsValue = JodaDateTimeNumberWrites.writes(o)
}

This is because the old default in play-json used the millis ( https://github.com/playframework/play-json/blob/master/play-json/jvm/src/main/scala/play/api/libs/json/EnvWrites.scala#L326-L328 ): 这是因为play-json中的旧默认值使用了millis( https://github.com/playframework/play-json/blob/master/play-json/jvm/src/main/scala/play/api/libs/ json / EnvWrites.scala#L326-L328 ):

@deprecated("Include play-json-joda as a dependency and use JodaWrites.JodaDateNumberWrites", "2.6.0")
object DefaultJodaDateWrites extends Writes[DateTime] {
    def writes(d: DateTime): JsValue = JsNumber(d.getMillis)
}

And the the new default uses ISO8601 ( https://github.com/playframework/play-json/blob/b4f812df628787e2d83131ceafbecb0d6d769704/play-json-joda/src/main/scala/play/api/libs/json/JodaWrites.scala#L33-L35 ): 而新的默认值使用ISO8601( https://github.com/playframework/play-json/blob/b4f812df628787e2d83131ceafbecb0d6d769704/play-json-joda/src/main/scala/play/api/libs/json/JodaWrites.scala# L33-L35 ):

/**
 * Default Serializer LocalDate -> JsString(ISO8601 format (yyyy-MM-dd))
 */
implicit object JodaDateTimeWrites extends Writes[DateTime] {
   def writes(d: DateTime): JsValue = JsString(d.toString)
}

You should use nscala-time time which is a wrapper of Joda 你应该使用nscala-time time,它是Joda的包装器

Then for a Json formatter you create this object 然后,对于Json格式化程序,您可以创建此对象

package formatters

import org.joda.time.{DateTime, DateTimeZone}
import org.joda.time.format.ISODateTimeFormat
import play.api.libs.json.{JsString, JsSuccess, JsValue, Format}

object DateTimeFormatter {
  private lazy val ISODateTimeFormatter = ISODateTimeFormat.dateTime.withZone(DateTimeZone.UTC)
  private lazy val ISODateTimeParser = ISODateTimeFormat.dateTimeParser

  implicit val dateTimeFormatter = new Format[DateTime] {
    def reads(j: JsValue) = JsSuccess(ISODateTimeParser.parseDateTime(j.as[String]))
    def writes(o: DateTime): JsValue = JsString(ISODateTimeFormatter.print(o))
  }
}

And in your companion object 并在你的伴侣对象

object GeoArea {
  import formatters.DateTimeFormatter._
  implicit val geoAreaFormat = Json.format[GeoArea]
}

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

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