简体   繁体   English

将 java.sql.Timestamp 转换为即时时间

[英]Converting java.sql.Timestamp to Instant Time

From my database i retrieve value as :从我的数据库中,我检索值如下:

20-DEC-17 10.15.53.000000000 AM

I want above java.sql.Timestamp to be converted to Instant time as :我想将上面的java.sql.Timestamp转换为即时时间为:

2017-12-20T10:15:53Z

I tried following with current time stamp我尝试使用当前时间戳

Timestamp ts2 = new Timestamp(date1.getTime());
Date tradeDate1=new Date(ts2.getTime());
Instant tradeInstant = tradeDate1.toInstant();
System.out.println("Tade Instant"+ tradeInstant);
  • Actual time stamp: Fri Jun 22 16:07:35 IST 2018实际时间戳: Fri Jun 22 16:07:35 IST 2018
  • What is prints in instan : Tade Instant2018-06-22T10:37:35.420Z什么是 instan 打印: Tade Instant2018-06-22T10:37:35.420Z

The hours/mins/seconds are updated which I dont want - is there a way this can be retained as is?更新了我不想要的hours/mins/seconds - 有没有办法保持原样?

I am assuming that you are using at least Java 8 and at least JDBC 4.2.我假设您至少使用 Java 8 和至少 JDBC 4.2。 I am further assuming that the timestamp doesn't have time zone or offset information in the database, but is to be understood as a timestamp in UTC (which is a recommended practice).我进一步假设时间戳在数据库中没有时区或偏移信息,但应理解为 UTC 中的时间戳(这是推荐的做法)。 In this case I would consider it safest to add the information about UTC offset explicitly in Java:在这种情况下,我认为在 Java 中显式添加有关 UTC 偏移量的信息是最安全的:

PreparedStatement yourPreparedStatement 
            = yourConnection.prepareStatement("select trade_timestamp from your_table");
ResultSet rs = yourPreparedStatement.executeQuery();
while (rs.next()) {
    LocalDateTime tradeDateTime = rs.getObject(1, LocalDateTime.class);
    Instant tradeInstant = tradeDateTime.atOffset(ZoneOffset.UTC).toInstant();
    System.out.println("Trade Instant: " + tradeInstant);
}

Note that the code avoids the outdated Timestamp class completely.请注意,代码完全避免了过时的Timestamp类。 A LocalDateTime is a date and time of day without time zone or offset. LocalDateTime是没有时区或偏移量的日期和时间。 If your database datatype had been timestamp with time zone , you could have passed either Instant.class or OffsetDateTime.class to rs.getObject and have got an Instant or an OffsetDateTime back.如果您的数据库数据类型是timestamp with time zone ,您可以将Instant.classOffsetDateTime.class传递给rs.getObject并返回InstantOffsetDateTime JDBC 4.2 only specifies support for OffsetDateTime , but many drivers support Instant too. JDBC 4.2 仅指定支持OffsetDateTime ,但许多驱动程序也支持Instant Obviously with Instant you need no further conversion.显然,使用Instant您无需进一步转换。 With OffsetDateTime doOffsetDateTime

    Instant tradeInstant = tradeDateTime.toInstant();

Depending on your database and its capabilities it is also possible that you can set UTC as offset/time zone on the database session so you can get the correct instant even from timestamp without time zone.根据您的数据库及其功能,您还可以将 UTC 设置为数据库会话上的偏移量/时区,这样即使从没有时区的timestamp也可以获得正确的时刻。

Discussion: Arvind Kumar Avinash in a comment recommends that one should rely only on the types officially supported by JDBC 4.2, that is, LocalDateTime and OffsetDateTime for our purposes.讨论: Arvind Kumar Avinash 在评论中建议我们应该仅依赖 JDBC 4.2 官方支持的类型,即LocalDateTimeOffsetDateTime用于我们的目的。 The types are mentioned at the bottom of the article Why do we need a new date and time library?文章底部提到的类型为什么我们需要一个新的日期和时间库? on Oracle's web site, there's a link at the bottom.在 Oracle 的网站上,底部有一个链接。 Arvind Kumar Avinash further refers us to PSQLException: Can't infer the SQL type to use for an instance of java.time.Instant , also linked to at the bottom. Arvind Kumar Avinash 进一步将我们提到 PSQLException: Can't infer the SQL type to use for an instance of java.time.Instant ,也链接到底部。 Since comments are fragile, I wanted to include the essence here in the answer.由于评论是脆弱的,我想在答案中包含这里的精髓。

What went wrong in your code?你的代码出了什么问题?

It seems your database session understood the timestamp as a date and time in your local time zone (IST, I assume it's for India Standard Time (other interpretations exist)).似乎您的数据库会话将时间戳理解为您当地时区的日期和时间(IST,我假设它是印度标准时间(存在其他解释))。 According to Mark Rotteveel's informative comment this behaviour is required by JDBC, but it doesn't agree with your need when the value is in UTC.根据 Mark Rotteveel 的信息性评论,JDBC 要求此行为,但当值为 UTC 时,它不符合您的需要。 Therefore it gave you the wrong point in time, though it looked right when you printed it.因此,它给了您错误的时间点,尽管您打印时看起来是正确的。 The conversion in itself was correct.转换本身是正确的。

Links链接

Building from the comment about not using SimpleDateFormat, I have moved to DateTimeFormatter:根据关于不使用 SimpleDateFormat 的评论构建,我已移至 DateTimeFormatter:

Date today = new Date();

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss") // same format
        .withLocale(Locale.UK) // UK locale
        .withZone(ZoneId.systemDefault());

String output = dateTimeFormatter.format( today.toInstant() );

System.out.println( output );

Running gives you:跑步给你:

2018-06-22T14:14:26

I have created a SimpleDateFormat, which only prints "up to seconds":我创建了一个 SimpleDateFormat,它只打印“最多秒”:

/* simple date format */   
DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

/* get toInstant() and convert to date */
Date myDate = Date.from(today.toInstant());

/* myDate formatted using DATE_FORMAT */
String formattedDate = DATE_FORMAT.format(myDate);

System.out.println(formattedDate);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM