我正在开发一个库来将复杂数据存储在一个对象中。此对象中的字段之一是日期。当我使用 setter 方法设置日期时,假定日期对象处于 GMT 时区。在内部,Date 存储为 long,其中包含距纪元的毫秒数。在我的 get()
方法中,我正在执行以下操作:
return new Date(storedDateinMilliseconds);
问题是,如果有人在返回的对象上调用 toString()
,它会使用默认时区返回日期。因此,返回的日期并不总是与 GMT 中提供的日期相匹配。有没有办法来解决这个问题?以便此实现的用户在调用 toString()
时始终获得 GMT 日期?
我尝试了以下操作:
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
但这会修改使用它的应用程序的默认时区。
最佳答案
正如 Sotirios Delimanolis 的评论所说,您将 java.util.Date 对象提供给调用程序员。她用它做什么取决于她。她有责任了解该物体带来的所有愚蠢问题,包括它的toString
。方法应用 JVM 的当前默认时区生成其日期时间值的字符串表示形式。
如果要返回具有指定时区的日期时间值,则返回一个不同的对象。
替代日期时间对象
您至少有三种方法可以返回 java.util.Date 对象。
java.time
在 Java 8 及更高版本中,显而易见的选择是使用新的 java.time framework (Tutorial)。给调用程序员一个 ZonedDateTime
基本上是 Instant
的对象对象加一个 ZoneId
目的。
提示:指定时区时,使用 proper time zone name .切勿使用 3-4 个字母的代码,例如 EST
或 IST
。
乔达时间
Joda-Time是 java.time 的灵感来源。这个第 3 方库非常好,并且因广泛使用而陈旧。它还支持多个版本的 Java 和 Android。
DateTime
类是时间轴上的一个时刻加上一个时区,类似于java.time的ZonedDateTime
。
ISO 8601
第三种选择是为调用程序员提供日期时间值的字符串表示形式。显而易见的格式选择是使用 ISO 8601 定义的格式。标准。这些格式是明智的、深思熟虑的和明确的。
2015-09-16T18:06:14Z
……或者……
2015-09-16T11:06:14-07:00
java.time 和 Joda-Time 在解析和生成字符串时默认使用这些格式。 java.time 明智地扩展了这些格式,以在方括号中附加时区的正确名称。
2015-09-16T11:06:14-07:00[America/Los_Angeles]
从不调整默认时区
您表示设置默认时区会影响您的整个应用。错误的。它会影响在该 JVM 中运行的所有线程中的所有应用程序的所有代码。更糟糕的是,它会在其他代码运行时在运行时立即执行此操作。
设置默认时区仅作为解决日期时间问题的所有其他方法都已用尽时的最后手段。这是罕见的。通常的解决方案是:
- 使用 java.time 或 Joda-Time。
- 始终指定所需/预期的时区,而不是隐含地依赖默认值。
- 使用UTC在您的大部分业务逻辑、数据存储和数据交换中。
- 尽可能避免 java.util.Date/.Calendar 的困惑。
搜索 StackOverflow
所有这些主题都已在 StackOverflow.com 上讨论过多次。请搜索更多信息和示例。
关于java - 在 Java 7 中处理日期对象和时区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32613606/