joda时区ID是否与java时区ID相同?

时间:2016-11-11 12:43:50

标签: java android datetime jodatime

我在Android上使用ACTION_TIMEZONE_CHANGED意图过滤器来响应时区更改。

我注意到此时Jodas当前时区未使用以下内容进行更新: DateTimeZone.getDefault()

当我使用Java的默认TimeZone.getDefault()时,时区是正确的。

注意:当我再次更改它时:Joda具有我之前更改过的值。所以它落后了(当Android激发广播意图时尚未更新。)

所以我只能将Java时区用于当前时区。但我的域对象使用Joda DateTimeZone。现在我想将当前时区与我的域对象中的时区进行比较。这样做可以节省:

TimeZone currenTimeZone = TimeZone.getDefault();
if(action.getLocation().getDateTimeZone().getID().equals(currenTimeZone.getID()))) {
 [...]
}

? 或者两个库之间的时区ID是否不同?

1 个答案:

答案 0 :(得分:5)

TL;博士

不,不安全假定时区:

  • 存在。
  • 定义了特定的标识符。
  • 具有相同的定义/规则。

的tzdata

大多数操作系统和软件库依赖tz database维护的IANA来提供当前和过去的时区信息。也称为tzdataTZDB。以前称为 Olson数据库

频繁更改

在全球范围内,政客们喜欢经常更改,重新定义,重新安排,重命名以及以其他方式搞乱时区定义和规则。他们经常在没有预警的情况下这样做,例如在Turkey(2016年秋季)的两个月内就已经少了。

有时会定义新的时区。因此,在这方面,要特别回答您的问题:是的,tzdata的某些副本可能具有旧版本中不存在的较新时区定义,因此时区标识符可能存在差异。

此外,有时会为现有时区指定新名称。例如,最近印度恢复了城市名称,Asia/Calcutta现在也标记为Asia/Kolkota。同样,旧的tzdata副本不会知道这个新名称。

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

某些软件会扩展tzdata以尝试识别这些伪时区。不是个好主意。但是,同样,这意味着使用这些非标准时区标识符可能在一个地方工作,但不能在另一个地方工作。坚持官方时区名称。

某些区域有display name,例如British Time。但是你应该从不将其用作标识符。

更新

系统管理员必须努力在所有可能使用的地方更新tzdata:

  • 操作系统
  • Java虚拟机
  • 软件库(例如Joda-Time,可能还有ThreeTen-Backport)。

JVM的提供者通常在JVM的更新中包含最新版本的tzdata。但政客们比Java更新更频繁地使用时区。因此,您可能需要手动更新JVM。 Oracle为Oracle&提供了Timezone Update Tool。 OpenJDK JVM。

Joda-Time包含自己的tzdata副本。因此,您需要更新Joda-Time库或手动更换tzdata。请注意,Joda-Time项目现在处于维护模式,并建议转移到Java 8及更高版本捆绑的java.time类。

列出已知标识符

java.time类可以显示他们的known zone identifiers列表。

Set<String> zoneIds = ZoneId.getAvailableZoneIds() ;

其他库和操作系统也可以这样做。

避免遗留日期时间类

与最早版本的Java捆绑在一起的麻烦的旧日期时间类现在已经遗留下来,取而代之的是java.time类。

因此,您TimeZone.getDefault()的使用现已过时ZoneId.systemDefault

ZoneId z = ZoneId.systemDefault() ;
String zoneIdentifier = z.toString() ;

使用它来获取特定区域的当前时刻。

ZonedDateTime zdt = ZonedDateTime.now( z );