Java 在joda time中,如何在不更改时间的情况下转换时区

Java 在joda time中,如何在不更改时间的情况下转换时区,java,datetime,jodatime,Java,Datetime,Jodatime,我正在从数据库中获取UTC时间戳,我正在将其设置到一个JodaTimeDateTime实例中 DateTime dt = new DateTime(timestamp.getTime()); 它完美地存储了时间,比如上午10:00,但带有本地时区。例如,我在IST时区,距离UTC+5:30 我已经尝试了很多改变时区的方法,但是每一种方法都是通过使用+5:30的时差将时间从10:00 AM改变为其他时间 有没有什么方法可以在不影响当前时间的情况下更改时区 编辑: 如果我的当前时间是: 2013-

我正在从数据库中获取UTC时间戳,我正在将其设置到一个JodaTime
DateTime
实例中

DateTime dt = new DateTime(timestamp.getTime());
它完美地存储了时间,比如上午10:00,但带有本地时区。例如,我在IST时区,距离UTC+5:30

我已经尝试了很多改变时区的方法,但是每一种方法都是通过使用+5:30的时差将时间从
10:00 AM
改变为其他时间

有没有什么方法可以在不影响当前时间的情况下更改时区

编辑: 如果我的当前时间是:

2013-09-25 11:27:34 AM      UTC
下面是我使用这个
newdatetime(timestamp.getTime())的结果

下面是我使用这个
新的DateTime(timestamp.getTime(),DateTimeZone.UTC)时的结果

你可以使用class

并将
LocalDateTime
转换为
DateTime

DateTime dt = new LocalDateTime(timestamp.getTime()).toDateTime(DateTimeZone.UTC);  

Joda
DateTime
将以毫秒为单位的任何时间视为“自1970年以来当前时区的毫秒”。因此,当您创建
DateTime
实例时,它是使用当前时区创建的。

您可以使用
DateTime
withZoneRetainFields()
方法来更改时区,而不更改日期中的数字。

我是这样做的:

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();
}
如果您的时间戳是: 2015-01-01T00:00:00.000-0500 (这是当地时间[对我来说])

试试这个:

DateTime localDt = new DateTime(timestamp.getTime())
    .withZoneRetainFields(DateTimeZone.UTC)
    .withZone(DateTimeZone.getDefault());
2014-12-31T19:00:00.000-05:00

细分: 这将为您提供一个与时间戳对应的日期时间,并指定它以UTC为单位:

new DateTime(timestamp.getTime())
    .withZoneRetainFields(DateTimeZone.UTC)
2015-01-01T00:00:00.000Z

这将为您提供日期时间,但将时间转换为您的本地时间:

new DateTime(timestamp.getTime())
    .withZoneRetainFields(DateTimeZone.UTC)
    .withZone(DateTimeZone.getDefault());

2014-12-31T19:00:00.000-05:00

此外,我还有另一种方法对我非常有用。 我想将我的工作流线程临时更改为一个特定的时区(节省时间),然后当我的代码完成时,我再次设置原始时区。 事实证明,当您使用joda库时,执行以下操作:

TimeZone.setDefault(TimeZone.getTimeZone(myTempTimeZone));
TimeZone.setDefault(timeZone);
这还不够。 我们还需要更改DateTimeZone中的时区,如下所示:

@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
}

希望这对其他人也有帮助。

我也有同样的问题。在阅读了这组有用的答案之后,考虑到我的特殊需求和可用对象,我使用另一个DateTime构造函数解决了这个问题:

new DateTime("2012-04-23T18:25:46.511Z", DateTimeZone.UTC)

所有给出的答案实际上都不能解释这个问题。真正的问题是最初的假设是错误的。数据库中的时间戳是使用本地JVM时区而不是UTC创建的。这是JDBC的默认行为,因此仍然建议将JVM时区设置为UTC

如果来自数据库的时间戳实际上是:

2013-09-25 11:27:34 AM UTC
或采用ISO-8601格式:

2013-09-25T11:27:34Z // The trailing 'Z' means UTC
然后使用
新的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
如果您想知道我是如何得到
138108454000L
,我只是使用了Joda解析类:

ISODateTimeFormat.dateTimeParser().parseMillis("2013-09-25T11:27:34Z")
或者,也可以在网上的网站上输入日期、时间和时区,然后以毫秒为单位返回历元值,反之亦然。它有时可以作为一种精神检查

// 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

另外,请记住
java.sql.Timestamp
类大致与Joda/java8+
Instant
类相关。有时,在等价类之间进行转换以发现前面类似的错误会更容易。

它使用
LocalDateTime
工作,但为什么DateTime会出现这种情况?有什么解决办法吗?@Abhi时间戳是什么
java.util.Date
java.sql.Timestamp
DateTime
没有
getTime
方法。很明显,我遗漏了一些关于这个答案的相关性或正确性的信息。不起作用。与getMillis的转换失败。@Abhi,我迟到了几年,但我在回答中解释了DateTime类的行为。请小心使用这种情况,因为如果在夏令时配置的环境中使用它,在时间转换时可能会引发异常。如果你有文本中的日期,你可能更喜欢这样的解决方案。你能告诉我哪种方法对你有效吗?@ShajeelAfzal当我不想玩弄时区时,我通常使用
LocalDateTime
。Joda time怎么知道什么是时区2012-04-23T18:25:46.511Z?
Timestamp timestamp = new Timestamp(1380108454000L);
DateTime dt = new DateTime(timestamp.getTime(), DateTimeZone.UTC);
System.out.println(dt); // => 2013-09-25T11:27:34.000Z
ISODateTimeFormat.dateTimeParser().parseMillis("2013-09-25T11:27:34Z")
// 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