【问题标题】:Android Date.from() taking device timezone into account?Android Date.from() 考虑设备时区?
【发布时间】:2023-03-15 05:00:01
【问题描述】:

在Java8中使用以下代码-

newTable.LogDate = Date.from(ZonedDateTime.of(year, month, day, 0, 0, 0, 0, ZoneId.of("GMT")).toInstant());

LogDate 最终会针对我(和我的用户)的设备进行调整。

在上述情况下,例如,如果我发送 1934, 1, 1(1934 年 1 月 1 日),则 LogDate 为 1933 年 12 月 31 日晚上 7 点。 (对于我的设备的美国东部时区。)

有没有办法让 Date 对象不采用设备的时区并进行任何转换?

编辑添加:如果我更改 ZoneId.of("GMT") 并将 JUST IT 更改为 ZoneId.systemDefault(),则最终结果符合预期且“正确”。 (即 1934 年 1 月 1 日停留。)

【问题讨论】:

  • 您如何以及在哪里看到您的时区被考虑在内? (问是因为不是。)
  • @OleV.V.我认为 Date 对象根本没有任何“时区”信息 - 但是,当我在调试期间查看 Android Studio 时,Date 对象的字段部分包含区域偏移时间。 (目前我不知道该字段的名称 - 明天我回到办公室后需要将其拉出来。)
  • 我说得对,Date 的实现通常存储一个时区。我一直不明白为什么,这很令人困惑。一个猜测是它是一个优化的东西。我从未见过它与 JVM 默认时区不同的情况。

标签: android date java-time java.util.date datetime-conversion


【解决方案1】:

设备或 JVM 时区在转换本身中考虑。

Date 类令人困惑。尽管它的名称不代表日期,也不代表一天中的日期和时间。它代表一个时刻,一个时间点,一个瞬间。您可能知道,格林威治标准时间 1934 年 1 月 1 日 00:00 与 1933 年 12 月 31 日晚上 7 点是同一时间点。在 America/New_York 时区。这意味着您得到了正确的转换。不仅如此:这意味着您正在获得唯一可能的正确转换。任何其他到Date 的转换都会给您一个不同的时间点,即错误的时间点。

您可能会感到困惑的是,如果您尝试将 Date 用于某些事情,那么某些事情很可能会假设您打算使用 JVM 和设备的默认时区。例如,如果您打印出Date 或在调试器中查看它,在这两种情况下都隐式调用其toString 方法,那么toString 方法使用您的时区来呈现您看到的字符串:

1933 年 12 月 31 日星期日 19:00:00 EST

toString() 在撒谎。我希望我们相信 Date 包含该值。它不是。它包含自 1970-01-01 00:00 UTC 的 Java 纪元以来的毫秒数。在您的情况下,因为您的时间点在纪元之前是负数,-1 136 073 600 000 毫秒。没有别的了。

解决方案?这取决于您在Date 需要什么以及Date 的要求是什么。理想情况下,您不应该需要Date,因为该类设计不良且早已过时。最好只使用 java.time 中的类,这是 ZonedDateTimeZoneId 所属的现代 Java 日期和时间 API。如果您确实需要Date,也许您已经找到了正确的,只需要清除您的困惑并解决它。如果您给我们理由和要求,我们可能会更好地指导您。

链接: All about java.util.Date on Jon Skeet 的编码博客

【讨论】:

  • 感谢您的回答。此时我(相信)我被 Date 对象困住了,因为该值最终以“Date”类型存储在 ObjectBox 数据库中。其他类型(如LocalDate,实际上也更适合,并且是我开始使用的)需要连接一个自定义转换器,以将值保存为基本类型。 (字符串、整数等)
  • 我不知道 ObjectBox。如果我正确理解this page,ObjectBox 存储我提到的毫秒值,所以你应该设置,我猜。我仍然希望摆脱令人困惑的 Date 类并从 java.time 存储例如 Instant,即使这意味着编写自定义转换器。
  • 您推荐InstantLocalDate?我注意到后者只存储日期,这在这个用例中很重要。如果我必须写一个转换器,我会的。 :)
  • 是的,在这种情况下是LocalDate,你是对的。类名中的local表示无时区
猜你喜欢
  • 2012-10-29
  • 1970-01-01
  • 1970-01-01
  • 2014-08-26
  • 2017-09-15
  • 2019-12-06
  • 2021-12-26
  • 2019-08-26
  • 1970-01-01
相关资源
最近更新 更多