当前位置: 首页 > 知识库问答 >
问题:

JodaTime解析后Android上的时区偏移错误

束福
2023-03-14

我试图用android的JodaTime库解析ISO格式的日期,但得到了错误的时区偏移量。

String dateString = "1990-05-03T20:00:00.000Z";
DateTimeFormatter inputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ").withZone(DateTimeZone.UTC);
DateTimeFormatter outputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ").withZone(DateTimeZone.getDefault());
DateTime dt = inputFormatter.parseDateTime(dateString);
String result = outputFormatter.print(dt); 

我的默认时区是“欧洲/莫斯科”,但结果是“1990-05-04T00:00:00.000 0400”,而它应该是“1990-05-03T23:00:00.000 0300”。Android版本是KitKat。

我做错了什么?

共有1个答案

李星波
2023-03-14

如果您只想使用实际莫斯科区域偏移量来显示历史时间戳,则可以使用以下代码:

String dateString = "1990-05-03T20:00:00.000Z";
DateTimeFormatter inputFormatter =
    DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ").withZone(DateTimeZone.UTC);
DateTime dt = inputFormatter.parseDateTime(dateString);
System.out.println(dt); // 1990-05-03T20:00:00.000Z

// only use actual offset for Moscow
DateTimeZone zoneOffset =
    DateTimeZone.forOffsetMillis(
        DateTimeZone.forID("Europe/Moscow").getOffset(DateTime.now())
    );
DateTimeFormatter outputFormatter =
    DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ").withZone(zoneOffset);
String result = outputFormatter.print(dt);
System.out.println(result); // 1990-05-03T23:00:00.000+0300

仍然是同一个瞬间,只是你要寻找的表单的不同偏移量和本地时间部分。

关于您对如何从服务器解析UTC时间的评论:

String input = "2016-12-10T13:40:38.595";
DateTime utc =
    DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS").parseLocalDateTime(input)
    .toDateTime(DateTimeZone.UTC);
System.out.println(utc); // 2016-12-10T13:40:38.595Z

如果设备数据错误,如何将当前设备时间作为UTC发送到服务器?

首先要说的是:我仍然认为,如果不需要向服务器发送当前客户端时间戳,那么它的设计会更好,因为服务器在接收客户端消息时应该使用自己的时钟来注册时间戳。这有效地防止了假客户在任何时候发送无意义的信息。

否则,如果tz数据和设备时钟(通过System.currentTimeMillis())都错误,但本地设备时间戳仍然正确,如您的注释所示(年-月-日-小时-分钟的有效字段值),则您可以应用以下解决方法:

// incorrect platform data from device clock or outdated tz-data
long platformMillis = System.currentTimeMillis();
int offsetMillis = TimeZone.getDefault().getOffset(platformMillis);
DateTimeZone tzPlatform = DateTimeZone.forOffsetMillis(offsetMillis); // +04 on your device

// we assume correct local time if the errors of platform data compensate each other
LocalDateTime ldt = new LocalDateTime(new Date(platformMillis), tzPlatform);

// now we combine local timestamp with the tz-data of Joda-Time (hopefully up-to-date)
long utcMillis = ldt.toDateTime(DateTimeZone.getDefault()).getMillis();

旁注:我的库时间4a支持更短的解决方案

Moment now = SystemClock.inPlatformView().now().inStdTimezone();
long utcMillis = TemporalType.MILLIS_SINCE_UNIX.from(now);
 类似资料:
  • 一切都清楚一次是UTC中的日期:

  • 问题内容: 日期格式:“ yyyy-MM-dd’T’HH:mm:ss.SSSZ ” 输入日期:“ 2017-09-18T03:08:20.888 + 0200 ” 问题:我需要从输入的字符串中检索时区偏移量,并在该时区中打印已解析的日期。换句话说,我需要输出与输入相同。 成功解析输入日期并返回对象。众所周知,Date没有时区字段。将解析的日期转换为其时区,默认情况下为系统时区。当我打印此日期时,它

  • 问题内容: 我想将joda设置为今天凌晨2点(请参见下面的示例代码)。但是我得到了这个例外: 解决上面的异常或在一天的特定时间创建异常的正确方法是什么? 样例代码: 谢谢。 问题答案: 似乎您正在尝试从特定的本地时间到达实例,并且您希望该功能对日光节约具有强大的作用。试试这个…(请注意,我在美国/东部,所以我们的过渡日期是2011年3月13日;我必须找到正确的日期来获取您今天遇到的例外。下面更新了

  • JSON-API-response包含以下属性: 我使用Moshi和ThreeTenBp解析时间戳,并准备了以下自定义适配器: 如您所见,区域偏移量在这里是硬编码的。 ... 使用Moshi和Kotlin的高级JSON解析技术 相关项目的进行中的分支

  • 我使用的是“亚洲/曼谷”区域id。该偏移是从格林尼治时间UTC 07:00开始的。 但是当我做了下面的事情时,设置为“01/01/1900 7:00:00.000”时不是7:00 结果就是 周一一月一日07:00:00 ICT 1900 -402 周一一月一日06:00:00 ICT 1900 -420 我想知道偏移量是否在1900年1月1日早上7点左右发生了变化,所以我在维基百科上查了一下。ht

  • 如果偏移量为4位(-05:00),我可以使用:,但这不适用于3位。 有什么想法吗?