Scala 如何通过fromJson(toJson(date))与specs2匹配日期

Scala 如何通过fromJson(toJson(date))与specs2匹配日期,scala,jodatime,specs2,playframework-2.1,Scala,Jodatime,Specs2,Playframework 2.1,我陷入了以下问题:我想写一个specs2规范来断言我的到json和从json的转换是对称的。但是,我在joda datetime日期上出错 '2012-04-17T00:04:00.000+02:00' is not equal to '2012-04-17T00:04:00.000+02:00'. Values have the same string representation but possibly different types like List[Int] and List[Str

我陷入了以下问题:我想写一个specs2规范来断言我的到json和从json的转换是对称的。但是,我在joda datetime日期上出错

'2012-04-17T00:04:00.000+02:00' is not equal to '2012-04-17T00:04:00.000+02:00'. Values have the same string representation but possibly different types like List[Int] and List[String] (TimeSpecs.scala:18) 
下面是一个极简主义的规范来说明这个问题

import org.joda.time.DateTime
import org.specs2.mutable.Specification

class TimeSpecs extends Specification {
  "joda and specs2" should {
    "play nice" in {
      val date = DateTime.parse("2012-04-17T00:04:00+0200")
      val date2 = DateTime.parse("2012-04-17T00:04:00+0200")
      date === date2
    }
    "play nice through play json transform" in {
      import play.api.libs.json._
      import play.api.libs.json.Json._
      val date = DateTime.parse("2012-04-17T00:04:00+0200")
      val jsDate= toJson(date)
      val date2= jsDate.as[DateTime]

      date === date2
    }
  }
}
在第二次测试中,我应该如何比较date和date2?它们是相同的,但specs2似乎没有看到:(

---编辑

使用date.getClass.getCanonicalName在运行时“手动”检查类型将返回org.joda.time.Datetime,这与预期一致

import org.joda.time.DateTime
import org.specs2.mutable.Specification

class TimeSpecs extends Specification {
  "joda and specs2" should {
    "play nice" in {
      val date = DateTime.parse("2012-04-17T00:04:00+0200")
      val date2 = DateTime.parse("2012-04-17T00:04:00+0200")
      date === date2
    }
    "play nice through play json transform" in {
      import play.api.libs.json._
      import play.api.libs.json.Json._
      val date:DateTime = DateTime.parse("2012-04-17T00:04:00+0200")
      val jsDate= toJson(date)
      val date2:DateTim= jsDate.as[DateTime]
      println(date.getClass.getCanonicalName) //prints org.joda.time.DateTime
      println(date2.getClass.getCanonicalName)//prints org.joda.time.DateTime
      date === date2
    }
  }
}
使用DateTime#isEqual做了一些工作,但我失去了流畅匹配器的优势以及它们带来的有用错误消息。另外,我实际上要比较的是碰巧包含日期的case类实例,而不是日期本身

使用

      date should beEqualTo(date2)

产生与
==

相同的错误。问题是,joda time定义了一个非常严格的等号,该等号考虑了日期的等号(DateTime#getChronology)。Kim Stebel提出的isEqual方法忽略了等号

从那时起,有两种可能:定义自定义的读写播放,然后使用相同的模式创建日期,如下面的示例所示

import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat
import org.specs2.mutable.Specification

class TimeSpecs extends Specification {
    val pattern = "yyyy-MM-dd'T'HH:mm:ssZZ"
  "joda and specs2" should {
    "play nice" in {
      val date = DateTime.parse("2012-04-17T00:04:00+0200",DateTimeFormat.forPattern(pattern))
      val date2 = DateTime.parse("2012-04-17T00:04:00+0200",DateTimeFormat.forPattern(pattern))
      date === date2
    }
    "play nice through play json transform" in {
      import play.api.libs.json.Json._

      //play2 custom write
      implicit def customJodaWrite = play.api.libs.json.Writes.jodaDateWrites(pattern)
      //play2 custom read
      implicit def customJodaRead = play.api.libs.json.Reads.jodaDateReads(pattern) 


      val date:DateTime = DateTime.parse("2012-04-17T00:04:00+0200",DateTimeFormat.forPattern(pattern)) //make sure you parse the initial date with the same pattern
      val jsDate= toJson(date)
      val date2:DateTime= jsDate.as[DateTime]

      println(date.getClass.getCanonicalName)
      println(date2.getClass.getCanonicalName)
      println(jsDate)
      date should beEqualTo(date2)
    }
  }
}

在无时区信息的情况下,以UNIX时间戳为基础,以2.1个默认值进行解析(并写入JSON)。当从UNIX时间戳解析时,它将在本地计算机时区(在我的例子中是欧洲/巴黎)中考虑。因此需要自定义解析器/写入器< /P> Joda在调用parse时使用了一个特定的格式化程序,而不使用解析器参数,因此似乎不可能仅使用模式字符串创建同一个格式化程序(我还没有找到通过模式字符串激活DateTimeFormatter#withOffsetParsed方法的方法)

另一种可能是为jodatime定义一个自定义specs2匹配器,它将使用isEqual而不是equals。
既然我不想在json中使用unix纪元,我将继续使用自定义的play transformers

是否尝试使用isEqual方法?是否尝试查看每个日期的类型?