启动时从主机操作系统。但是定义存储的时区数在内部Java实现。
Java时区更新器
因此,您需要更新Java实现中的时区定义。大多数实现使用tz database亦称为TZDATA.
对于Oracle品牌的Java实现,Oracle提供了Timezone Updater Tool. 该登录页的日期为2018-08,因此可能包括您的时区更改。但我建议你更仔细地调查核实。
对于其他实现,请与供应商核实。他们可能已经提供了JVM的更新版本,以包含新的TZdata。或者他们也提供了一个更新工具。或者您可以手动替换TZDATA文件。
使用代码避免损坏区域
我强烈建议您避免在代码中人为地调整偏移量。你很可能弄错了。约会时间的工作令人惊讶的棘手和混乱。
但是如果你坚持的话,首先要避免像GregorianCalendar
和;Calendar
和;Date
. 这些在几年前被JSR 310所取代。如果必须与尚未更新到的旧代码进行互操作Java.时间在现代类中完成您的工作,然后在最后通过添加到旧类中的新方法进行转换。
使用现代Java.时间类,具体来说:
Instant
(暂时使用UTC)
OffsetDateTime
(暂时与UTC的时差为小时分钟秒,但没有时区)
ZonedDateTime
(在特定时区的某一时刻)
您可以使用这些类在堆栈溢出中搜索许多现有的示例和解释。你应该专注于OffsetDateTime
,ZoneOffset
(而不是ZoneId
)Instant
因为你必须避免ZoDeDeDeTimeTimes
如果你知道你的TZDATA文件过期。
同一时刻,不同的挂钟时间

OffsetDateTime::withOffsetSameInstantâ
OffsetDateTime odt = OffsetDateTime.parse( "2018-10-21T01:00:00.000-02:00" ) ;
ZoneOffset offset = ZoneOffset.ofHours( -3 ) ;
OffsetDateTime odt2 = odt.withOffsetSameInstantâ( offset ) ; // Same moment, same point on the timeline, different wall-clock time.
odt.toString():2018-10-21t01:00-02:00
odt2.toString():2018-10-21t00:00-03:00
在这个例子中,两者都是odt
和odt2
表示同一同时时刻,时间线上的同一点。如果你提取一个瞬间
(以UTC表示的值),您的结果将是相同的。只有他们的挂钟时间不同。
Instant instant1 = odt.toInstant() ; // Adjust to UTC.
Instant instant2 = odt2.toInstant() ;
boolean sameMoment = instant1.equals( instant2 ) ;
Instant1.ToString():2018-10-21t03:00:00z
Instant2.ToString():2018-10-21t03:00:00z
samemomen=真
这个Z
在末尾表示UTC,与UTC的偏移量为零,+00:00
. 这个Z
发音为__zulu__。定义为ISO 8601标准。
不同的时刻,相同的挂钟时间

OffsetDateTime::withOffsetSameLocalâ
相反,您可能希望强制一天中的时间,从而表示不同的时刻。为此,使用withOffsetSameLocal
方法。要知道你是更改数据的含义,您将移动到时间线上的另一个点。
OffsetDateTime differentMomentButSameTimeOfDay = odt. withOffsetSameLocal( offset ) ;
差分时间间隔:2018-10-21t01:00-03:00
提取瞬间,看看我们有不同的时刻。
Instant differentInstant = differentMomentButSameTimeOfDay.toInstant() ;
差分状态toString():2018-10-21t04:00:00z
请注意上面看到的4 AM UTC与3 AM UTC。这一时刻发生在上述时刻一小时后。时间线上的两个不同点。
在完全理解时间线上的点的概念之前,不要尝试这项工作,并且在点之间的变化与调整偏移完全不同。在做真正的工作之前广泛地练习。半心半意的猜测会让你陷入伤痛和头痛的世界。
而且,正如我上面所建议的,您的时间将更好地用于安装更新TZDATA文件而不是黑客攻击这些偏移。
实况编码
查看上面的所有代码run live at IdeOne.com.
更新TZDATA到处
为了获得最佳结果,您应该更新TZDATA在所有这些不同的地方:
关于Java.时间
这个java.time框架是在Java 8和之后构建的。这些阶级取代了麻烦的旧阶级。legacy日期时间类,如java.util.Date
,Calendar
和;SimpleDateFormat
.
这个Joda-Time项目,现在maintenance mode,建议迁移到java.time类。
要了解更多信息,请参阅Oracle Tutorial. 以及搜索堆栈溢出以获得许多示例和解释。规格为JSR 310.
你可以换Java.时间直接使用数据库的对象。使用AJDBC driver顺从JDBC 4.2或稍后。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
这个ThreeTen-ExtraProject使用其他类扩展java.time。这个项目是将来可能添加到java.time的一个试验场。您可以在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more.