57

我正在从数据库中获取 UTC 时间戳,我将其设置为 JodaTimeDateTime实例

DateTime dt = new DateTime(timestamp.getTime());

它完美地存储了时间,10:00 AM但带有本地时区。例如,我在 IST 时区,距 UTC +5:30

我已经尝试了很多方法来更改时区,但是每件事都会10:00 AM通过使用 +5:30 差异将时间从其他时间更改为其他时间

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

编辑:如果我现在的时间是:

2013-09-25 11:27:34 AM      UTC

以下是我使用它时的结果new DateTime(timestamp.getTime());

2013-09-25 11:27:34 AM  Asia/Kolkata

以下是我使用它时的结果new DateTime(timestamp.getTime(), DateTimeZone.UTC)

2013-09-25 05:57:34 AM  UTC
4

7 回答 7

51

您可以使用类LocalDateTime

LocalDateTime dt = new LocalDateTime(t.getTime()); 

并转换LocalDateTimeDateTime

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

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

于 2013-09-25T11:21:55.493 回答
47

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

于 2013-09-25T15:36:07.063 回答
14

如果您的时间戳是: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

将其分解:这将为您提供与您的时间戳相对应的 DateTime,并指定它采用 UTC:

new DateTime(timestamp.getTime())
    .withZoneRetainFields(DateTimeZone.UTC)

2015-01-01T00:00:00.000Z

这会给你一个 DateTime 但时间转换为你的本地时间:

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

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

于 2015-09-09T14:56:52.950 回答
2

这是我的做法:

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-04-30T07:48:41.087 回答
2

给出的答案都没有真正解释这个问题。真正的问题是最初的假设是不正确的。数据库中的时间戳是使用本地 JVM 时区Asia/Kolkata而不是 UTC 创建的。这是 JDBC 的默认行为,因此仍建议将 JVM 时区设置为 UTC。

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

2013-09-25 11:27:34 AM UTC

或采用 ISO-8601 格式:

2013-09-25T11:27:34Z // The trailing 'Z' means UTC

然后使用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

如果你想知道我是怎么得到1380108454000L的,我只是使用了 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/Java 8+ 类大致相关Instant。有时在等价类之间进行转换以更早地发现此类错误会更容易。

于 2019-07-23T05:26:18.567 回答
1

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

new DateTime("2012-04-23T18:25:46.511Z", DateTimeZone.UTC)
于 2018-04-08T12:05:43.540 回答
0

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

TimeZone.setDefault(TimeZone.getTimeZone(myTempTimeZone));
TimeZone.setDefault(timeZone);

这不够。我们还需要更改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
}

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

于 2017-03-05T19:48:25.570 回答