我尝试以jodatime库为Android解析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。
我做错了什么?
如果您只想使用实际的莫斯科区域偏移量来显示历史性的时间戳,则可以使用此代码:
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-DATA和设备时钟(通过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);