Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Joda Time从MutableDateTime实例中减去24小时,我想知道原因_Java_Timezone_Jodatime - Fatal编程技术网

Java Joda Time从MutableDateTime实例中减去24小时,我想知道原因

Java Joda Time从MutableDateTime实例中减去24小时,我想知道原因,java,timezone,jodatime,Java,Timezone,Jodatime,我不明白为什么MutableDateTime.setDate()将时间设置为“昨天”(参见日志时间戳hours-现在是20:28)。这个时区相关吗?我需要在格式化程序上设置一些内容吗 我希望在使用“10/27/2010”调用setDate后,该日期将与解析的日期00:00 EDT 10/27/10相同,而不是20:28 EDT 10/26/10。这是24小时前的“现在” 我在这里遗漏了什么,或者我应该如何编辑代码以获得期望的结果?我是乔达时代的新人,我想解开这个谜 DateTimeFormatt

我不明白为什么
MutableDateTime.setDate()
将时间设置为“昨天”(参见日志时间戳hours-现在是20:28)。这个时区相关吗?我需要在格式化程序上设置一些内容吗

我希望在使用“10/27/2010”调用setDate后,该日期将与解析的日期00:00 EDT 10/27/10相同,而不是20:28 EDT 10/26/10。这是24小时前的“现在”

我在这里遗漏了什么,或者我应该如何编辑代码以获得期望的结果?我是乔达时代的新人,我想解开这个谜

DateTimeFormatter dateFormatterJ = DateTimeFormat.forPattern("MM/dd/yyyy");
DateTimeFormatter timestampFormatJ = DateTimeFormat.forPattern("HH:mm zzz MM/dd/yy");

MutableDateTime startDate = new MutableDateTime();

log.info("parsed date " + 
    timestampFormatJ.print(dateFormatterJ.parseMutableDateTime(startDateString)));

startDate.setDate((dateFormatterJ.parseMutableDateTime(startDateString)));

log.info("startDate: " + timestampFormatJ.print(startDate));
在本例中,
startDateString
只是“10/27/2010”

以下是日志输出:

10-27 20:28:55 INFO parsed date: 00:00 EDT 10/27/10
10-27 20:28:55 INFO startDate: 20:28 EDT 10/26/10

谢谢

简单的答案是,因为javadoc是这么说的

公共无效设置日期(ReadableInstant) (即时)

从另一个日期设置日期 即刻的此对象的时间部分 将不受影响。

参数: instant—复制日期的瞬间 从开始,忽略时间部分

抛出: IllegalArgumentException-如果 对象无效对象无效

当乔达说“日期”时,它的意思是“日期”这个词的人类含义。“该值的年-月-日部分”,不是java.util.Date的逻辑等价物。(joda的全部目的是为处理日期和时间引入一些自然、合理的语义。)

编辑: 要回答您的“如何修复”问题,只需执行以下操作:

MutableDateTime startDate = new MutableDateTime(dateFormatterJ.parseMutableDateTime(startDateString));
或者手动将课程的时间部分归零

编辑2:嗯,我显然读得不够仔细,这只是答案的一半。我会检查的

编辑3:这个问题让我非常头疼,以至于我花了一分钟去寻找它

public void setDate(final ReadableInstant instant) {
    long instantMillis = DateTimeUtils.getInstantMillis(instant);
    Chronology instantChrono = DateTimeUtils.getInstantChronology(instant);
    DateTimeZone zone = instantChrono.getZone();
    if (zone != null) {
        instantMillis = zone.getMillisKeepLocal(**DateTimeZone.UTC**, instantMillis);
    }
    setDate(instantMillis);
}
出于某种原因,它将您的绝对时间向前滚动到UTC,然后再设置日期。所以你给它10/27/2010 00:00美国东部夏令时,它将时间的绝对大小设置为毫秒数,代表10/27/2010 00:00 UTC,当然是前一天下午6点或7点。然后,它发现其EDT日期值为10/26


无法说明这是否出于某种目的,或者这是否是一个已经存在了2年的bug或什么。)

解析不包含GMT偏移量或时区ID的字符串时,必须执行以下三项操作之一:

  • 不执行任何操作,并接受在默认时区解析字符串
  • 使用格式化程序上的
    withZone()
    指定要解析的时区
  • 使用
    parseLocalDate()
    而不是
    parseMutableDateTime()
最后一个是首选解决方案,因为它正确解析实际输入的数据,即没有时间、偏移量或区域的日期


在测试代码中使用
parseLocalDate()
可以正确解析日期。

谢谢,Aff。修复了使用解析的日期字符串而不是使用setDate()更新MutableDateTime的问题。对根本原因的解释也很受欢迎。我会把这解释为一个bug,但可能会有不同的意见。我已经为这个问题创建了一个罚单-一个google for+“parseLocalDate”+joda返回了一个google groups六月发布的帖子和一些GWT代码。在查看源代码之前,我确实使用withZone()进行了尝试,结果是一样的。看起来,即使我指定了一个区域,MutableDateTime中的代码也会在我的年表上看到它,然后将其转换为UTC,而不是将其转换为MutableDateTime的时区。