java日历的DST问题

Posted

技术标签:

【中文标题】java日历的DST问题【英文标题】:DST issue with java Calendar 【发布时间】:2017-04-02 19:33:41 【问题描述】:

我在使用日历实例从夏令时结束并转换到标准时间的时间减去一小时时看到了这个问题。 这是代码:

 Date startTime = new Date();// Gives me Sun Nov 06 01:26:16 EST 2016
Calendar temp;
TimeZone timezone = TimeZone.getDefault(); //Eastern
temp= Calendar.getInstance(timezone);
temp.setTime(startTime);
temp.add(Calendar.HOUR_OF_DAY, -1);
 temp.set(Calendar.MILLISECOND, 0);
    Date endDate =  temp.getTime(); // This is still Sun Nov 06 01:26:16 EST 2016

我期望 endDate 的结果是 Sun Nov 06 01:26:16 EDT 2016 而不是 Sun Nov 06 01:26:16 EST 2016。我不确定这是否符合设计。如果我减去 2 小时,那么我认为它工作正常。 对此有何意见?

谢谢, SS

【问题讨论】:

【参考方案1】:

使用 java.time

您应该使用 java.time 类而不是麻烦的旧日期时间类,例如 Calendar,而不是现在的遗留类。

请务必阅读 ZonedDateTime 的课程文档,以了解其选择如何处理夏令时 (DST) 切换。

continent/region 的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用 3-4 个字母的缩写,例如 ESTEDTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。

ZoneId z = ZoneId.of( "America/New_York" );
// of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond, ZoneId zone)
ZonedDateTime zdt = ZonedDateTime.of( 2016 , 11 , 6 , 1 , 26 , 16 , 0 , z );
ZonedDateTime zdtOneHourEarlier = zdt.minusHours( 1 );
ZonedDateTime zdtOneHourLater = zdt.plusHours( 1 );

注意每个结果中与 UTC 的偏移量。

zdt.toString(): 2016-11-06T01:26:16-04:00[美国/纽约]

zdtOneHourEarlier.toString(): 2016-11-06T00:26:16-04:00[America/New_York]

zdtOneHourLater.toString(): 2016-11-06T01:26:16-05:00[America/New_York]

查看此代码run live at IdeOne.com。


关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。

从哪里获得 java.time 类?

Java SE 8SE 9 及更高版本 内置。 标准 Java API 的一部分,带有捆绑实现。 Java 9 添加了一些次要功能和修复。 Java SE 6SE 7 大部分 java.time 功能在ThreeTen-Backport 中向后移植到 Java 6 和 7。 Android ThreeTenABP 项目专门针对 android 改编了 ThreeTen-Backport(如上所述)。 见How to use ThreeTenABP…

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuarter 和more。

【讨论】:

以上是关于java日历的DST问题的主要内容,如果未能解决你的问题,请参考以下文章

为日历对象禁用 DST

Java 为啥 Calendar.get(Calendar.DST_OFFSET) 在夏令时给出 0?

自己整理的linux常用操作指令

java题目,日历类,求助。

用java编辑日历记事本

怎样用java编写日历