【问题标题】:Format ZonedDateTime and Instant to different string format将 ZonedDateTime 和 Instant 格式化为不同的字符串格式
【发布时间】:2019-04-27 22:30:58
【问题描述】:

我阅读了 ZonedDate 和 Instant 的文献,发现我可以通过以下方式将本地时间转换为 UTC:

LocalDate d = LocalDate.now();
LocalTime time = LocalTime.of(00, 00, 00);
ZoneId zone = ZoneId.systemDefault();
ZonedDateTime zonedDateTime = ZonedDateTime.of(d, time, zone);
System.out.println(zonedDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));

Instant instant = zonedDateTime.toInstant();
System.out.println(instant); 

问题是输出看起来像这样:

2018-11-26T00:00:00
2018-11-26T08:00:00Z

我正在尝试以“yyyy-MM-dd HH:mm:ss”的格式获取两个字符串,但是很难让任何东西正常工作。由于我使用输出来查询 MYSQL 数据库,我可以手动执行:

String zoneDate = zonedDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
String utcDate = zonedDateTime.toInstant().toString();
zoneDate = zoneDate.replace('T', ' ').replace('Z', ' ');
utcDate = utcDate.replace('T', ' ').replace('Z', ' ');

我的新输出是:

2018-11-26 00:00:00
2018-11-26 08:00:00 

但我觉得这是不好的做法,应该有一种方法可以在类中转换为正确的格式。有没有这样一种方法可以从默认类中执行上述格式化?

【问题讨论】:

  • System.out.println(instant); 将调用Instant.toString(),因此您一定会使用返回的内容。相反,您应该使用格式化程序来生成格式化字符串,就像使用 zonedDateTime.format(...) 一样,例如通过DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(instant).
  • 我明白,但问题是我无法为 MYSQL 日期时间对象找到合适的格式化程序,如上表所示。我正在调用 toString() 方法,因为如果在声明中设置它,则需要获取字符串本身。您描述的执行 DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(instant) 的方法会引发异常并且堆栈跟踪状态为“java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: Year”
  • 您可能需要使用其他格式化程序或定义自己的格式。除了将字符串传递给 MySQL 可能不是最好的方法之外,我会尝试将 Instant 转换为 java.sql.Date 或类似的东西(取决于驱动程序支持的内容,我没有使用普通的 JDBC过一会儿)。
  • 如果您的 JDBC 驱动程序不接受未格式化的 Instant,给它一个 OffsetDateTime 并完全不用担心格式。这是正确的方法,也是一种简单且无故障的方法。也不要使用两位数00。虽然它在视觉上令人愉悦并且可以工作,但使用 0809 将无法编译,因此这是一个不好的习惯。

标签: java mysql datetime date-formatting


【解决方案1】:

关注下面的sn-p。

LocalDate d = LocalDate.now();
LocalTime time = LocalTime.now();
ZoneId zone = ZoneId.systemDefault();
ZonedDateTime zonedDateTime = ZonedDateTime.of(d, time, zone);
String zoneDate = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(zonedDateTime);
ZonedDateTime utcZonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of(ZoneOffset.UTC.getId()));
String utcZoneDate = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(utcZonedDateTime);

System.out.println(zoneDate);
System.out.println(utcZoneDate);     

输出是

2018-11-26 02:20:08
2018-11-26 10:20:08

更多信息请访问 java doc -> https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

【讨论】:

  • 如何解决 Instant 的问题?我一直在用它来转换为 UTC。
  • 如果您的目的是从偏移值中获取UTC时间,则不需要使用instant。而是将 ZonedDateTime 转换为使用 UTC ZoneId。
  • ZonedDateTime utcZonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of(ZoneOffset.UTC.getId()));
  • 我编辑了上面的内容以包含它,它就像我想要的那样工作。感谢您的帮助!
  • 小写 hh 在一天中的某个小时不正确,并且会给出不正确的结果(经常)。你需要大写的HH
猜你喜欢
  • 2014-10-03
  • 2017-07-14
  • 2019-05-03
  • 2017-05-31
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多