时间区是政治家们经常重新定义。出现新区域。旧的改名(例如:Asia/Kolkata
)。有些人确定实际上并不明确,最后指向另一人(例如:America/Montreal
)。这就是名称 - 每个区域内的偏移量也经常会被政客们修改为夏令时(DST)等异常情况,或者决定完全下载DST或决定全年停留DST或决定改变抵消15分钟做出一些政治声明,如区分你的邻国。所以没有简单的永久列表。
Java拥有tzdata时区数据库的副本。如果您关心的任何区域发生更改,则需要在Java安装中更新此tzdata。 Oracle在其实施中为这件事提供了一个工具;我不知道其他人。同样,你也应该更新主机操作系统中的tzdata以及其他工具,比如你的数据库,如Postgres。
至于Java中的ZoneId
对象引用,你可以定义一些常量。 java.time类是线程安全的。所以你可以保持一个实例作为一个常量。
public class TimeUtils {
static public ZoneId ZONEID_EUROPE_PARIS = ZoneId.of("Europe/Paris") ;
static public ZoneId ZONEID_ASIA_KOLKATA = ZoneId.of("Asia/Kolkata") ;
}
你有LocalDateTime
代表潜在的时刻,而不是在时间轴上的特定点。 A LocalDateTime
有没有时区或偏移量信息。所以中午在今年6月1日的LocalDateTime
可能意味着很多不同的时刻,与第一中午在Kiribati在时区具有比UTC的偏移14小时发生。孟加拉国的中午晚些时候来临,而在法国巴黎的中午还有几个小时过去了。所以一个LocalDateTime
没有真正的意义,直到你申请一个时区的上下文。
LocalDateTime noon1June2017Anywhere = LocalDateTime.of(2017 , Month.JUNE , 1 , 12 , 0);
使用那些你需要的常量ZoneId
。
ZonedDateTime noon1June2017EuropeParis = noon1June2017Anywhere.atZone(TimeUtils.ZONEID_EUROPE_PARIS) ;
ZonedDateTime noon1June2017AsiaKolkata = noon1June2017Anywhere.atZone(TimeUtils.ZONEID_ASIA_KOLKATA) ;
注意noon1June2017EuropeParis
和noon1June2017AsiaKolkata
是两个不同时刻,在时间轴上的不同点。中午在印度发生得比在法国早得多。
让我们来看看在UTC这两个数值为Instant
对象。这两个Instant
对象不等于作为加尔各答一个比一个巴黎早几个小时。
Instant instantNoon1June2017EuropeParis = noon1June2017EuropeParis.toInstant() ; // Extract the same moment but in UTC zone.
Instant instantNoon1June2017AsiaKolkata = noon1June2017AsiaKolkata.toInstant() ; // Extract the same moment but in UTC zone.
外部化
如果您的问题的意图是外部的应用是什么区的决定,这样你就可以改变这样的选择,而无需再次重新编译源代码,只是存储区的字符串名称,如Europe/Paris
作为一些外部资源中的字符串。
将您的字符串传递给ZoneId.of
。乡亲常用
ZoneId z = ZoneId.of(someStringOfZoneName) ;
可能的存储机制:
- 存放在一个文件中的文本。
- 将文本存储在数据库行中以供应用程序检索。
- 将文本作为条目存储在JNDI工具中(LDAP服务器,Servlet容器中的配置文件等)(请参阅Tutorial)
- 从Web服务进行查询。 (请参阅Tutorial)
- 询问用户的偏好,并将其存储在变量(如类的成员)中,或存储在Servlet环境存储字符串中作为上下文对象或会话对象的属性。您可以通过调用
ZoneId.getAvailableZoneIds
向用户提供所有区域的选择列表。
您可以询问JVM的当前默认区域:ZoneId.systemDefault
。但要小心,这可以随时通过该JVM中任何应用程序中的任何代码进行更改。
你能举个例子说明你想达到什么目的。 – SubOptimal
示例代码中的dateTime是什么? –
你的问题没有写作的意义。最佳做法是在[UTC](https://en.wikipedia.org/wiki/Coordinated_Universal_Time)中完成大部分任务:您的日志记录,业务逻辑,数据存储和数据交换/序列化。仅在业务问题需要或向用户呈现时才使用时区。与Instant.now()类似,UTC值的基本java.time类是'Instant'。我相信我们在最近的其他问题中广泛地介绍了这一点。 –