我想获取设备所在国家/地区的时区偏移量。让我们以芬兰的设备为例,芬兰当前使用 EEST,但由于某种原因我的设备存储了 时区为 EET。现在我们知道 EEST 和 EET 有不同的偏移量(分别为 +3 和 +2)。所以我想要一个java代码,它可以通过获取EET中的时区,确定该国家/地区当前使用的时区是否实际上是EET或EEST(或确定DST是否有效)并返回给我正确的偏移量正确的偏移量。
注意:EEST 和 EET 只是我使用的一个示例,我希望代码能够与在一年中的不同时间使用多个时区的任何国家/地区一起使用。
我无法使用大陆/城市格式,因为我从设备获得的唯一信息是 EET 时区。
确定夏令时是否启用
ZoneId
.of( "Europe/Helsinki" )
.getRules()
.isDaylightSavings(
Instant.now()
)
EEST 和 EET 不是时区。它们只是给出了关于可能使用的时区的含糊提示,并指示夏令时 (DST) 是否有效。这些伪区域没有标准化,甚至不是唯一/独特的。仅当本地化以呈现给用户时才应使用这些。这些绝不应该用于数据存储、数据交换或业务逻辑。
你说:
现在我们知道 EEST 和 EET 具有不同的偏移量(分别为 +3 和 +2)
不,我们不知道这一点。 EEST 和 EET 隐含的偏移量没有官方/标准定义。 EEST 和 EET 隐含的时区在某些日期可能会有不同的偏移,因为他们的政客可能会在不同的日期开始/停止 DST。或者政客们可能会引入夏令时之外的其他异常现象;政治家是不可预测的。
你说:
我想获取设备所在国家/地区的时区偏移量。
至于以地点来确定时区,那是自以为是的。对于演示来说唯一重要的时区是用户预期/期望的时区。你可以猜那可能是什么。但在关键情况下,您必须明确与用户确认。
你说:
Calendar calendar = …
您正在使用有严重缺陷的日期时间类,这些类在几年前已被 JSR 310 中定义的现代 java.time 类取代。
你说:
确定该国家/地区当前使用的时区实际上是 EET 还是 EEST(或确定 DST 是否有效)
首先,确定一个实时时区。实时区域的名称格式为
Continent/Region
。例如,Africa/Casablanca
或 Pacific/Auckland
。对于芬兰,唯一的时区是Europe/Helsinki
。
ZoneId z = ZoneId.of( "Europe/Helsinki" ) ;
获取为该区域定义的规则。
ZoneRules rules = z.getRules() ;
捕获与 UTC 零小时-分钟-秒的偏移所看到的当前时刻。
Instant now = Instant.now() ;
询问当时的规则,询问夏令时是否有效。
boolean isDST = rules.isDaylightSavings( now ) ;
你说:
我无法使用大陆/城市格式,因为我从设备获得的唯一信息是 EET 时区。
那么你的信息不完整,你的任务是不可能完成的。
这就像询问“美元”当前的货币汇率,但你不知道那是澳元、加元、港币还是美元。
这里是参考时区偏移的教程。
时区和偏移量类(Java™ 教程 > 日期时间 > 标准日历)。
作为获取 UTC 偏移量的替代方法,您可以使用 TimeZone 类。
要创建新的 TimeZone 对象,您可以使用 getTimeZone 方法。
在此示例中,我将使用 EET 或 东欧时间。
TimeZone timeZone = TimeZone.getTimeZone("EET");
TimeZone类提供getOffset方法,该方法采用一组值或Unix-epoch时间戳作为参数。
我们可以使用 Calendar 对象来获取 UTC 的时间值,并使用 getTimeInMillis 方法获取时间戳。
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
long offset = timeZone.getOffset(calendar.getTimeInMillis());
如果我们打印offset,我们会得到以下结果。
10800000
相当于3小时,即3×60×60×1000。
对于夏令时或夏令时,您可以利用以下方法:useDaylightTime、getDSTSavings、
如果时区遵守夏令时,第一个方法将返回 true,而后者将返回一个以毫秒为单位的值,该值与 UTC 偏移量相反。
不同地区实行夏令时的时间不同。
您可以使用可通过 Calendar 对象获取的 Date 对象来查询时间戳当前是否遵守 DST。
TimeZone timeZone = TimeZone.getTimeZone("EET");
Calendar calendar = Calendar.getInstance(timeZone);
boolean dst = timeZone.inDaylightTime(calendar.getTime());