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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 13:16:29  来源:igfitidea点击:

In joda time how to convert time zone without changing time

javadatetimejodatime

提问by Abhi

I am getting UTC timestamp from database which is I am setting into a JodaTime DateTimeinstance

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

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

It stores the time perfectly say 10:00 AMbut 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 AMto 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 LocalDateTimeto DateTime

并转换LocalDateTimeDateTime

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

Joda DateTimetreats any time in millis like "millis since 1970y in currenttime zone". So, when you create DateTimeinstance, it is created with current time zone.

JodaDateTime以毫秒为单位处理任何时间,就像“当前时区自 1970 年以来的毫秒”一样。因此,当您创建DateTime实例时,它是使用当前时区创建的。

回答by jgm

You can use the withZoneRetainFields()method of DateTimeto 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/Kolkataand 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.Timestampclass roughly correlates to the Joda/Java 8+ Instantclass. Sometimes it's easier to convert between equivalent classes to spot bugs like this earlier.

另外,请记住java.sql.Timestamp该类与 Joda/Java 8+Instant类大致相关。有时,在等效类之间进行转换以更早地发现此类错误会更容易。