这里是我的 java 代码,它尝试在 Android 设备上获取当前 UTC 日期:
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 是正确的,以 UTC 格式显示当前日期,但在 parse
后,dateResult 不正确。为什么?
最佳答案
不好意思提一下,我怀疑你的代码没有问题,只是困惑。如果您认为旧的 Date
类的行为令人困惑,请允许我成为第一个同意您观点的人。解决此问题的最佳方法是停止使用 Date
并开始使用现代 Java 日期和时间 API。
由于您正在为 Android 编码,因此第一步是获取 ThreeTenABP,这是一个提供现代 API 的 Android 库(如果您使用的是 Java 8 或 9,您可以跳过此步骤,因为现代 API 将会构建)在)。详情参见 this question: How to use ThreeTenABP in Android Project 。现在您可以执行以下操作:
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
保存自纪元(定义为 UTC 时间 1970 年 1 月 1 日午夜 0:00)以来的秒数和纳秒数。我鼓励您将其视为不相关的实现细节。 瞬间
是时间线上的一个点。
出了什么问题?
您询问了 UTC 日期。你可以或不能拥有它,取决于你如何看待它。
- 一方面,
Date
被实现为自纪元以来的秒数和毫秒数,因此,如果您使用上述纪元定义,您可能会说它总是 采用 UTC 时间。 - 另一方面,您不必担心实现细节。从概念上讲,
Date
(如Instant
)是时间线上的一个点,没有也不可能有时区或偏移量;它不能是 UTC。更令人困惑的是,当您执行"getCurrentDateUTC: dateResult = "+ dateResult
时,会隐式调用dateResult.toString()
。此方法获取 JVM 的时区设置,并将日期时间转换为该时区,并将其用于生成的字符串(无需修改Date
对象)。这就是为什么无论您尝试打印哪个日期
,您都会在计算机或设备上看到 EET 时间。
java.time
或 JSR-310
现代日期和时间 API 称为 java.time
或 JSR-310。学习使用它的一个很好的来源是 the Oracle tutorial .
关于java - DateFormat 解析 - 不返回 UTC 格式的日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47307909/