繁体   English   中英

如何在Joda时间中将日期时间从时区A转换为时区B?

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

想象一下,我有一些来自一个系统的datetime值,和一个时区信息(源和目标时区)来自另一个系统。 我需要将datetime从源转换为目标时区。

例如,假设我得到了莫斯科时区的日期时间。 我需要将其转换为柏林时区。 我该如何使用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);
}

为什么actualResult包含错误的日期时间?

new DateTime(sourceDateTime, TIMEZONE_MOSCOW).withZone(TIMEZONE_BERLIN).toDate()也不起作用。

java.util.Date对象不包含时区信息。 自格林尼治标准时间1970年1月1日00:00:00以来,它只是一个毫秒数的包装器。 您不能具有位于特定时区的Date对象。 Date对象始终引用“绝对”时间点。 您不应假装Date对象包含特定时区(例如莫斯科或柏林时区)中的日期和时间。

而是在设置要显示的Date对象的格式时指定时区,方法是设置要在DateFormat对象上看到Date的时区:

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

这似乎可行:

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

我认为这一点可以解决您的问题。 只要将此逻辑转换为JUnit,它就可以工作。

    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

希望此解决方案能解决您的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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