0

在部署到生产环境后,我的代码坏了,并且经过相当多的 bug 追逐后,我发现 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

请注意+03:00ISO8601 字符串末尾的 ,无论是最初还是重新序列化之后。现在这是在 +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: 我打开了一个相关问题并在这里得到了我需要的解决方案。

4

1 回答 1

0

鉴于您编辑的问题,最简单的答案是强制每个日期时间都在同一个时区,例如

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

但是请注意,在这种情况下,您会丢失信息,即日期所在的时区。如果您将日期用于内部目的(例如查找新项目),那么这并不重要,如果您将数据发送回用户,那么您需要找到另一个解决方案。

于 2013-09-21T08:21:41.010 回答