Dealing with Date Object and TimeZone in Java 7



我正在开发一个库,用于在对象中存储复杂数据。此对象中的一个字段是日期。当我使用setter方法设置日期时,假设日期对象在GMT时区。在内部,Date存储为从epoch起以毫秒为单位的长。在我的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

在Java8及更高版本中,显而易见的选择是使用新的Java.time框架(教程(。给调用程序员一个ZonedDateTime对象,它基本上是Instant对象加上ZoneId对象。

提示:指定时区时,请使用正确的时区名称。切勿使用像ESTIST这样的3-4个字母的代码。

Joda时间

Joda Time是java.Time的灵感来源。这个第三方库非常棒,而且在流行使用中已经过时了。它还支持Java和Android的多个版本。

DateTime类是时间线上的一个时刻加上一个时区,类似于java.time的ZonedDateTime

ISO 8601

第三种选择是给调用程序员一个日期-时间值的字符串表示。格式的明显选择是使用ISO 8601标准定义的格式。这些格式是合理的、经过深思熟虑的、明确的。

2015-09-16T18:06:14Z

…或…

2015-09-16 t11:06:14-07:00

在解析和生成字符串时,java.time和JodaTime默认都使用这些格式。java.time明智地扩展了这些格式,将时区的正确名称附加在方括号中。

2015-09-16T11:06:14-07:00〔美国/洛杉矶〕

从不调整默认时区

您表示,设置默认时区会影响您的整个应用程序。错误的它会影响JVM中运行的所有线程中所有应用程序的所有代码。更糟糕的是,当其他代码正在运行时,它会在运行时立即执行此操作。

只有当解决日期时间问题的所有其他方法都已用尽时,才将默认时区设置为最后手段。这是罕见的。通常的解决方案是:

  • 使用java.time或Joda time
  • 始终指定所需/预期的时区,而不是隐含地依赖默认时区
  • 在您的大部分业务逻辑、数据存储和数据交换中使用UTC
  • 尽可能避免java.util.Date/.Calendar的混乱

搜索堆栈溢出

所有这些主题都在StackOverflow.com上进行了多次讨论。请搜索更多信息和示例。

AFAIK,您有两个选项:

选项1。这听起来可能有些过头了,但您可以为您的这个复杂类推出自己的Date对象,并覆盖toString((方法。也许像

public class GMTDate extends java.util.Date {
    @Override
    public String toString() {
        //return GMTDate
    }
}

选项2:将日期保持为java.util.date,但不要为其公开公共getter。相反,公开一个以GMT格式返回日期的公共getter,或者一个以长(从epoch开始的毫秒数(返回日期的公用getter

编辑:还有第三个选项:AspectJ。您可以使用面向方面的编程来拦截对toString((方法的调用,并返回GMT字符串日期相关堆栈溢出问题:AspectJ:拦截方法执行/调用并使其返回

相关内容

  • 没有找到相关文章