1 回答
TA贡献1875条经验 获得超3个赞
使用时区而不仅仅是偏移量。
ZonedDateTime.now(
ZoneId.of( "Europe/Dublin" )
)
细节
在现代协议中,偏移量中的小时-分钟-秒数被认为是领先于基线 (GMT/UTC) 的正数,而落后于基线的负数。一些较旧的协议是相反的。您的Etc/GMT+1风格似乎相反。
最好的解决方案是使用时区而不是仅仅使用偏移量。偏移量只是小时数-分钟-秒数。时区要多得多。时区是特定地区的人们使用的偏移量的过去、现在和未来变化的历史。
时区的名称格式为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,请Instant从您的ZonedDateTime. 同一时刻,时间轴上的同一点,但挂钟时间不同。
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 );
在 IdeOne.com 上查看此代码的实时运行。
zdt 输入:2019-07-02T14:23:57.463-01:00[等/GMT+1]
即时:2019-07-02T15:23:57.463Z
zdtDublin: 2019-07-02T16:23:57.463+01:00[欧洲/都柏林]
第 14 小时
果然,我们看到时间比UTC晚[Etc/GMT+1]一个小时(小时偏移的旧反向含义)一个小时。14
第 15 小时
UTC(零小时-分钟-秒的偏移量)有一个小时15。
第 16 小时
都柏林时区当时使用爱尔兰标准时间 (IST)、UTC +1 而不是夏令时 (DST)。所以我们看到它的时间是,比 UTC 的时间早16一个小时。15
关键:理解所有这三个代表同一时刻,时间轴上非常相同的一个点。他们的挂钟时间不同:查看同一时刻的三种方式。
顺便说一句,当您想要专门使用偏移量而不是时区时,请使用OffsetDateTime&ZoneOffset类。ZonedDateTime&类ZoneId用于时区。
添加回答
举报