0

我正在尝试保存LocalDateTime到数据库。所以我的情况是我有消费者和生产者。生产者生成一些代码并将其提供给消费者,消费者将条目保存到数据库中。

生产者端代码

LocalDate.now().toString() // returns 2021-07-13T12:25:38.841775700 sometimes it returns 2021-07-13T12:25:38.841 so basically after the last decimal point the precision can be anything.

消费者方面的代码

在消费者方面,我想将从生产者收到的条目保存到数据库中,因为我需要将 str 转换为 LocalDateDime。

  private static DateTimeFormatter timeFormatterInMs= DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");

  public static LocalDateTime unmarshalDateTime(final String dateTimeStr) {
    return dateTimeStr == null ? null : LocalDateTime.parse(str, timeFormatterInMs);
  }

这里的问题是 LocalDateTime 的返回类型的格式是什么

我知道它返回格式yyyy-MM-dd'T'HH:mm:ss.SSS的数据,在我们的例子中,ms 有时有 9 位,有时有 6 位小数?如果我将此字符串提供给函数 unmarshalDateTime(..),则该函数将中断并且无法正常工作。因为它期望 ms 部分为小数点后 3 位。该怎么办

4

4 回答 4

1

您的问题的直接答案在LocalDateTime.toString()(底部的链接)的文档中:

将此日期时间输出为字符串,例如2007-12-03T10:15:30.

输出将是以下 ISO-8601 格式之一:

  • uuuu-MM-dd'T'HH:mm
  • uuuu-MM-dd'T'HH:mm:ss
  • uuuu-MM-dd'T'HH:mm:ss.SSS
  • uuuu-MM-dd'T'HH:mm:ss.SSSSSS
  • uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSS

使用的格式将是最短的输出时间的完整值,其中省略的部分被暗示为零。

要将这样的字符串解析回一个LocalDateTime根本不使用任何格式化程序。one-argLocalDateTime.parse(CharSequence)解析每一种格式。

我来给你展示:

    System.out.println(LocalDateTime.parse("2021-07-13T12:25:38.841775700"));
    System.out.println(LocalDateTime.parse("2021-07-13T12:25:38.841"));
    System.out.println(LocalDateTime.parse("2021-07-13T12:26"));

输出:

2021-07-13T12:25:38.841775700
2021-07-13T12:25:38.841
2021-07-13T12:26

这说 Ali Behzadian Nejad 在他的回答中是正确的:假设这些值应该定义时间点,LocalDateTime对它们来说是错误的类型。使用Instant. 如果可以,请timestamp with time zone在 SQL 端使用。根据您的 JDBC 驱动程序,您可能需要也可能不需要通过OffsetDateTime. 如果您需要存储字符串,Instant.toString()也可以生成不同的格式,并且可以通过 one-arg 解析每一个Instant.parse()

于 2021-07-14T18:27:01.547 回答
1

在数据库中存储本地日期不是一个好主意,因为它们不是时间的瞬间,它们只是时间的本地化表示。

Instant从 LocalTime 及其时区创建一个对象,并将该时间保存Instant在数据库列中,Timestamp类型为:

LocalDateTime localDateTime = ...
Instant instant = localDateTime.atZone(ZoneId.of("Europe/Paris")).toInstant();

来自 Java 文档:

此类 [LocalDateTime] 不存储或表示时区。相反,它是对日期的描述,用于生日,结合挂钟上的当地时间。如果没有诸如偏移或时区之类的附加信息,它就不能代表时间线上的瞬间。

于 2021-07-14T09:30:37.927 回答
0

使用 jdk11:使用的格式将是最短的输出时间的完整值,其中省略的部分被暗示为零。
还有 LocalDate.format 按格式生成时间字符串。

顺便说一句,如果你想节省时间到数据库我建议使用longorTimestamp代替String

于 2021-07-14T09:29:12.060 回答
0

您可以使用DateTimeFormatter考虑不同模式的 a 来解析Strings 具有不同数量的秒(此处:6 或 9):

public static void main(String[] args) throws Exception {
    String datetime = "2021-07-13T12:25:38.841775700";
    String datetimeShort = "2021-07-13T12:25:38.841775";
    // provide a formatter that "knows" two different patterns
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern(
            "[uuuu-MM-dd'T'HH:mm:ss.nnnnnnnnn][uuuu-MM-dd'T'HH:mm:ss.SSSSSS]");
    // parse the one with 9 fractions-of-second
    LocalDateTime ldt = LocalDateTime.parse(datetime, dtf);
    // and the one with 6 using the same formatter
    LocalDateTime ldtShort = LocalDateTime.parse(datetimeShort, dtf);
    // output the parsed LocalDateTimes
    System.out.println(ldt + " and " + ldtShort + " are successfully parsed");
}

这输出

2021-07-13T12:25:38.841775700 and 2021-07-13T12:25:38.841775 are successfully parsed
于 2021-07-14T09:39:10.837 回答