Java Joda MutableDateTime和#x27;s setDate(日期时间)方法是否有效?

Java Joda MutableDateTime和#x27;s setDate(日期时间)方法是否有效?,java,jodatime,Java,Jodatime,我有一个测试: @Test public void testJodaStartDate2a() { DateTime dateTime = new DateTime(2010,10,10,4,0, DateTimeZone.forID("America/Caracas")); MutableDateTime mutableDateTime = dateTime.toMutableDateTime(); mutableDateTime.setDate(dateTime)

我有一个测试:

@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()必须执行的操作:

此测试是setDate()内容的副本。正如我在调试过程中看到的,首先,在

long instantMillis = DateTimeUtils.getInstantMillis(dateTime);
instantMillis变量的赋值为1286699400000,即2010-10-10 04:00(VET)和2010-10-10 08:30(UTC)

之后

instantMillis为1286683200000,分别为2010-10-10 00:00(VET)和2010-10-10 04:00(UTC)

在断言时,mutableDateTime的毫秒值为1286613000000,即2010-10-0904:00(VET)和2010-10-0908:30(UTC)


这个函数不是应该将mutableDateTime的日期部分重新计算为参数值的日期部分吗?我在考试中遗漏了什么?非常感谢。

您似乎发现了一个bug

下面的一行是错误的——它应该使用
正在使用的时区

instantMillis = zone1.getMillisKeepLocal(DateTimeZone.UTC, instantMillis);
快速搜索未发现当前错误。我现在已经提交了一份()

我运行了一些测试,以检查此时哪些时区存在问题。基本上,当给定时区的日期与UTC(在同一时刻)的日期不同时,问题似乎就会出现

@测试
公共图书馆0401({
DateTime DateTime=新的日期时间(“2010-10-10T04:00:00”,
DateTimeZone.forOffsetHoursMinutes(-4,1));
testDate(dateTime);
}
@试验
公开无效测试(){
List failedds=new ArrayList();
对于(字符串id:DateTimeZone.getAvailableIDs()){
DateTime DateTime=新的日期时间(“2010-10-10T04:00:00”,
DateTimeZone.forID(id));
试一试{
testDate(dateTime);
}捕获(断言错误){
failedds.add(id);
}
}
assertEquals(failedIds.toString(),0,failedIds.size());
}
@试验
公共空测试小时数(){
List failedHours=新建ArrayList();
对于(int i=-12;i<12;i++){
DateTime DateTime=新的日期时间(“2010-10-10T04:00:00”,
DateTimeZone.ForOffesthours(i));
试一试{
testDate(dateTime);
}捕获(断言错误){
故障时间。添加(i);
}
}
assertEquals(failedHours.toString(),0,failedHours.size());
}
私有void testDate(DateTime DateTime){
MutableDateTime MutableDateTime=dateTime.toMutableDateTime();
mutableDateTime.setDate(日期时间);
assertEquals(dateTime,mutableDateTime.toDateTime());
}

和?这是第二次测试的代码,我从Joda的源代码中获取。据我所知,它设置的日期部分不是从我传入它的那一刻开始,而是从表示相同本地时间但在UTC时区的那一刻开始。这就是它失败的原因,因为UTC中的瞬间是本例中VET中的另一个日期(-1天)。当调用setDate(long)时,它首先将long的日期部分转换为宿主mutableDateTime值来查找它。这是一天以前的事了。所以这就是它不起作用的原因。对吗?你问这个方法是如何工作的,并且说你不能调试joda的方法(我不知道你为什么不能)。所以我刚刚告诉你在哪里可以找到源代码,看看它是如何工作的。谢谢你,但是我已经有了源代码,因为我无法调试它们,所以我创建了第二个测试,在那里我已经内联了这个方法。我错过了。很抱歉但是没有理由不能调试joda的代码。只需将源代码附加到IDE中joda的jar文件中。第一个测试就是告诉它不工作,因为直觉上暗示它可以工作imho,所以我很惊讶,问了这个问题,所以有人可以确认和否认我没有遗漏任何内容,是的,这正是它应该工作的方式。修正于
instantMillis = zone1.getMillisKeepLocal(DateTimeZone.UTC, instantMillis);
instantMillis = zone1.getMillisKeepLocal(DateTimeZone.UTC, instantMillis);
@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());
}