转换为数据对象时,莫斯科时间晚一小时

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 升级到最新版本后问题得到解决。

以上是关于转换为数据对象时,莫斯科时间晚一小时的主要内容,如果未能解决你的问题,请参考以下文章

Javascript 和 Java 日期 JSON 序列化

Momentjs:将 12 小时转换为日期对象

使用 Duration 对象在 Java 中将天、分钟、小时转换为秒失败

IOS- 时间格式转换问题(12小时和24小时的区别)

为啥 ColdFusion 纪元时间比 javascript 纪元时间晚一小时?

有没有办法将 24 小时时间格式转换为一天的四个类别或四个象限?