DateFormat解析 – 不以UTC格式返回日期

这里我试图在Android设备上以UTC格式获取当前日期的java代码:

public static Date getCurrentDateUTC() { try { TimeZone timeZoneUTC = TimeZone.getTimeZone("UTC"); Date localTime = new Date(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss Z"); dateFormat.setTimeZone(timeZoneUTC); String dateUTCAsString = dateFormat.format(localTime); Debug.d(TAG, "getCurrentDateUTC: dateUTCAsString = " + dateUTCAsString); Date dateResult = dateFormat.parse(dateUTCAsString); Debug.d(TAG, "getCurrentDateUTC: dateResult = " + dateResult); return dateResult; } catch (ParseException e) { Debug.e(TAG, "getCurrentDateUTC: ", e); return null; } } 

结果:

 dateUTCAsString = 2017-11-15T12:54:25 +0000 dateResult = Wed Nov 15 14:54:25 EET 2017 

正如您所看到的, dateUTCAsString IS CORRECT以UTC 格式显示当前日期,但在parse之后dateResult不正确。 为什么?

请原谅我提到它,我怀疑你的代码没有问题,只有混乱。 如果您认为旧的Date类表现令人困惑,请允许我成为许多人中第一个同意您的人。 这个问题的良好和合理的解决方案是您停止使用Date并开始使用现代Java日期和时间API。

由于您正在编写Android代码,因此您首先要获得ThreeTenABP,即提供现代API的Android库(如果您使用的是Java 8或9,则可以跳过此步骤,因为现有的API将被内置)。 详细信息在此问题中描述:如何在Android项目中使用ThreeTenABP 。 现在你可以这样做:

  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss Z"); String dateUTCAsString = "2017-11-15T12:54:25 +0000"; Instant dateResult = OffsetDateTime.parse(dateUTCAsString, formatter).toInstant(); System.out.println(dateResult); 

在我的电脑上打印出来:

 2017-11-15T12:54:25Z 

最后的Z表示祖鲁时区或UTC。

您可能知道, System.out.println(dateResult)隐式调用dateResult对象的toString方法。 类Instant对象产生上述格式,总是以UTC为单位,正如我所理解的那样。 对于大多数用途, Instant类是旧式Date类的自然替代品。 在内部, Instant保持自纪元以来的秒数和纳秒数,该纪元定义为1970年1月1日UTC时间午夜0点。 我鼓励您将此视为无关的实施细节。 Instant是时间线上的一个点。

什么地方出了错?

你要求UTC的日期。 根据您的看法,您可以或不可以。

  • 一方面, Date实现为自纪元以来的秒数和毫秒数,因此如果您使用上述纪元定义,则可以说它始终为UTC。
  • 另一方面,您不应该担心实现细节。 从概念上讲, Date (如Instant )是时间线上的一个点,并且没有也没有时区或偏移; 它不能是UTC。 更令人困惑的是,当你执行"getCurrentDateUTC: dateResult = " + dateResult ,会隐式调用dateResult.toString() 。 此方法获取JVM的时区设置,并将日期时间转换为此区域,并将其用于生成的字符串(不修改Date对象)。 这就是为什么无论您尝试打印哪个Date您都会在计算机或设备上看到EET的时间。

java.time或JSR-310

现代日期和时间API称为java.time或JSR-310。 学习使用它的一个很好的资源是Oracle教程 。