我有一个Java类,它输入一个位置的纬度/经度,并在夏令时开启和关闭时返回GMT偏移量。我想找到一种简单的方法,在Java中确定当前日期是否在夏令时,以便我可以应用正确的偏移量。目前,我只在美国的时区执行这个计算,尽管最终我也想将其扩展到全球各个时区。
我有一个Java类,它输入一个位置的纬度/经度,并在夏令时开启和关闭时返回GMT偏移量。我想找到一种简单的方法,在Java中确定当前日期是否在夏令时,以便我可以应用正确的偏移量。目前,我只在美国的时区执行这个计算,尽管最终我也想将其扩展到全球各个时区。
这是针对提问机器的答案:
TimeZone.getDefault().inDaylightTime( new Date() );
服务器需要确定客户端的时区才能解决这个问题。有关原因,请参见@Powerlord的答案。
对于任何特定的时区
TimeZone.getTimeZone( "US/Alaska").inDaylightTime( new Date() );
ZoneId.of( "America/Montreal" ) // Represent a specific time zone, the history of past, present, and future changes to the offset-from-UTC used by the people of a certain region.
.getRules() // Obtain the list of those changes in offset.
.isDaylightSavings( // See if the people of this region are observing Daylight Saving Time at a specific moment.
Instant.now() // Specify the moment. Here we capture the current moment at runtime.
) // Returns a boolean.
ZoneId
表示一个时区。该类知道规则,告诉我们DST是否适用于特定时区。ZoneRules
类模拟了一个时区的所有历史和未来转换。Instant
是UTC时间线上的一个时刻。ZonedDateTime
是将ZoneId
应用于Instant
的结果。ZonedDateTime now = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
…
ZoneId z = now.getZone();
ZoneRules zoneRules = z.getRules();
Boolean isDst = zoneRules.isDaylightSavings( now.toInstant() );
toInstant
从 ZonedDateTime
对象中提取一个 Instant
对象。
java.time 框架是内置于 Java 8 及更高版本中的。这些类取代了老旧的、麻烦的 遗留 日期时间类,例如 java.util.Date
、Calendar
和 SimpleDateFormat
。
Joda-Time项目现在处于维护模式,建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。无需字符串,无需java.sql.*
类。
如何获取java.time类?
ThreeTen-Extra 项目通过提供额外的类扩展了 java.time。该项目是 java.time 可能未来增加内容的实验场所。您可能会在这里找到一些有用的类,例如 Interval
, YearWeek
, YearQuarter
和 更多。
TimeZone tz = TimeZone.getTimeZone("EST");
boolean inDs = tz.inDaylightTime(new Date());
TimeZone
类,而改用ZoneId
)。 - Ole V.V.Joda Time 包含处理方法,可以为您计算偏移量。请参阅 DateTimeZone.convertLocalToUTC(...)
此外,您需要使用纬度/经度信息查找当前时区。GeoNames 提供了其 Web 服务的 Java 客户端,以及一个简单的 Web 请求框架(即 http://ws.geonames.org/timezone?lat=47.01&lng=10.2)