简体   繁体   中英

How can I convert date time from time zone A to time zone B in Joda time?

Imagine I have some datetime value coming from one system, and a timezone information (source and target time zones) coming from another. I need to convert the datetime from source to target time zone.

For example, let's say I get a datetime in the Moscow time zone. I need to convert it to the Berlin time zone. How can I do it using Joda Time?

private static final String TIMEZONE_BERLIN_ID = "Europe/Berlin"; //$NON-NLS-1$

private static final DateTimeZone TIMEZONE_BERLIN = DateTimeZone
    .forID(TIMEZONE_BERLIN_ID);

private static final DateTimeZone TIMEZONE_MOSCOW = DateTimeZone
    .forID("Europe/Moscow"); //$NON-NLS-1$

@Test
public void testDateTimeConversion() {
    final Date sourceDateTime = new DateTime(2015, 3, 15, 12, 55).toDate();
    // We assume that sourceDateTime is in TIMEZONE_MOSCOW. We want to convert it to TIMEZONE_BERLIN.
    // Note that the conversion should work regardless whether sourceDateTime contains any timezone
    // information. It must be converted from TIMEZONE_MOSCOW to TIMEZONE_BERLIN (regardless of whether
    // a timezone is specified in it).
    final Date expectedResult =
        new DateTime(2015, 3, 15, 12 - 2, 55).toDate(); // At 12:55 in Moscow, it is 10:55 in Berlin.
    final Date actualResult =
        new DateTime(sourceDateTime, TIMEZONE_MOSCOW).toDateTime(
            TIMEZONE_BERLIN).toDate();
    Assert.assertEquals(expectedResult, actualResult);
}

Why does actualResult contain wrong datetime?

new DateTime(sourceDateTime, TIMEZONE_MOSCOW).withZone(TIMEZONE_BERLIN).toDate() doesn't work, either.

A java.util.Date object does not contain timezone information. It's just a wrapper around a number of milliseconds since 01-01-1970, 00:00:00 GMT. You cannot have a Date object that is in a specific timezone. A Date object always refers to an "absolute" point in time. You should not pretend that the Date object contains a date and time in a particular timezone (such as Moscow or Berlin timezone).

Instead, you specify the timezone when you format the Date object for display, by setting the timezone you want to see the Date in on the DateFormat object:

DateFormat df1 = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss z");
df1.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));

DateFormat df2 = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss z");
df2.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));

Date now = new Date();

// Note: The same Date object, but displayed in different timezones
System.out.println("The time in Berlin: " + df1.format(now));
System.out.println("The time in Moscow: " + df2.format(now));

This one seems to work:

@Test
public void testDateTimeConversion() {
    final Date sourceDateTime = new DateTime(2015, 3, 15, 12, 55, TIMEZONE_MOSCOW).toDate();
    final Date expectedResult =
        new DateTime(2015, 3, 15, 12 - 2, 55, TIMEZONE_BERLIN).toLocalDateTime().toDate();

    final DateTime timeInMoscow =
        new DateTime(sourceDateTime, TIMEZONE_MOSCOW);
    final DateTime timeInBerlin = timeInMoscow.toDateTime(TIMEZONE_BERLIN);
    final Date actualResult = timeInBerlin.toLocalDateTime().toDate();

    Assert.assertEquals(expectedResult, actualResult);
}

I think this one addresses your concern. Just convert this logic to JUnit then it will work.

    DateTimeZone TIMEZONE_BERLIN = DateTimeZone.forID("Europe/Berlin");
    DateTimeZone TIMEZONE_MOSCOW = DateTimeZone.forID("Europe/Moscow");

    //moscow timezone 12:55
    DateTime sourceTimeMoscow = new DateTime(2015, 3, 15, 12, 55, TIMEZONE_MOSCOW);
    //berlin time expected 10:55
    Date expectedResult = new DateTime(2015, 3, 15, 10, 55, TIMEZONE_BERLIN).toLocalDateTime().toDate();
    //get actual result in Berlin in reference to Moscow
    Date actualResult = new DateTime(sourceTimeMoscow, TIMEZONE_BERLIN).toLocalDateTime().toDate();

    //for display purposes
    System.out.println(expectedResult); //expected result Berlin Time
    System.out.println(actualResult); //actual result Berlin Time

I hope this solution addresses your issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM