Jboss Java Date夏令时

时间:2017-06-08 11:14:46

标签: java datetime jboss dst java.util.calendar

有一个问题,当时钟由于夏令时(一年两次)而移动时,日期在Java中不正确(我位于中欧:GMT+2夏季,{{1}在冬天)

如果提前1小时移动时间,GMT+1仍会返回旧时间(比当前时间晚1小时)。

在Java 7中,这可以解决,而无需重新启动Jboss应用程序服务器吗?

如果我在Windows中手动更改时间,请重现问题:除非重新启动jboss,否则new Date()不会更新到系统日期。

Date

2 个答案:

答案 0 :(得分:2)

使用JDK 8 ZonedDateTime中的java.time类。它适应夏令时变化。 请参阅详细信息:https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html

答案 1 :(得分:2)

Java< = 7 中,您可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。

有了这个,您可以轻松处理DST更改。

首先,您可以使用org.threeten.bp.DateTimeUtils转换为Calendar

以下代码将Calendar转换为org.threeten.bp.Instant,这是一个代表" UTC瞬间"的类。 (一个独立于时区的时间戳:现在,在这个时刻,世界上的每个人都处于同一时刻,尽管他们的当地日期和时间可能会有所不同,具体取决于他们所处的位置。)

然后,Instant转换为org.threeten.bp.ZonedDateTime(这意味着:此时此时区的日期和时间是多少?)。我还使用org.threeten.bp.ZoneId来获取时区:

Calendar c = Calendar.getInstance();
c.setTime(new Date());

// get the current instant in UTC timestamp
Instant now = DateTimeUtils.toInstant(c);

// convert to some timezone
ZonedDateTime z = now.atZone(ZoneId.of("Europe/Berlin"));

// today is 08/06/2017, so Berlin is in DST (GMT+2)
System.out.println(z); // 2017-06-08T14:11:58.608+02:00[Europe/Berlin]

// testing with a date in January (not in DST, GMT+1)
System.out.println(z.withMonth(1)); // 2017-01-08T14:11:58.608+01:00[Europe/Berlin]

我刚刚选择了一些使用中欧时区(Europe/Berlin)的时区:您不能使用这些3个字母的缩写,因为它们是ambiguous and not standard。您可以将代码更改为最适合您系统的时区(您可以使用ZoneId.getAvailableZoneIds()获取所有可用时区的列表。)

我更喜欢这种解决方案,因为它明确了我们用来向用户显示的时区(DateCalendar' s toString()方法在幕后使用默认时区,你永远不知道他们在做什么。

在内部,我们可以继续使用UTC中的Instant,因此它不会受到时区的影响(并且您可以随时根据需要转换为时区) - 如果您需要要将ZonedDateTime转换回Instant,只需使用toInstant()方法。

实际上,如果您想获取当前日期/时间,请忘记旧课程(DateCalendar)并仅使用Instant

// get the current instant in UTC timestamp
Instant now = Instant.now();

但是如果您仍然需要使用旧课程,只需使用DateTimeUtils进行转换。

以上示例的输出是ZonedDateTime.toString()方法的结果。如果您想更改格式,请使用org.threeten.bp.format.DateTimeFormatter类(有关所有可能格式的详细信息,请查看javadoc):

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss z X");
// DST (GMT+02)
System.out.println(formatter.format(z)); // 08/06/2017 14:11:58 CEST +02
// not DST (GMT+01)
System.out.println(formatter.format(z.withMonth(1))); // 08/01/2017 14:11:58 CET +01