部署到生产环境后,我的代码中断了,并且在追捕了很多错误之后,我发现JodaTime在生产环境中对反序列化的处理与在开发环境中不同。显然,生产服务器位于另一个时区。
反序列化和开发序列化:
scala> val input ="2013-09-07T17:11:03.117+03:00"
input: String = 2013-09-07T17:11:03.117+03:00
scala> val thisIsDev = new DateTime(input).toString()
thisIsDev: String = 2013-09-07T17:11:03.117+03:00
scala> input == thisIsDev
res3: Boolean = true
请注意,在初始和重新序列化之后,ISO8601字符串末尾的+03:00。现在,这就是在+0时区的生产中发生的情况:
scala> val sameInput ="2013-09-07T17:11:03.117+03:00"
sameInput: String = 2013-09-07T17:11:03.117+03:00
scala> val thisIsProd = new DateTime(sameInput).toString()
thisIsProd: String = 2013-09-07T14:11:03.117Z
scala> sameInput == thisIsProduction
res1: Boolean = false
如您所见,+03:00被取消,日期字符串的格式更改了时区。
这是一个解决的问题吗?有什么建议吗?
编辑:
要澄清的是,这样做的问题是,如果我序列化,更改时区(例如转到其他服务器),然后反序列化和重新序列化,那么最终得到的字符串与开始时的字符串不同。这就是为什么我的产品坏了,但我的测试却没有。花了我一段时间来解决这个问题。
注意:这些ISO8601字符串在CouchDb服务器上使用,该服务器对它们进行字母数字排序,这就是为什么我不能使用JodaTime方法进行比较的原因。
编辑2:
理想的答案是建议如何在不丢失时区信息(在不同时区)的情况下将ISO8601字符串反序列化为DateTime对象。
编辑2.1:我打开了一个相关的问题,并在这里找到了需要的解决方案。
这里没有足够的信息来了解实际的问题是什么。 两次都相等,如果尝试new DateTime("2013-09-07T17:11:03.117+03:00").equals(new DateTime("2013-09-07T14:11:03.117Z"))可以看到。 请显示完整的错误信息以及引起该错误的代码。
@jgm,作为回应,我更新了问题。
给定您已编辑的问题,最简单的答案是强制每个日期时间位于同一时区,因此例如
scala> new DateTime("2013-09-07T17:11:03.117+03:00").withZone(DateTimeZone.UTC)
res1: org.joda.time.DateTime = 2013-09-07T14:11:03.117Z
scala> new DateTime("2013-09-07T14:11:03.117Z").withZone(DateTimeZone.UTC)
res2: org.joda.time.DateTime = 2013-09-07T14:11:03.117Z
但是请注意,在这种情况下,您将丢失信息,即日期所在的时区。 如果您将日期用于内部目的(例如查找新项目),那么这没什么大不了的;如果您要将数据发送回用户,则需要注意一点,那么您需要寻找其他解决方案。