编辑:为什么转换mdt.toDate()后的“June 6 00:00”变成了“May 31 23:00”?
您令人惊讶的观察结果可能来自旧的 Joda-Time 版本,该版本具有旧时区数据库,其中欧洲/莫斯科的偏移量为 +04:00 而不是 +03:00。那是在 2010 年 10 月 31 日到 2014 年 10 月 26 日之间。如果 Joda-Time“相信”情况仍然如此,它会将您的 MutableDateTime 设置为类似于 2021-06-01T00:00:00.000+04:00 的偏移量 +04:00 而不是 +03:00。这对应于2021-05-31T20:00Z UTC,其中正确的时间点应该是2021-05-31T21:00Z UTC。换句话说,太早了一个小时。因此你得到一个Date 也太早了一个小时。您的 Java 1.8 “知道”莫斯科这些天的偏移量为 +03:00,因此将时间打印为 Mon May 31 23:00:00 MSK 2021。
解决方案包括:
- 升级到具有最新时区数据库的更新版本的 Joda-Time。
- 从源代码构建您的 Joda-Time,用于您仅与较新的捆绑时区数据库一起使用的版本。 Joda-Time 主页对此进行了说明,请参阅下面的第二个链接。
原答案
您令人惊讶的观察结果可能来自具有旧时区数据库的旧 Java 版本,其中欧洲/莫斯科的偏移量为 +04:00 而不是 +03:00。那是在 2010 年 10 月 31 日到 2014 年 10 月 26 日之间。我在我的 Java 1.7.0_67 上复制了你的结果,并验证了我的 Java 安装“相信”莫斯科位于偏移 +04:00 并且不使用夏令时 (DST),与上述时期的情况一样。
您的 Joda-Time 似乎足够新,知道欧洲/莫斯科在 +03:00,因此在相关日期的 00:00 正确地将您的 MutableDateTime 转换为 Date。仅当您打印此 Date 时,Java 使用其默认时区,仍然是欧洲/莫斯科,但使用其自己的时区数据,因此错误地将时间打印为 01:00 小时而不是 00:00。
可能的解决方案包括:
- 升级到具有最新时区数据的较新 Java 版本。
- 通过仅升级其时区数据库来修复您当前的 Java 安装。请参阅下面第二个链接中的时区更新工具。
将时间设置为一天的开始
编辑:您添加了:
这里MutableDateTime time =new MutableDateTime(new Date().getTime());
要使用 Joda-Time 获取代表今天日期开始的 Date:
Date oldfashionedDateObject = LocalDate.now(DateTimeZone.getDefault()).toDate();
System.out.println(oldfashionedDateObject);
刚才的输出:
5 月 31 日星期一 00:00:00 MSK 2021
原创:顺便说一句,将时间设置为一天开始的更简单、更安全的方法是:
mdt = mdt.toDateTime().withTimeAtStartOfDay().toMutableDateTime();
如果您需要保留相同的 MutableDateTime 对象,请改为:
mdt.setMillis(mdt.toDateTime().withTimeAtStartOfDay().toInstant());
首先我会担心您的代码可能会在某个时区运行,并且在该时区的某一天在 00:00 发生转换,因此一天的第一刻是 01:00 或其他时间.在这种情况下,我相信您的代码会抛出一个令人惊讶的异常。此外,我发现将单个字段设置为低级,并且更喜欢在一个方法调用中设置所有内容,即使它需要进一步操作来确定要传递给该方法的参数。
链接