In joda time how to convert time zone without changing time

JavaDatetimeJodatime

Java Problem Overview


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

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

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

Is there any way by which I can change TimeZone without affecting current time

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());

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

And following is the result when I use this new DateTime(timestamp.getTime(), DateTimeZone.UTC);

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

Java Solutions


Solution 1 - Java

You can use class LocalDateTime

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

and convert LocalDateTime to DateTime

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

Joda DateTime treats any time in millis like "millis since 1970y in current time zone". So, when you create DateTime instance, it is created with current time zone.

Solution 2 - Java

You can use the withZoneRetainFields() method of DateTime to alter the timezone without altering the numerals in the date.

Solution 3 - Java

If your timestamp is: 2015-01-01T00:00:00.000-0500 (this is local time [for me])

Try this:

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

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:

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

2015-01-01T00:00:00.000Z

This gives you a DateTime but with the time converted to your local time:

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

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

Solution 4 - Java

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();
}

Solution 5 - Java

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.

If the timestamp from the database were in fact:

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

Or in ISO-8601 format:

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

Then using the new DateTime(timestamp, DateTimeZone.UTC) constructor works fine. See for yourself:

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:

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.

Solution 6 - Java

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:

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

Solution 7 - Java

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:

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

It's not enough. We also need to change the TimeZone in DateTimeZone as follows:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAbhinavView Question on Stackoverflow
Solution 1 - JavaIlyaView Answer on Stackoverflow
Solution 2 - Javauser1596371View Answer on Stackoverflow
Solution 3 - JavaStvnBrkdllView Answer on Stackoverflow
Solution 4 - JavaRobertView Answer on Stackoverflow
Solution 5 - JavanogridbagView Answer on Stackoverflow
Solution 6 - JavaBen WeaverView Answer on Stackoverflow
Solution 7 - Javaleonardo derksView Answer on Stackoverflow