【问题标题】:Joda Time subtracting 24 hours from an instance of MutableDateTime, I would like to know whyJoda Time 从 MutableDateTime 的实例中减去 24 小时,我想知道为什么
【发布时间】:2011-05-02 00:39:29
【问题描述】:

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

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

我在这里遗漏了什么,或者我应该如何编辑代码以获得所需的结果?我是 Joda Time 的新手,想解开这个谜。

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

谢谢

【问题讨论】:

    标签: java timezone jodatime


    【解决方案1】:

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

    public void setDate(ReadableInstant 瞬间)

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

    参数: Instant - 复制日期的瞬间 从,时间部分忽略

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

    当 Joda 说“日期”时,它表示日期这个词的人类含义。 “此值的年月日部分”,而不是 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 EDT 并将时间的绝对量级设置为代表 10/27/2010 00:00 UTC 的毫秒数,这当然是前一天下午 6 点或 7 点.然后它发现它的 EDT 日期值是 10/26。

    不能说这是出于某种目的,还是存在 2 年之久的错误。)

    【讨论】:

    • 谢谢你,Affe。您使用解析的日期字符串而不是使用 setDate() 更新 MutableDateTime 的修复工作有效。对根本原因的解释也非常感谢。我会将此解释为一个错误,但可能会有不同的意见。
    • 我已经为此问题创建了一张票 - sourceforge.net/tracker/…
    【解决方案2】:

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

    • 什么都不做,接受在默认时区解析字符串
    • 使用格式化程序上的withZone() 指定要解析的时区
    • 使用parseLocalDate() 而不是parseMutableDateTime()

    最后一个是首选解决方案,因为它正确解析了实际输入的数据,即没有时间、偏移量或区域的日期。

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

    【讨论】:

    • a google for +"parseLocalDate" +joda 返回 6 月的单个 google 群组帖子和 GWT 中的一些代码。在查看源代码之前,我确实使用 withZone() 进行了尝试,结果是相同的。似乎即使我指定了一个区域,MutableDateTime 中的代码也会在我的 Chronology 上看到它,然后将其转换为 UTC,而不是将其转换为 MutableDateTime 的时区。
    猜你喜欢
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    • 2010-12-21
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    相关资源
    最近更新 更多