postgresql Date 与 java Instant

Lec*_*chP 1 java postgresql date java.time.instant

假设我在 Java 应用程序中有一个类型为 的字段Instant,并将其作为类型存储在 PostgreSQL 数据库中DATE

例如,如果我保存,21.02.2019 14:03:59它将被存储为21.02.2019,但是当我从数据库读取时,它将如何重新翻译?

那将会:

  • 21.02.2019 00:00:00.000或者
  • 21.02.2019 23:59:59.000

附言。我知道我应该使用Timestamp:)

Bas*_*que 7

太长了;博士

\n\n
    \n
  • 符合 SQL 标准的数据库(例如 Postgres)中的列DATE仅存储日期,没有时间,也没有区域。
  • \n
  • 用于LocalDate仅日期值,没有时间和区域。
  • \n
  • LocalDate要从中获取Instant,请指定您想要确定日期的特定区域(时区)的人们使用的挂钟时间。
  • \n
  • 如果要存储时刻(由Instant对象表示),请使用 SQL 标准类型TIMESTAMP WITH TIME ZONE而不是DATE.
  • \n
\n\n

细节

\n\n

Instant是在 UTC 时间

\n\n

对象代表UTCInstant中的某个时刻,并且始终采用 UTC。换句话说,与UTC 偏移量为零时-分-秒的时刻。

\n\n

确定日期需要时区

\n\n

因此,从 a 获取日期Instant需要时区(a ZoneId)。在法国巴黎,午夜过后的一刻是一个新的日期,比如23 号,而在 Montr\xc3\xa9al Qu\xc3\xa9bec 仍然是 \xe2\x80\x9cyesterday\xe2\x80\x9d 22 号。对于任何特定时刻,全球各地的日期都会因地区而异。

\n\n

因此,如果您指的是 Qu\xc3\xa9bec 中显示的日期,请指定时区“美国/蒙特利尔”。

\n\n
ZoneId z = ZoneId.of( "America/Montreal" ) ;\nZonedDateTime zdt = instant.atZone( z ) ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

你说你的数据库列是类型DATE。在 Postgres 中,与 SQL 标准一样,这意味着仅日期值,没有日期和时区。

\n\n

要仅存储日期,而不存储当天的时间和时区,请提取LocalDate. \xe2\x80\x9clocal\xe2\x80\x9d 一词表示任何位置或所有位置,但不是任何一个特定位置。

\n\n
LocalDate ld = zdt.toLocalDate() ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

数据库连接4.2

\n\n

LocalDate通过准备好的声明中的占位符进行交换。

\n\n
myPreparedStatement.setObject( \xe2\x80\xa6 , ld ) ; \n
Run Code Online (Sandbox Code Playgroud)\n\n

恢复:

\n\n
LocalDate ld = myResultSet.getObject( \xe2\x80\xa6 , LocalDate.class ) ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

存储日期、检索日期

\n\n
\n

当我从数据库读取时,它将如何重新翻译?

\n\n

那将会:

\n\n

21.02.2019 00:00:00.000 或 \xe2\x80\xa6

\n
\n\n

这个问题没有意义。当您从 Postgres 等符合 SQL 标准的数据库读取DATE数据时,您会得到一个日期,只有一个日期 \xe2\x80\x94 ,没有时间,也没有时区。

\n\n

LocalDate如果将 a of value存储2019-02-21在列中DATE,您将得到相同的结果: a LocalDateof value 2019-02-21

\n\n

一天的第一时刻

\n\n

如果您想添加一天中第一时刻的时间,请让java.time为您确定。在某些时区的某些日期,一天的开始时间不是00:00:00,而是可能从 01:00:00 等时间开始。

\n\n
LocalDate ld = myResultSet.getObject( \xe2\x80\xa6 , LocalDate.class ) ;\nZoneId z = ZoneId.of( "Pacific/Auckland" ) ;\nZonedDateTime zdt = ld.atStartOfDay( z ) ;  // Returns a `ZonedDateTime` object set to the first moment of the day as seen on that date in that time zone. May or may not be the time 00:00:00. \n
Run Code Online (Sandbox Code Playgroud)\n\n

世界标准时间

\n\n

如果您想Instant使用 UTC 作为时区提取日期,这意味着与 UTC 的偏移量为零小时-分钟-秒,请使用OffsetDateTime带有常量 的类ZoneOffset.UTC

\n\n
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;\nLocalDate ld = odt.toLocalDate() ;\nmyPreparedStatement.setObject( \xe2\x80\xa6 , ld ) ; \n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

关于java.time

\n\n

java.time框架内置于 Java 8 及更高版本中这些类取代了麻烦的旧遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

\n\n

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

\n\n

Joda -Time项目现在处于维护模式,建议迁移到java.time类。

\n\n

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

\n\n

从哪里获取 java.time 类?

\n\n\n\n

ThreeTen -Extra项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如Interval、、、等等。YearWeekYearQuarter

\n