时区确实会不时发生变化,我知道在英国,每年似乎都有人说我们应该取消格林尼治标准时间或使用"双夏令时间"。
当这些更改发生时,我想通过旧版本Java上基于TimeZone
或Calendar
的类获得的任何日期都可能会给您提供不正确的数据。除了一直更新你的Java版本之外,有没有办法解决这个问题,比如你可以把一个总是最新的补丁文件放进你的应用程序中?
此外,这个问题对Applets来说也是可以解决的吗?因为你不能直接控制运行应用程序的Java版本/更新?
最好的解决方案是升级到最新的JRE和JDK。
如果由于任何原因无法做到这一点,SUN会提供一个工具,用于将时区表更新为最新的时区表。您可以在此处找到TZUpdater
Java TimeZone和派生的SimpleTimeZone类的文档说明。。。
该类保存与GMT的偏移量,称为原始偏移量,以及夏令时的开始和结束规则日程由于它只为每个值保存一个值,因此无法处理偏移量的历史变化GMT和夏令时时间表,但setStartYear方法可以指定夏令时开始生效。
这意味着,如果您的应用程序不依赖于历史日期/时间,那么如果您在生成这些对象时使用的TimeZone对象是最新的,则不会出现问题。
然而。。。
如果您的应用程序包含任何类型的历史日期/时间数据库,那么当新的时区规则生效时,您的应用软件将错误地解释您的历史信息并显示不正确的结果,因为它将使用的时区对象与生成历史数据时使用的TimeZone对象不同。
如果维护历史上准确的日期/时间对您来说很重要(例如,政府机构的账单记录,这些机构对账单资格的参数定义非常明确),那么您不仅需要将历史日期/时间信息存储在数据库中,但是可以用于重新创建当时有效的时区规则的信息。有几种可能的解决方案。
Java SimpleTimeZone类有一个构造函数,它将允许您创建一个带有一组时区和夏令时规则的TimeZone对象:
SimpleTimeZone(int rawOffset,String ID,int startMonth,int startDay,int startDayOfWeek,int startTime,int endMonth,int endDay,int endDayOfWeek,int endTime,int dstSavings)
构造一个SimpleTimeZone,该SimpleTimeZone具有给定的基准时区相对于GMT的偏移量、时区ID和开始和结束夏令时。
因此,只需确保将数据库中的所有日期/时间信息存储为UTC时间戳即可。我喜欢将时间戳存储在数据库中作为"修改的儒略日数字",它能够以毫秒精度存储日历日期和时间。修改后的儒略日数始终以UTC定义。不管怎样,只要你的信息是UTC,你就是标准的。
然后,您可以创建一个表,其中包含创建数据库中使用过的SimpleTimeZone对象所需的所有参数,也可以使用您喜欢的对象持久化API来持久化数据库使用的所有对象。使用指示用于相关数据的时区规则的外键,可以确保数据库应用程序能够报告历史上准确的本地时间。
Mark Rhodes是对的,如果时区的某些内容发生了更改(比如我的夏季),它甚至会返回错误的时间。因此,最终用户应该更新他们的JRE。
PS:此外,您还可以在此处对IBM JRE的时区更新实用程序进行微调http://www.ibm.com/developerworks/java/jdk/dst/jtzu.html
API时区为您计算夏令时。
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/TimeZone.html