为什么 java 8 时间没有显示时区 Etc/GMT+1 的正确时间
Why is java 8 time not showing me the correct time for timezone Etc/GMT+1
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Etc/GMT+1"));
调试时的这个值显示 2019-07-02T14:23:57.463-01:00[Etc/GMT+1]
应该是 16:23,我错过了什么.. 时钟不知为何慢了 2 小时?
tl;博士
使用时区而不仅仅是偏移量。
ZonedDateTime.now(
ZoneId.of( "Europe/Dublin" )
)
详情
在现代协议中,偏移量中 hours-minutes-seconds 的数量被认为是正数,比基线 (GMT/UTC) 提前 ,而负数数字 落后于 基线。一些较旧的协议是相反的。你的Etc/GMT+1
好像是反的风格。
最好的解决方案是使用时区而不是仅仅偏移。偏移量只是 hours-minutes-seconds 的数字。时区 多。时区是特定地区人们使用的偏移量的过去、现在和未来变化的历史。
时区的名称格式为 Continent/Region
。例如,America/Montreal
、Europe/Paris
和 Pacific/Auckland
。
ZoneId z = ZoneId.of( "Europe/Dublin" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
生成标准 ISO 8601 格式的字符串,明智地扩展以在方括号中附加区域名称。
String output = zdt.toString() ;
您的大部分业务逻辑、日志记录和数据更改都应使用 UTC。要调整为 UTC,请从您的 ZonedDateTime
中提取一个 Instant
。同一时刻,时间轴上的同一点,但 wall-clock 时间不同。
Instant instant = zdt.toInstant() ;
生成标准 ISO 8601 格式的字符串。
String output = instant.toString() ;
你的例子
所以现在我们可以回去检查您的具体情况。
让我们用 [Etc/GMT+1]
作为区域名称来解析给定的字符串。
String input = "2019-07-02T14:23:57.463-01:00[Etc/GMT+1]" ;
ZonedDateTime zdtInput = ZonedDateTime.parse ( input );
然后调整为UTC。
Instant instant = zdtInput.toInstant ();
再次调整为Europe/Dublin
.
ZoneId zDublin = ZoneId.of( "Europe/Dublin");
ZonedDateTime zdtDublin = zdtInput.withZoneSameInstant ( zDublin );
转储到控制台。
System.out.println ("zdtInput: " + zdtInput );
System.out.println ("instant: " + instant );
System.out.println ("zdtDublin: " + zdtDublin );
看到这个code run live at IdeOne.com。
zdtInput: 2019-07-02T14:23:57.463-01:00[Etc/GMT+1]
instant: 2019-07-02T15:23:57.463Z
zdtDublin: 2019-07-02T16:23:57.463+01:00[Europe/Dublin]
14 小时
果然,我们看到 day-of-time 和 [Etc/GMT+1]
比 落后 UTC(小时偏移的旧反向含义)一个小时14
.
15 小时
UTC(偏移量为零 hours-minutes-seconds)有一个小时 15
。
16 小时
那一刻的Dublin time zone is using Irish Standard Time (IST), UTC +1 rather than Daylight Saving Time (DST)。所以我们看到它的时间是 16
,比 UTC 15
小时 提前 小时。
关键: 了解所有这三个代表同一时刻,时间轴上的同一点。他们的 wall-clock 时间不同:查看同一时刻的三种方式。
顺便说一句,如果您想专门使用偏移量而不是时区,请使用 OffsetDateTime
& ZoneOffset
类。 ZonedDateTime
& ZoneId
类 用于时区。
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Etc/GMT+1"));
调试时的这个值显示 2019-07-02T14:23:57.463-01:00[Etc/GMT+1]
应该是 16:23,我错过了什么.. 时钟不知为何慢了 2 小时?
tl;博士
使用时区而不仅仅是偏移量。
ZonedDateTime.now(
ZoneId.of( "Europe/Dublin" )
)
详情
在现代协议中,偏移量中 hours-minutes-seconds 的数量被认为是正数,比基线 (GMT/UTC) 提前 ,而负数数字 落后于 基线。一些较旧的协议是相反的。你的Etc/GMT+1
好像是反的风格。
最好的解决方案是使用时区而不是仅仅偏移。偏移量只是 hours-minutes-seconds 的数字。时区 多。时区是特定地区人们使用的偏移量的过去、现在和未来变化的历史。
时区的名称格式为 Continent/Region
。例如,America/Montreal
、Europe/Paris
和 Pacific/Auckland
。
ZoneId z = ZoneId.of( "Europe/Dublin" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
生成标准 ISO 8601 格式的字符串,明智地扩展以在方括号中附加区域名称。
String output = zdt.toString() ;
您的大部分业务逻辑、日志记录和数据更改都应使用 UTC。要调整为 UTC,请从您的 ZonedDateTime
中提取一个 Instant
。同一时刻,时间轴上的同一点,但 wall-clock 时间不同。
Instant instant = zdt.toInstant() ;
生成标准 ISO 8601 格式的字符串。
String output = instant.toString() ;
你的例子
所以现在我们可以回去检查您的具体情况。
让我们用 [Etc/GMT+1]
作为区域名称来解析给定的字符串。
String input = "2019-07-02T14:23:57.463-01:00[Etc/GMT+1]" ;
ZonedDateTime zdtInput = ZonedDateTime.parse ( input );
然后调整为UTC。
Instant instant = zdtInput.toInstant ();
再次调整为Europe/Dublin
.
ZoneId zDublin = ZoneId.of( "Europe/Dublin");
ZonedDateTime zdtDublin = zdtInput.withZoneSameInstant ( zDublin );
转储到控制台。
System.out.println ("zdtInput: " + zdtInput );
System.out.println ("instant: " + instant );
System.out.println ("zdtDublin: " + zdtDublin );
看到这个code run live at IdeOne.com。
zdtInput: 2019-07-02T14:23:57.463-01:00[Etc/GMT+1]
instant: 2019-07-02T15:23:57.463Z
zdtDublin: 2019-07-02T16:23:57.463+01:00[Europe/Dublin]
14 小时
果然,我们看到 day-of-time 和 [Etc/GMT+1]
比 落后 UTC(小时偏移的旧反向含义)一个小时14
.
15 小时
UTC(偏移量为零 hours-minutes-seconds)有一个小时 15
。
16 小时
那一刻的Dublin time zone is using Irish Standard Time (IST), UTC +1 rather than Daylight Saving Time (DST)。所以我们看到它的时间是 16
,比 UTC 15
小时 提前 小时。
关键: 了解所有这三个代表同一时刻,时间轴上的同一点。他们的 wall-clock 时间不同:查看同一时刻的三种方式。
顺便说一句,如果您想专门使用偏移量而不是时区,请使用 OffsetDateTime
& ZoneOffset
类。 ZonedDateTime
& ZoneId
类 用于时区。