在Java中更改时区而不更改时间
我从 SOAP Web 服务接收没有时区信息的日期时间。因此,Axis 解串器采用 UTC。但是,日期时间确实是悉尼时间。我通过减去时区偏移量解决了这个问题:
Calendar trade_date = trade.getTradeDateTime();
TimeZone est_tz = TimeZone.getTimeZone("Australia/Sydney");
long millis = trade_date.getTimeInMillis() - est_tz.getRawOffset();
trade_date.setTimeZone( est_tz );
trade_date.setTimeInMillis( millis );
但是,我不确定这个解决方案是否也考虑了夏令时。我认为应该如此,因为所有操作均以 UTC 时间进行。有没有在 Java 中操作时间的经验?关于如何解决这个问题的更好的想法?
I'm receiving a datetime from a SOAP webservice without timzone information. Hence, the Axis deserializer assumes UTC. However, the datetime really is in Sydney time. I've solved the problem by substracting the timezone offset:
Calendar trade_date = trade.getTradeDateTime();
TimeZone est_tz = TimeZone.getTimeZone("Australia/Sydney");
long millis = trade_date.getTimeInMillis() - est_tz.getRawOffset();
trade_date.setTimeZone( est_tz );
trade_date.setTimeInMillis( millis );
However, I'm not sure if this solution also takes daylight saving into account. I think it should, because all operations are on UTC time. Any experiences with manipulating time in Java? Better ideas on how to solve this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我可怜那些必须用 Java 进行约会的傻瓜。
在夏令时转换期间,您所做的几乎肯定会出错。最好的方法可能是创建一个新的 Calendar 对象,在其上设置时区,然后单独设置所有字段,例如年,月,日,小时,分钟,秒,从 Date 对象中获取值。
编辑:
为了让每个人都满意,您可能应该这样做:
这样您就不会使用任何已弃用的方法。
I pity the fool who has to do dates in Java.
What you have done will almost certainly go wrong around the daylight savings transitions. The best way to to it is probably to create a new Calendar object, set the Timezone on it, and then set all of the fields individually, so year, month, day, hour, minute, second, getting the values from the Date object.
Edit:
To keep the everyone happy, you should probably do this:
Then you won't be using any deprecated methods.
我要感谢这个人的回复 6。这对我来说是一个很好的开始,也是我没有考虑过的方法。需要一些额外的步骤才能将其提升到生产代码级别。特别要注意 DST_OFFSET 和 ZONE_OFFSET 所需的步骤。我想分享我想出的解决方案。
这从输入 Calendar 对象中获取时间,将其复制到输出时间,并将新时区设置为输出。当从数据库中获取时间并设置时区而不更改时间时,会使用此方法。
I want to thank the person for responce 6. This was a great start for me and an approach I did not consider. There are some addtional steps required to bring it to production code level. In particular observe the steps required for DST_OFFSET and ZONE_OFFSET. I want to share the solution I came up with.
This takes the time from the input Calendar object, copies it to the output time, sets the new time zone to the output. This is used when taking time literally from the database and setting the Time Zone without changing the time.
是的,您应该考虑夏令时,因为它会影响与 UTC 的偏移。
Joda-Time 是一个更好的时间 API。也许以下代码片段可能会有所帮助:
JodaTime 类型是不可变的,这也是一个好处。
Yes, you should take the daylight saving into account, since it affects the offset to UTC.
Joda-Time is a better time API. Maybe the following snippet could be of help :
JodaTime types are immutable which is also a benefit.
我通常这样做
I normally do it this way
您是否从那个混乱的 Web 服务中获取了 ISO 8601 样式的字符串?如果是这样,Joda-Time 2.3 库会让这一切变得非常简单。
如果您获取没有任何时区偏移的 ISO 8601 字符串,则将时区对象传递给 DateTime 构造函数。
转储到控制台...
运行时...
Are you getting an ISO 8601 style string from that messed-up Web Service? If so, the Joda-Time 2.3 library makes this very easy.
If you are getting an ISO 8601 string without any time zone offset, you pass a time zone object to the DateTime constructor.
Dump to console…
When run…
运行日历测试
2016-06-30 19:09:16.522 +0300
1467302956522
2016-06-30 19:09:16.522 +0100
1467310156522
测试运行:1,失败:0,错误:0,跳过:0,已用时间:0.137 秒
Running CalendarTest
2016-06-30 19:09:16.522 +0300
1467302956522
2016-06-30 19:09:16.522 +0100
1467310156522
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.137 sec
我决定重新解析接收到的带有正确时区设置的日期时间字符串。这还应该考虑夏令时:
I've decided to reparse the datetime string received with the correct time zone set. This should also consider daylight saving: