如何修复使用Jackson/Gson库解析的不准确的DateTime(分钟)?

Aym*_*ric 5 google-app-engine android jackson gson

我正在开发一个与一些Google App Engine网络服务对话的Android应用程序.

此应用程序实现了一个聊天活动,它具有非常简单的功能:发送文本.

在调试过程中,我注意到我从服务器列出的消息没有按照我在应用程序上发送的顺序显示.我的第一个想法是问题来自服务器.

起初我检查了我收到的原始Json:

{
 "messages": [
  {
   "message": "test 3",
   "author": "daniel",
   "message_id": "5724160613416960",
   "sent_at": "2014-11-13T09:42:42.861950"
  },
  {
   "message": "test 2",
   "author": "daniel",
   "message_id": "5649050225344512",
   "sent_at": "2014-11-13T09:42:10.390960"
  },
  {
   "message": "test 1",
   "author": "daniel",
   "message_id": "5178081291534336",
   "sent_at": "2014-11-13T09:41:01.998830"
  }
 ],
 "kind": "company#chatsItem",
 "etag": "\"RUCkC9XynEQNZ2t5E0aa41edXro/xRNtgkWIUbq4zCgmv2iq2fy-UIg\""
}
Run Code Online (Sandbox Code Playgroud)

如您所见,原始数据已正确排序.但这里有趣的部分.当我添加JSON解析器时,例如JacksonFactory(甚至是GsonFactory):

Company.Builder builder = new Company.Builder(AndroidHttp.newCompatibleTransport(), new JacksonFactory(), null);
Company service = builder.build();
ChatsChatCollectionResponse response = service.chats().list(user_id, album_id, token).execute();
List<ChatsChatResponse> messagesResponse = response.getMessages();
Run Code Online (Sandbox Code Playgroud)

以下是以与ChatsChatResponse上述相同的方式订购的商品:

[0] = {com.appspot.com_pany.company.model.ChatsChatResponse@830029063096} size = 4
[0] = {com.google.api.client.util.DataMap$Entry@830029082528}"author" -> "daniel"
[1] = {com.google.api.client.util.DataMap$Entry@830029082552}"message" -> "test 3"
[2] = {com.google.api.client.util.DataMap$Entry@830029082576}"message_id" -> "5724160613416960"
[3] = {com.google.api.client.util.DataMap$Entry@830029082600}"sent_at" -> "2014-11-13T10:57:03.950+01:00"

[1] = {com.appspot.com_pany.company.model.ChatsChatResponse@830029066376} size = 4
[0] = {com.google.api.client.util.DataMap$Entry@830029083616}"author" -> "daniel"
[1] = {com.google.api.client.util.DataMap$Entry@830029083640}"message" -> "test 2"
[2] = {com.google.api.client.util.DataMap$Entry@830029083664}"message_id" -> "5649050225344512"
[3] = {com.google.api.client.util.DataMap$Entry@830029083688}"sent_at" -> "2014-11-13T10:48:40.960+01:00"

[2] = {com.appspot.com_pany.company.model.ChatsChatResponse@830029068008} size = 4
[0] = {com.google.api.client.util.DataMap$Entry@830029084760}"author" -> "daniel"
[1] = {com.google.api.client.util.DataMap$Entry@830029084784}"message" -> "test 1"
[2] = {com.google.api.client.util.DataMap$Entry@830029084808}"message_id" -> "5178081291534336"
[3] = {com.google.api.client.util.DataMap$Entry@830029084832}"sent_at" -> "2014-11-13T10:57:39.830+01:00"
Run Code Online (Sandbox Code Playgroud)

为什么"sent_at"字段会出现这样的随机差异?

编辑 我忘了提到我不是在谈论与TimeZone相对应的1小时班次,而是关于会议记录的随机性.

mat*_*ash 3

我不确定解决方案,但解释似乎很清楚:变化根本不是随机的,而是由将小数点后的所有内容添加为毫秒引起的。

以第三条为例:

2014-11-13T09:41:01.998830
Run Code Online (Sandbox Code Playgroud)

显然,解析器将其读作:

hours: 09
minutes: 41
seconds: 01
milliseconds: 998830
Run Code Online (Sandbox Code Playgroud)

由于毫秒大于 1000,因此它最终会转换为998s 830ms,当考虑完整分钟时为16m 38s 830ms。因此:

hours: 09
minutes: 41 + 16
seconds: 01 + 38
milliseconds: 830
Run Code Online (Sandbox Code Playgroud)

这会准确产生您所看到的结果(模时区调整):

2014-11-13T10:57:39.830+01:00
Run Code Online (Sandbox Code Playgroud)

如果您可以控制服务输出(这一点从问题措辞中不太清楚),最简单的解决方法是仅输出小数点后三位数字(即以毫秒而不是百万分之一舍入)。例如,这将是2014-11-13T09:41:01.999.

也可以在解析器本身上修复这个问题,但这需要更多的研究(理想情况下,需要重现问题的要点)。