Java日历日期仍在UTC日期00:00添加时间

时间:2017-12-21 09:34:37

标签: java java-calendar

我将我的日历实例设置为00:00的UTC日期,但是一旦我将结果提前1小时

Calendar cal = Calendar.getInstance(TIMEZONE_UTC, Locale.ENGLISH);
cal.set(2017, 12 - 1, 15);
cal.set(Calendar.AM_PM, Calendar.AM);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
System.out.println(cal.getTime());
// Fri Dec 15 01:00:00 CET 2017 but should be 00:00:00

我想有冬季/夏季偏移,但我没有在格里高利或日历元素中找到任何描述来处理这个问题

2 个答案:

答案 0 :(得分:4)

我的印象是你真的在2017年12月15日之后,并且只是想确保没有意外的一小时?如果是这样,那么现代Java日期和时间API LocalDate中的java.time就是为您制作的:

LocalDate ld = LocalDate.of(2017, Month.DECEMBER, 15);
System.out.println(ld);

打印

2017-12-15

无需关注小时,分钟或秒钟。

如果你需要一个日期时间00:00 UTC(我以前打电话给午夜直到Basil Bourque’s comment),有几种方法可以获得它。其中之一是:

    OffsetDateTime utcDateTime = LocalDateTime.of(2017, Month.DECEMBER, 15, 0, 0)
            .atOffset(ZoneOffset.UTC);
    System.out.println(utcDateTime);

打印

2017-12-15T00:00Z

最后Z表示UTC或偏移零。你可以根据需要看到时间是00:00。

您在问题中使用的Calendar课程已经过时了,所以我建议您不要再使用它了。 java.time,现代Java日期和时间API,也称为JSR-310,可以更好地使用。

您的代码出了什么问题?

虽然Calendar确实包含时区(您将其初始化为TIMEZONE_UTC),但Date(另一个过时的类)却没有。因此,当您使用Date转换为cal.getTime()时,您将失去想要以UTC为时间的信息。下一步(这会让很多人感到困惑),当您打印日期时,您隐式调用Date.toString(),此方法会抓取您的JVM的时区设置,并生成一个包含此时区中时间的字符串。显然你(就像我)在12月的UTC + 01:00的时区。以下两个日期时间表示时间轴上相同的点:

Fri Dec 15 01:00:00 CET 2017
Fri Dec 15 00:00:00 UTC 2017

答案 1 :(得分:1)

您看到打印本地时间的原因是您使用Date.toString()通过日历实例显示它,该实例使用本地时区(隐式使用系统时区)。