首页 > 解决方案 > 如何从 MySQL DATETIME 转换为 java.time.Instant 并在系统默认时区显示给用户?

问题描述

我正在为学校做一个项目,我完全不知所措。这是背景:

我正在开发一个将在本地运行的 JavaFX 约会应用程序,因此我不必担心服务器端时区与实际用户时间不同的后果。我不能使用任何 3rd 方库。该应用程序当前使用一个 DatePicker 和两个 ComboBox 控件供用户输入日期、小时和分钟值。这些使用传统的 get/set 方法存储在 Instant 变量(start)中的 Appointment 对象上。我成功地从控件写入数据库,结果如我所料。如果我选择 2019 年 6 月 31 日和 12:00,然后将其写入数据库,它会显示在数据库中,存储在开始列(数据类型为 DATETIME)中为 2019-12-31 17:00: 00. 我在 CST,所以我的 UTC 偏移量是 -5 小时。到目前为止,我相信一切都很美好。

从这里,有些东西向南走。我在 ResultSet 中的每个项目上使用类似这样的东西将每个 DB 约会映射到 ObservableList 对象

Instant start = i_rs.getTimestamp("start").toInstant();
Return newAppointment(start);

对 Instant start 变量的值检查给了我:

2019-12-31T17:00

正如我所料。但是,我似乎无法将此时间成功转换为用户的时区。我最接近的是这个:

ZonedDateTime localStartDate = currentAppointment
            .getStart()
            .atZone(ZoneId.systemDefault());

但这又回来了

2019-12-31T17:00-05:00

我也试过

ZonedDateTime zdt = date.atZone(ZoneOffset.systemDefault());

但它最终将我的时间转向了错误的方向,让我

2019-12-31T22:00

一天多来,我一直在研究这个“简单”的小部分。任何帮助将不胜感激。

标签: javamysqljavafx

解决方案


ZonedDateTime localStartDate = currentAppointment
  .getStart()
  .atZone(ZoneId.systemDefault());

在这里你说“我有一些时间戳,把它当作 CST” 这就是为什么它变成“17:00-05:00”

看来您将时间戳存储在 UTC 中(如果不这样做,那么我建议您将编写代码更改为始终存储在 UTC 中),因此您应该告诉 Java

ZonedDateTime localStartDate = currentAppointment
  .getStart()
  .atZone(ZoneId.of("UTC")) // my instant is UTC
  .withZoneSameInstant(ZoneId.systemDefault()) // convert to my local zone

推荐阅读