首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否将java.sql.Timestamp转换为Java8 ZonedDateTime?

是否将java.sql.Timestamp转换为Java8 ZonedDateTime?
EN

Stack Overflow用户
提问于 2018-07-17 02:52:07
回答 3查看 17.1K关注 0票数 19

将Joda时间迁移到Java 8

Joda:

代码语言:javascript
复制
UserObject user = new UserObject()
user.setCreatedAt(new DateTime(rs.getTimestamp("columnName")));`

迁移到Java 8

这是我的代码;它可以编译;我怀疑它是否能工作:

代码语言:javascript
复制
ZonedDateTime.ofInstant(rs.getTimestamp("columnName").toLocalDateTime().toInstant(ZoneOffset.UTC),ZoneId.of("UTC")));

在某些情况下,日期是错误的。有什么建议吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-07-18 19:35:07

这似乎是可行的:

代码语言:javascript
复制
ZonedDateTime.ofInstant(rs.getTimestamp("columnname").toInstant(), ZoneId.of("UTC"))
票数 11
EN

Stack Overflow用户

发布于 2018-07-17 05:28:17

tl;dr

要跟踪历史中的某个时刻,请使用Instant作为类成员变量的类型。具体地说,在UTC中,这一时刻被视为日期和时间。

代码语言:javascript
复制
public class UserObject() {
    Instant createdAt ;
    …
    public void setCreatedAt( Instant instantArg ) {
        this.createdAt = instantArg ;
    {
}

使用,捕获当前时刻。

代码语言:javascript
复制
UserObject user = new UserObject() ;
user.setCreatedAt( Instant.now() ) ;

用法,正在从数据库填充值。

代码语言:javascript
复制
UserObject user = new UserObject() ;
Instant instant = myResultSet.getObject( "when_created" , Instant.class ) ;
user.setCreatedAt( instant ) ;

JDBC 4.2不需要对Instant的支持(以协调世界时为单位)。如果您的驱动程序不支持该类,请切换到所需的OffsetDateTime

代码语言:javascript
复制
UserObject user = new UserObject() ;
OffsetDateTime odt = myResultSet.getObject( "when_created" , OffsetDateTime.class ) ;  
user.setCreatedAt( odt.toInstant() ) ;  // Convert from an `OffsetDateTime` (for any offset-from-UTC) to `Instant` (always in UTC). 

呈现给用户,为用户界面本地化。

代码语言:javascript
复制
user               // Your business object.
.getCreatedAt()    // Returns a `Instant` object.
.atZone(           // Adjust from UTC to a time zone. Same moment, same point on the timeline, different wall-clock time.
    ZoneId.of( "Pacific/Auckland" )  // Specify the user’s desired/expected time zone.
)                  // Returns a `ZonedDateTime` object. 
.format(           // Generate a `String` representing the value of date-time object.
    DateTimeFormatter.ofLocalizedDateTime(
        FormatStyle.FULL   // Specify how long or abbreviated the string.
    )
    .withLocale(   // Specify `Locale` to determine human language and cultural norms for localization.
        Locale.CANADA_FRENCH 
    )
)                  // Returns a `String`.

请注意,Locale与时区无关,这是一个正交问题。上面的代码可能是为在New Zealand旅行的Québec商务人员编写的。她想看到周围的kiwis使用的挂钟时间,但她更喜欢用她的母语法语阅读它的文本显示。时区和区域设置都是最好留给演示文稿的问题;通常情况下,最好在代码的其余部分使用UTC。因此,我们将成员变量createdAt定义为Instant,根据定义,Instant始终在UTC中。

避免java.sql.Timestamp

正如该项目网站的首页所述,

  • java.sql.Timestamp以及java.sql.Datejava.util.DateCalendar都是非常麻烦的旧date-time类的一部分,这些date-time类在几年前也被java.time date-time取代,现在被java.time类取代。

java.time

JDBC 4.2和更高版本中,我们可以直接与数据库交换java.time对象。

Instant

使用Instant类将当前时刻发送到数据库。Instant类表示UTC中时间轴上的一个时刻,分辨率为nanoseconds (最多九(9)位小数)。

代码语言:javascript
复制
Instant instant = Instant.now() ;  // Capture the current moment in UTC.
myPreparedStatement.setObject( … , instant ) ;

和检索。

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

ZonedDateTime

要通过特定地区(时区)的人使用的挂钟时间的镜头来查看相同的时刻,请应用ZoneId来获取ZonedDateTime

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

LocalDateTime不是一个时刻

.toLocalDateTime()。

在表示特定时刻时,从不涉及 LocalDateTime类。这个类故意缺少任何时区或UTC偏移量的概念。因此,它不能代表一个时刻,不是时间线上的一个点。这是一个关于大约26-27小时范围(时区范围)的潜在时刻的模糊概念。

关于java.time

框架内置于Java8和更高版本中。这些类取代了麻烦的旧legacy日期时间类,如java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参阅。和搜索堆栈溢出,以获得许多示例和解释。规范为JSR 310

现在在maintenance mode中的项目建议迁移到java.time类。

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

从哪里获取java.time类?

  • ,、、和更高版本-标准Java API的一部分,具有捆绑的实现。
    • 带来了一些次要的特性和fixes.

  • 和.

中的

  • 大多数java.time功能已向后移植到Java6和7

    • 更高版本的Android (26+)捆绑了java.time类的实现。
    • 对于早期的Android (<26),一个称为的过程带来了一个subset of the 功能,这个功能最初并没有内置到Android中。
      • 如果去糖化没有提供你需要的东西,项目会让 (上面提到的)适应安卓系统。请参阅.
票数 28
EN

Stack Overflow用户

发布于 2018-07-17 03:07:53

使用以下内容:

代码语言:javascript
复制
rs.getTimestamp("columnName").toInstant()
    .atZone(ZoneId.[appropriate-zone-ID-here])

您需要使用适合该区域的ZoneId (您可以尝试使用ZoneId.systemDefault()作为开始)。

有关各种Java-Time API之间差异的更多详细信息,请参阅this great answer

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

https://stackoverflow.com/questions/51368395

复制
相关文章

相似问题

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