Scala 如何在Lift中反序列化DateTime

Scala 如何在Lift中反序列化DateTime,scala,datetime,lift,datetime-format,Scala,Datetime,Lift,Datetime Format,我无法将JSON中的org.joda.time.DateTime字段反序列化到case类中 JSON: val-ajson=parse(“{”creationDate:“2013-01-02T10:48:41.000-05:00“}”) 我还设置了这些序列化选项: implicit val formats=Serialization.formats(notypehitts)++net.liftweb.json.ext.JodaTimeSerializers.all 反序列化: val val1=

我无法将JSON中的org.joda.time.DateTime字段反序列化到case类中

JSON:
val-ajson=parse(“{”creationDate:“2013-01-02T10:48:41.000-05:00“}”)

我还设置了这些序列化选项:
implicit val formats=Serialization.formats(notypehitts)++net.liftweb.json.ext.JodaTimeSerializers.all

反序列化:
val val1=ajson.extract[Post]

发布位置:
case类Post(
creationDate
:DateTime){…}

我得到的例外是:

 net.liftweb.json.MappingException: No usable value for creationDate
    Invalid date format 2013-01-02T10:48:41.000-05:00
如何将该日期字符串反序列化为DateTime对象

编辑:
这是有效的:
val date3=新的日期时间(“2013-01-05T06:24:53.000-05:00”)

它使用JSON中与反序列化中相同的日期字符串。这里发生了什么?

似乎是Lift默认使用的
DateParser
格式。在深入研究中,您可以看到解析器在将结果传递给
org.joda.time.DateTime
的构造函数之前尝试使用
DateParser.parse(s,format)

object DateParser {
  def parse(s: String, format: Formats) = 
    format.dateFormat.parse(s).map(_.getTime).getOrElse(throw new MappingException("Invalid date format " + s))
}

case object DateTimeSerializer extends CustomSerializer[DateTime](format => (
  {
    case JString(s) => new DateTime(DateParser.parse(s, format))
    case JNull => null
  },
  {
    case d: DateTime => JString(format.dateFormat.format(d.toDate))
  }
))
Lift似乎使用的格式是:
yyyy-MM-dd'T:HH:MM:ss.SSS'Z'

为了解决这个问题,您可以指定正确的模式并将其添加到序列化选项中,或者如果您希望让JodaTime构造函数完成所有工作,您可以创建自己的序列化程序,如:

case object MyDateTimeSerializer extends CustomSerializer[DateTime](format => (
  {
    case JString(s) => tryo(new DateTime(s)).openOr(throw new MappingException("Invalid date format " + s))
    case JNull => null
  },
  {
    case d: DateTime => JString(format.dateFormat.format(d.toDate))
  }
))

然后将其添加到格式列表中,而不是
net.liftweb.json.ext.jodaTimeSerializer。所有

可能不是100%优雅,但只是几行,可读性很强,可以工作:

val SourISODateTimeFormat = DateTimeFormat.forPattern("YYYY-MM-dd'T'HH:mm:ss.SSSZ")
val IntermediateDateTimeFormat = DateTimeFormat.forPattern("YYYY-MM-dd'T'HH:mm:ss'Z'")

def transformTimestamps(jvalue: JValue) = jvalue.transform {
  case JField(name @ ("createdTime" | "updatedTime"), JString(value)) =>
    val dt = SourceISODateTimeFormat.parseOption(value).get
    JField(name, JString(IntermediateDateTimeFormat.print(dt)))
}

我有两个后续问题:(1)这是“YYYY-MM-dd'T'HH:MM:ss.SSS'-'Z”我的日期格式,如“2013-01-02T10:48:41.000-05:00”(2)这是将我的格式添加到格式中的正确方法吗:`隐式val格式=序列化。格式(非类型提示)+MyDateTimeSerializerfigured out(2):将MyDateTimeSerializer包装在一个列表中:对于那些感兴趣的人来说,它看起来是这样的:
implicit val formats=Serialization.formats(notypeHights)++list(MyDateTimeSerializer)
我对DateFormat模式的所有复杂之处都不太熟悉,但您的建议看起来很接近。有两件事,年份应该是小写的
y
,并且“-”是时区的一部分(即从UTC算起的-5小时),因此您可能应该删除它
yyyy-MM-dd'HH:MM:ss.SSSZ
可能与您要查找的内容很接近,但这可能与TZ中的
有关。至于添加自定义序列化程序,将其包装在
列表中应该对您有用。好的,我使用了(2),但它不起作用,但我认为解析很好,但是JSON字符串中可能有一些需要转义的时髦字符。我推断是因为它可以
新的日期时间(parse(“{”creationDate:“2013-01-05T06:24:53.000-05:00“}”)。extract[Post3].creationDate)
但是当用户输入JSON时,它不起作用
val date3=新的日期时间(parse(Text(name.toString()).extract[Post3].creationDate)