首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >postgresql日期与java Instant

postgresql日期与java Instant
EN

Stack Overflow用户
提问于 2019-02-21 13:10:51
回答 2查看 3.5K关注 0票数 0

假设我在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

PS。我知道我应该使用Timestamp代替:)

EN

回答 2

Stack Overflow用户

发布于 2019-02-21 18:57:36

tl;dr

  • 与SQL标准兼容的数据库(如Postgres )中的DATE列只存储日期,不存储时间,不存储区域。
  • 只对日期值使用LocalDate,不需要时间和区域.
  • 若要从LocalDate中获取Instant,请指定特定区域(时区)的人使用的挂钟时间,通过该时间确定日期。
  • 如果您想要存储片刻(由Instant对象表示),请使用SQL标准类型TIMESTAMP WITH TIME ZONE而不是DATE

详细信息

Instant在世界协调时

Instant对象表示UTC中的某个时刻,总是以UTC表示。换句话说,一个与世界协调时相抵为零小时-分-秒的时刻。

确定日期需要时区

因此,从Instant获取日期需要一个时区 ( ZoneId)。the 23说,午夜过后的巴黎,法国是一个新的日子,而在魁北克的蒙特雷,它仍然是“昨天”的第22。在任何特定时刻,全球各地的日期因地区而异。

因此,如果您指的是魁北克的日期,请指定“美国/蒙特利尔”时区。

代码语言:javascript
复制
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

您说您的数据库列是DATE类型的。在Postgres中,就像SQL标准一样,这意味着只有日期的值,没有一天的时间,也没有时区。

若要仅存储日期,不需要一天的时间,也不需要时区,请提取LocalDate。“地方”一词是指任何地方或所有地方,但不是任何一个特定的地方。

代码语言:javascript
复制
LocalDate ld = zdt.toLocalDate() ;

JDBC 4.2

通过准备语句中的占位符交换该LocalDate

代码语言:javascript
复制
myPreparedStatement.setObject( … , ld ) ; 

检索:

代码语言:javascript
复制
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;

存储日期,检索日期

当我从数据库读取时,它将如何被重新翻译? 会否: 21.02.2019 00:00:00.000或…

这个问题没有任何意义。当您从符合SQL标准的数据库(如Postgres )中读取DATE时,您将得到一个日期,一个日期--没有日期,也没有时区。

如果将LocalDate of value 2019-02-21存储在DATE列中,则返回相同的值:LocalDate of value 2019-02-21

一天中的第一个时刻

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

代码语言:javascript
复制
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime 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. 

UTC

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

代码语言:javascript
复制
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
LocalDate ld = odt.toLocalDate() ;
myPreparedStatement.setObject( … , ld ) ; 

关于java.time

http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html框架内置到Java8和更高版本中。这些类取代了麻烦的旧遗赠日期时间类,如java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参见http://docs.oracle.com/javase/tutorial/datetime/TOC.html。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310

http://www.joda.org/joda-time/项目现在在维护模式中,建议迁移到java.time类。

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

在哪里获得java.time类?

  • Java 8Java 9Java 10Java 11和更高版本--捆绑实现的标准Java的一部分。
    • Java 9添加了一些次要的特性和修复。

  • Java 6Java 7
    • 大多数java.time功能都是在http://www.threeten.org/threetenbp/中移植到Java6&7中的。

  • 安卓
    • 较晚版本的Android实现的java.time类。
    • 对于早期的Android (<26),https://github.com/JakeWharton/ThreeTenABP项目采用了http://www.threeten.org/threetenbp/ (上面提到的)。见http://stackoverflow.com/q/38922754/642706

三次-额外项目使用其他类扩展java.time。这个项目是将来可能加入java.time的试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter更多

票数 5
EN

Stack Overflow用户

发布于 2019-02-21 14:14:34

那要看你是怎么看的。Instant和SQL DATE不是等价的,而且我不知道任何允许您将DATE读入Instant的可靠库。如果您自己编写的代码允许这样做,那么您可以让它以您想要的任何方式填充小时、分钟、秒和毫秒,即使这没有意义(因此,除非显式地编写代码将java.sql.Date转换为java.time.Instant,否则问题的真正答案将是“两者都没有”)。

如果您正在设计将即时存储为日期的软件,那么您的设计是有缺陷的。要么在Java端使用LocalDate,要么在数据库中使用TIMESTAMP

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54807934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档