Java 在乔达时间如何转换时区而不改变时间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19002978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In joda time how to convert time zone without changing time
提问by Abhi
I am getting UTC timestamp from database which is I am setting into a JodaTime DateTime
instance
我从数据库中获取 UTC 时间戳,我正在将其设置为 JodaTimeDateTime
实例
DateTime dt = new DateTime(timestamp.getTime());
It stores the time perfectly say 10:00 AM
but with local time zone. E.g, I am in IST time zone which is +5:30 from UTC
它可以完美地存储时间,10:00 AM
但使用本地时区。例如,我在 IST 时区,它是 UTC +5:30
I have tried lots of things for changing the timezone but with every thing it changes the time from 10:00 AM
to something else by using +5:30 difference
我已经尝试了很多改变时区的方法,但是每件事10:00 AM
都通过使用 +5:30 的差异来改变时间
Is there any way by which I can change TimeZone without affecting current time
有什么方法可以在不影响当前时间的情况下更改 TimeZone
EDIT: If my current time is:
编辑:如果我当前的时间是:
2013-09-25 11:27:34 AM UTC
Following is the result when I use this new DateTime(timestamp.getTime());
以下是我使用它时的结果 new DateTime(timestamp.getTime());
2013-09-25 11:27:34 AM Asia/Kolkata
And following is the result when I use this new DateTime(timestamp.getTime(), DateTimeZone.UTC)
;
以下是我使用它时的结果new DateTime(timestamp.getTime(), DateTimeZone.UTC)
;
2013-09-25 05:57:34 AM UTC
采纳答案by Ilya
You can use class LocalDateTime
您可以使用类LocalDateTime
LocalDateTime dt = new LocalDateTime(t.getTime());
and convert LocalDateTime
to DateTime
并转换LocalDateTime
为DateTime
DateTime dt = new LocalDateTime(timestamp.getTime()).toDateTime(DateTimeZone.UTC);
Joda DateTime
treats any time in millis like "millis since 1970y in currenttime zone". So, when you create DateTime
instance, it is created with current time zone.
JodaDateTime
以毫秒为单位处理任何时间,就像“当前时区自 1970 年以来的毫秒”一样。因此,当您创建DateTime
实例时,它是使用当前时区创建的。
回答by jgm
You can use the withZoneRetainFields()
method of DateTime
to alter the timezone without altering the numerals in the date.
您可以使用 的withZoneRetainFields()
方法DateTime
更改时区而不更改日期中的数字。
回答by Robert
Here's how I do it:
这是我的方法:
private DateTime convertLocalToUTC(DateTime eventDateTime) {
// get your local timezone
DateTimeZone localTZ = DateTimeZone.getDefault();
// convert the input local datetime to utc
long eventMillsInUTCTimeZone = localTZ.convertLocalToUTC(eventDateTime.getMillis(), false);
DateTime evenDateTimeInUTCTimeZone = new DateTime(eventMillsInUTCTimeZone);
return evenDateTimeInUTCTimeZone.toDate();
}
回答by StvnBrkdll
If your timestamp is: 2015-01-01T00:00:00.000-0500 (this is local time [for me])
如果你的时间戳是:2015-01-01T00:00:00.000-0500(这是当地时间[对我来说])
Try this:
尝试这个:
DateTime localDt = new DateTime(timestamp.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
.withZone(DateTimeZone.getDefault());
2014-12-31T19:00:00.000-05:00
2014-12-31T19:00:00.000-05:00
Breaking it down: This gives you a DateTime corresponding to your timestamp, specifying that it is in UTC:
分解:这会为您提供与时间戳对应的 DateTime,指定它是 UTC:
new DateTime(timestamp.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
2015-01-01T00:00:00.000Z
2015-01-01T00:00:00.000Z
This gives you a DateTime but with the time converted to your local time:
这为您提供了一个 DateTime,但将时间转换为您的本地时间:
new DateTime(timestamp.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
.withZone(DateTimeZone.getDefault());
2014-12-31T19:00:00.000-05:00
2014-12-31T19:00:00.000-05:00
回答by leonardo derks
Also i have another approach that was very helpful for me. I wanted to have my workflow thread temporary changed to an specific Timezone (conserving the time), and then when my code finishes, i set the original timezone again. It turns out that when you are using joda libraries, doing:
我还有另一种对我非常有帮助的方法。我想让我的工作流线程临时更改为特定的时区(节省时间),然后当我的代码完成时,我再次设置原始时区。事实证明,当您使用 joda 库时,请执行以下操作:
TimeZone.setDefault(TimeZone.getTimeZone(myTempTimeZone));
TimeZone.setDefault(timeZone);
It's not enough. We also need to change the TimeZone in DateTimeZoneas follows:
这不够。我们还需要更改DateTimeZone 中的 TimeZone如下:
@Before
public void setUp() throws Exception {
timeZone = TimeZone.getDefault();
dateTimeZone = DateTimeZone.getDefault();
}
@After
public void tearDown() throws Exception {
TimeZone.setDefault(timeZone);
DateTimeZone.setDefault(dateTimeZone);
}
@Test
public void myTest() throws Exception {
TimeZone.setDefault(TimeZone.getTimeZone(myTempTimeZone));
DateTimeZone.setDefault(DateTimeZone.forID(myTempTimeZone));
//TODO
// my code with an specific timezone conserving time
}
Hope it helps to somebody else as well.
希望它对其他人也有帮助。
回答by Ben Weaver
I had the same problem. After reading this set of useful answers, and given my particular needs and available objects, I solved it by using another DateTime constructor:
我有同样的问题。在阅读了这组有用的答案后,并考虑到我的特殊需求和可用对象,我使用另一个 DateTime 构造函数解决了这个问题:
new DateTime("2012-04-23T18:25:46.511Z", DateTimeZone.UTC)
回答by nogridbag
None of the given answers actually explained the problem. The real problem is the initial assumptions were incorrect. The timestamp from the database was created using the local JVM timezone Asia/Kolkata
and not UTC. This is the default behavior with JDBC which is why it's still recommended to set your JVM timezone to UTC.
给出的答案都没有真正解释这个问题。真正的问题是最初的假设是不正确的。数据库中的时间戳是使用本地 JVM 时区Asia/Kolkata
而不是 UTC 创建的。这是 JDBC 的默认行为,这就是为什么仍然建议将 JVM 时区设置为 UTC 的原因。
If the timestamp from the database were in fact:
如果来自数据库的时间戳实际上是:
2013-09-25 11:27:34 AM UTC
Or in ISO-8601 format:
或采用 ISO-8601 格式:
2013-09-25T11:27:34Z // The trailing 'Z' means UTC
Then using the new DateTime(timestamp, DateTimeZone.UTC)
constructor works fine. See for yourself:
然后使用new DateTime(timestamp, DateTimeZone.UTC)
构造函数工作正常。你自己看:
Timestamp timestamp = new Timestamp(1380108454000L);
DateTime dt = new DateTime(timestamp.getTime(), DateTimeZone.UTC);
System.out.println(dt); // => 2013-09-25T11:27:34.000Z
If you're wondering how I got 1380108454000L
, I simply used the Joda parsing classes:
如果你想知道我是怎么得到的1380108454000L
,我只是使用了 Joda 解析类:
ISODateTimeFormat.dateTimeParser().parseMillis("2013-09-25T11:27:34Z")
Alternatively there are websites online where you can enter a date, time, and timezone and it returns the epoch value in milliseconds or vice versa. It's sometimes good as a sanity check.
或者有一些在线网站,您可以在其中输入日期、时间和时区,它会以毫秒为单位返回纪元值,反之亦然。有时作为健全性检查很好。
// https://www.epochconverter.com
Input: 1380108454000 Click: "Timestamp to Human Date"
Assuming that this timestamp is in milliseconds:
GMT: Wednesday, September 25, 2013 11:27:34 AM
Also, keep in mind the java.sql.Timestamp
class roughly correlates to the Joda/Java 8+ Instant
class. Sometimes it's easier to convert between equivalent classes to spot bugs like this earlier.
另外,请记住java.sql.Timestamp
该类与 Joda/Java 8+Instant
类大致相关。有时,在等效类之间进行转换以更早地发现此类错误会更容易。