0

我有一个测试:

@Test
public void testJodaStartDate2a() {

    DateTime dateTime = new DateTime(2010,10,10,4,0, DateTimeZone.forID("America/Caracas"));

    MutableDateTime mutableDateTime = dateTime.toMutableDateTime();
    mutableDateTime.setDate(dateTime);
    assertEquals(dateTime, mutableDateTime.toDateTime());
}

这很简单,在其中我想将 dateTime 值的日期部分设置为 dateTime 值的日期部分,这应该是有效的,并且断言应该成功。然而它失败了。

由于我无法调试 Joda 的方法,我创建了另一个测试,它模拟 setDate() 必须执行的操作:

@Test
public void testJodaStartDate() {

    DateTime dateTime = new DateTime(2010,10,10,4,0, DateTimeZone.forID("America/Caracas"));

    long instantMillis = DateTimeUtils.getInstantMillis(dateTime);
    Chronology instantChrono = DateTimeUtils.getInstantChronology(dateTime);
    DateTimeZone zone1 = instantChrono.getZone();
    if (zone1 != null) {
        instantMillis = zone1.getMillisKeepLocal(DateTimeZone.UTC, instantMillis);
    }

    MutableDateTime mutableDateTime = dateTime.toMutableDateTime();
    mutableDateTime.setMillis(mutableDateTime.getChronology().millisOfDay().set(instantMillis,
                                                                                mutableDateTime.getMillisOfDay()));
    assertEquals(dateTime, mutableDateTime);
}

此测试是 setDate() 内容的副本。正如我在调试过程中看到的那样,起初,之后

long instantMillis = DateTimeUtils.getInstantMillis(dateTime);

InstantMillis 变量的值是 1286699400000,即 2010-10-10 04:00 (VET) 和 2010-10-10 08:30 (UTC)。

instantMillis = zone1.getMillisKeepLocal(DateTimeZone.UTC, instantMillis);

InstantMillis 是 1286683200000,即 2010-10-10 00:00 (VET) 和 2010-10-10 04:00 (UTC)。

在断言中, mutableDateTime的毫秒值为 1286613000000,即 2010-10-09 04:00 (VET) 和 2010-10-09 08:30 (UTC)。

这个函数不应该只是将 mutableDateTime 的日期部分重新计算为参数值的日期部分吗?我在测试中缺少什么?我非常感激。

4

1 回答 1

1

您似乎发现了一个错误。

以下行是错误的——它应该使用this正在使用的时区。

instantMillis = zone1.getMillisKeepLocal(DateTimeZone.UTC, instantMillis);

快速搜索没有发现当前的错误。我已经提交了一个(在这里)。

我跑了一些测试来检查这次哪些时区有问题。基本上,当给定时区的日期与 UTC 的日期不同时(在同一时刻),似乎会出现问题。

@Test
public void minus0401() {
    DateTime dateTime = new DateTime("2010-10-10T04:00:00",
            DateTimeZone.forOffsetHoursMinutes(-4, 1));
    testDate(dateTime);
}

@Test
public void testIds() {
    List<String> failedIds = new ArrayList<>();
    for (String id : DateTimeZone.getAvailableIDs()) {
        DateTime dateTime = new DateTime("2010-10-10T04:00:00",
                DateTimeZone.forID(id));
        try {
            testDate(dateTime);
        } catch (AssertionError e) {
            failedIds.add(id);
        }
    }
    assertEquals(failedIds.toString(), 0, failedIds.size());
}

@Test
public void testHours() {
    List<Integer> failedHours = new ArrayList<>();
    for (int i = -12; i < 12; i++) {
        DateTime dateTime = new DateTime("2010-10-10T04:00:00",
                DateTimeZone.forOffsetHours(i));
        try {
            testDate(dateTime);
        } catch (AssertionError e) {
            failedHours.add(i);
        }
    }
    assertEquals(failedHours.toString(), 0, failedHours.size());
}

private void testDate(DateTime dateTime) {
    MutableDateTime mutableDateTime = dateTime.toMutableDateTime();
    mutableDateTime.setDate(dateTime);
    assertEquals(dateTime, mutableDateTime.toDateTime());
}
于 2012-09-27T15:52:27.230 回答