【问题标题】:Java:Convert date in UTC to local time zoneJava:将UTC中的日期转换为本地时区
【发布时间】:2016-12-07 11:24:03
【问题描述】:

我有日期存储在 UTC 时区的 db 中。必须将此日期转换为系统本地时区。我研究了stackoverflow中的所有其他问题,但没有一个对我有用。请任何人都可以帮我解决这个问题。 我只需要 java.utils.Date 中的输出,因为石英调度程序的 startAt() 方法只接受日期。

【问题讨论】:

  • 如果调度程序只接受Date,那么就没有需要关注的时区——Date 代表一个瞬间。我怀疑如果您提供更多背景信息,我们将能够为您提供更多帮助...
  • @dhananjay 你用的是哪个java版本?
  • 实际上日期由 ROR 存储到数据库中,它在存储之前将日期转换为 UTC 格式。因此,当我从 db 获取日期并创建 Date 对象时,时间会从我输入的内容发生变化,因为它的时区发生了变化。所以我需要一种方法来获取 UTC 时区中存储在 db 中的日期并将其转换为本地时区
  • 向我们展示您用于从数据库中获取日期的代码。您是否在此处指定数据库中的日期为 UTC?
  • reminderQueues.setStartDate(rs.getTimestamp("rq.start_date"));其中 rs 是 ResultSet。是的,日期以 UTC 格式存储在 db 中

标签: java date utc


【解决方案1】:

tl;博士

您确实不需要需要应用时区。

详情

Date 已经有一个时区:UTC。它代表一个特定的时刻,时间线上的一个点。您只会应用一个时区以在用户首选的wall-clock time 中显示给用户。 Europe/Paris 的上午 7 点和 Asia/Kolkata 的上午 11:30 设置为 UTC 上午 6 点的闹钟 - 同一时刻。

Date 是 UTC

java.util.Date 类已经使用了UTC。您不能将该对象调整到另一个时区。该类只是 UTC 自 1970 年第一刻以来毫秒数的包装器。不要被它的 toString 方法的混乱行为分心,该方法应用 JVM 当前的默认时区来呈现字符串;内部值采用 UTC

所以你问的(从Date开始,调整到本地时区,然后渲染Date)是不可能的,也没有意义。

我建议您对 StackOverflow 上的其他日期时间问题进行一些搜索和研究,以了解这些概念。专门搜索这些 Java 类:InstantZoneIdZonedDateTime

转化

当需要与尚未更新为 java.time 类型的旧代码交互时,您可以转换为 java.time。调用添加到旧类的新转换方法。

Instant instant = myJavaUtilDate.toInstant();  // UTC.
ZonedDateTime zdt = instant.atZone( ZoneId.of( "America/Montreal" ) );  // Same moment, but different wall-clock time.

您可以从 java.time 类转换。

LocalDate ld = LocalDate.of( 2016 , 1 , 23 );  // 2016-01-23. No time zone at all.
LocalTime lt = LocalTime.of( 6 , 0 , 0 );  // 06:00:00. No time zone at all.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime( ld , lt , z );
Instant instant = zdt.toInstant();  // UTC.

// Convert from modern classes to legacy class.
java.util.Date d = java.util.Date.from( instant );

java.util.Date 实际上确实在其内部设置了一个时区。但是该区域没有设置器和获取器方法。出于我们的目的,我们可以忽略它。令人困惑?是的。在早期的 Java 日期时间类中做出的许多糟糕的设计选择之一。避免这些课程的众多原因之一。只坚持使用 java.time 类。

【讨论】:

  • 我几乎研究了 StackOverFlow 上的所有问题,但没有一个能满足我的要求。既然您说 Date 的时区无法更改,那么问题是我将如何安排调度程序在仅接受 Date 的不同时区执行。 :(
  • @dhananjaysengraphwar 您错过了关键思想:您确实不需要需要应用时区Date 已经有一个时区:UTC。它代表一个特定的时刻,时间线上的一个点。您只会应用一个时区以在用户首选的wall-clock time 中显示给用户。 Europe/Paris 上午 7 点和 Asia/Kolkata 上午 11:30 设置为 UTC 上午 6 点的闹钟 — 同一时刻。也许你应该编辑你的问题来解释更多关于你的问题。
  • 感谢您抽出宝贵时间与我分享详细信息,我很高兴
【解决方案2】:

你可以使用下面的代码

    DateFormat localFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
    localFormat.setTimeZone(TimeZone.getTimeZone("PST"));


    Date locaTime = new Date(localFormat.format(date));

【讨论】:

    【解决方案3】:

    我正在使用来自 java 8 的LocalDateTime。我使用下面的代码从 unix 时间戳获取本地日期时间。可能还有其他方法可以从您想要的格式中获取它。

    Date.from(LocalDateTime.ofEpochSecond(unixTimestamp, 0, ZoneOffset.UTC).toLocalDate());
    

    【讨论】:

    • 此处使用了错误的类。 LocalDateTime 缺少任何时区或偏移量的概念。
    【解决方案4】:

    通过查看 StackOverFlows 问题,找到有助于转换时区的石英类 DateBuilder

    Date startDate = DateBuilder.translateTime(job.getStartDate(), TimeZone.getTimeZone("UTC"), TimeZone.getDefault());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-30
      • 1970-01-01
      • 2021-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多