转换为数据对象时,莫斯科时间晚一小时
Posted
技术标签:
【中文标题】转换为数据对象时,莫斯科时间晚一小时【英文标题】:while converting to data object, Moscow time is one hour behind 【发布时间】:2021-08-18 15:46:43 【问题描述】:在我的应用程序中,在转换为日期对象时,我总是比时间晚一小时。这个问题只发生在莫斯科时区。 下面是代码:
MutableDateTime mdt = new MutableDateTime(time);
mdt.setSecondOfMinute(0);
mdt.setMinuteOfDay(0);
mdt.toDate()
在上面的代码中 mdt.todate() 返回 5/30/2021 23:00 而不是 5/31/2021 00:00。
jdk 版本:“1.8.0_191”
【问题讨论】:
你应该检查 TZ/夏令时 ;) TZ 仅适用于欧洲/莫斯科,夏令时是错误的。 这里 MutableDateTime 时间 =new MutableDateTime(new Date().getTime()); 【参考方案1】:编辑:为什么转换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 或其他时间.在这种情况下,我相信您的代码会抛出一个令人惊讶的异常。此外,我发现将单个字段设置为低级,并且更喜欢在一个方法调用中设置所有内容,即使它需要进一步操作来确定要传递给该方法的参数。
链接
Time Zone in Moscow, Russia (Moskva)。 乔达时间Updating the time zone data. Timezone Updater Tool 在 Oracle 的网站上。【讨论】:
我想我们在这里很困惑,这里不是增加一小时。它总是做小一小时。例如:如果今天开始时间是“6 月 6 日 00:00”,则转换后 mutabledatetime.todate() 返回“5 月 31 日 23:00”。我认为夏令时有些问题。 感谢您的回复。你是对的,我一开始没有正确阅读你的问题。我已经编辑解释了为什么时间太早了 1 小时(而不是提前了一个小时),并采用了不同的解决方案。 感谢您的详细解释,知道他们修复了哪个 joda 版本吗? 不,我对此一无所知。我猜它会从 2016 年的 2.9 版开始修复,因为那时莫斯科已经很长时间了 +03:00。 谢谢...在将 joda jar 升级到最新版本后问题得到解决。以上是关于转换为数据对象时,莫斯科时间晚一小时的主要内容,如果未能解决你的问题,请参考以下文章
使用 Duration 对象在 Java 中将天、分钟、小时转换为秒失败