具有自定义ID的Java TimeZone不考虑夏令时

时间:2014-03-26 14:24:04

标签: java calendar timezone dst

我只是想分享一下有关Java TimeZone的经验。问题出在这里:
无论日期如何,时区的inDaylightTime(Date date)函数始终返回0。一致getDSTSavings()也返回0。 这是创建时区的代码片段:

Timezone timezone = TimeZone.getTimeZone("GMT+1:00");

3 个答案:

答案 0 :(得分:1)

使用id "UTC+1:00"(或" GMT + 1:00")创建的时区对象中的DST与使用相应字符串"Europe/Berlin"创建的时区对象不同,因此,如果DST对您的应用程序很重要,请始终使用完整的字符串ID而不是相应的时间偏移量 所以将时区定义更改为:

Timezone timezone = TimeZone.getTimeZone("Europe/Berlin");

将解决问题。

答案 1 :(得分:1)

不,TimeZone API可以节省一天的费用。您正在使用自定义时区ID。

来自TimeZone API的文档

  

不能使用自定义时区ID

指定夏令时转换计划

因此,您需要指定可用于节省白天的时区ID

  

通常,您使用getDefault获取TimeZone,它会根据程序运行的时区创建TimeZone。例如,对于在日本运行的程序,getDefault会根据日语标准时间创建一个TimeZone对象。您还可以使用getTimeZone和时区ID获取TimeZone。例如,美国太平洋时区的时区ID是“America / Los_Angeles”。因此,您可以使用以下命令获取美国太平洋时间TimeZone对象:

使用时区ID,这将照亮该特定区域的日光节省

 TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");

答案 2 :(得分:1)

tl; dr

询问DST当前是否有效。

ZoneId
.of( "Europe/Madrid" )
.getRules()
.isDaylightSavings​( Instant.now() )

询问当前生效的UTC前后的偏移量(小时-分钟-秒)。

ZoneId
.of( "Africa/Tunis" )
.getRules()
.getOffset​( Instant.now() )

DST来了

要询问“夏时制是否有效?”,您必须指定一个时刻。 Daylight Saving Time (DST)的确切定义是每年两次。

使用Instant指定时刻。

Instant instant = Instant.now() ;  // Capture the current moment as seen in UTC.

java.time

您使用的是可怕的日期时间类,这些类现在已被遗留,几年前被JSR 310中定义的现代 java.time 类所取代。

Table of all date-time types in Java, both modern and legacy

使用ZoneId而不是TimeZone

偏移量与时区

TimeZone.getTimeZone(“ GMT + 1:00”);

字符串GMT+1:00 not 表示时区,它表示偏移量。现在有许多时区可能恰巧都使用UTC之前一小时的偏移量,例如Africa/CasablancaAfrica/BrazzavilleAfrica/TunisEurope/Andorra,{{ 1}}等。

了解偏移量仅在本初子午线之前或之后数小时-数分钟-秒。偏移量看起来像Europe/Warsaw+05:30

时区远不止于此。时区是过去,现在和将来更改特定区域的人们使用的偏移量的历史。时区的规则是政客反复设定的,并且以惊人的频率变化。

正确的时区名称由-05:00组成,例如Continent/RegionAmerica/Montreal。请参阅this list of zones at Wikipedia(可能不是最新的)。

America/New_York

询问“ DST是否有效?”

您似乎想知道DST在特定时区当前是否有效。获取特定ZoneRulesZoneId。然后interrogate特定时间。

ZoneId z = ZoneId.of( "Europe/Gibraltar" ) ;

您可以索要offset-from-UTC currently in effect的金额。 ZoneId z = ZoneId.of( "Europe/Gibraltar" ) ; ZoneRules rules = z.getRules() ; boolean dstInEffect = rules.isDaylightSavings​( Instant.now() ) ; 对象代表本初子午线之前或之后的小时-分钟-秒数。

ZoneOffset

关于 java.time

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

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

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

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要ZoneOffset offset = rules.getOffset​( Instant.now() ) ; 类。

在哪里获取java.time类?