简体   繁体   English

将 java.sql.Timestamp 与 DB2 Timestamp 匹配

[英]Match java.sql.Timestamp with DB2 Timestamp

I need to pass Timestamp value as parameter in URL to retrieve some data.我需要将时间戳值作为 URL 中的参数传递来检索一些数据。 Format of Timestamp in DB2 is: 2022-05-25-11:10:44.662000, but in java.sql.Timestamp is: 2022-05-25 11:10:44.0 and when I pass it, it returns empty list. DB2 中时间戳的格式为:2022-05-25-11:10:44.662000,但在 java.sql.Timestamp 中为:2022-05-25 11:10:44.0,当我通过它时,它返回空列表。

My ActionController class method:我的 ActionController 类方法:

@GetMapping(value = "/fetchData/{id}/{timestamp}")
  def fetchData(@PathVariable int id, @PathVariable Timestamp timestamp) {
    def serviceResult = actionService.fetchData(id, timestamp);
    return parseServiceResult(serviceResult)
  }

My ActionService class method:我的 ActionService 类方法:

  ServiceResult fetchData(int id, Timestamp timestamp) {
    ServiceResult ret = new ServiceResult()
    List<DataDTO> retSet = new ArrayList<DataDTO>()
    List<String> errorMessage = new ArrayList<String>()
    try {
      retSet = actionEntity.fetchData(id, timestamp)
    } catch (CollectionsException e) {
      errorMessage << "ActionService.fetchData error"
      log.debug("ActionService.fetchData error" + e.getMessage())
    }
    ret = new ServiceResult(success: errorMessage.isEmpty(), result: retSet, errorMessageTextList: errorMessage)

    ret
  }

My ActionEntity class method:我的 ActionEntity 类方法:

ArrayList<DataDTO> fetchPoulsFromStorno(int id, Timestamp timestamp) throws CollectionsException {

    def sql = """SELECT * FROM NSNP.TABLE1 PT INNER JOIN NSNP.TABLE2 ST
                        ON (ST.COLUMN1 = PT.COLUMN1 AND
                        ST.COLUMN2 = PT.COLUMN2 AND
                        ST.COLUMN3 = PT.COLUMN3 AND
                        ST.COLUMN4 = PT.COLUMN4 AND
                        ST.COLUMN5 = PT.COLUMN5 AND
                        ST.COLUMN6 = PT.COLUMN6 AND
                        ST.COLUMN7 = PT.COLUMN7 AND
                        ST.COLUMN8 = PT.COLUMN8 )
                        WHERE ST.ID = $id AND ST.TIMESTAMP= $timestamp"""


    ArrayList<DataDTO> dataList = new ArrayList<DataDTO>()

    try {
      if (this.sql != null) {
        this.sql.eachRow(sql) {
          resultSet ->
            System.out.println(resultSet)
            DataDTO dataDTO = new DataDTO()
            dataDTO .setProperty1(resultSet.COLUMN1)
            dataDTO .setPropety2(resultSet.COLUMN2)
            dataDTO .setProperty3(resultSet.COLUMN3)
            
            dataList.add(dataDTO)
        }
      }
    } catch (SQLException se) {
      log.info "ActionEntity.fetchData error $se.message  executed sql: $sql"
    } finally {
      if (this.sql != null) {
        this.sql.close()
      }
    }
    dataList
  }

Can't provide you exact and real data, but I'm sure you'll understand code and what I'm trying to do.无法为您提供准确和真实的数据,但我相信您会理解代码和我正在尝试做的事情。

tl;dr tl;博士

You are using the wrong types.您使用了错误的类型。

  • To exchange data with a DB2 column of type TIMESTAMP WITHOUT TIME ZONE , use java.time.LocalDateTime .要与类型为TIMESTAMP WITHOUT TIME ZONE的 DB2 列交换数据,请使用java.time.LocalDateTime
  • To exchange data with a DB2 column of type TIMESTAMP WITH TIME ZONE , use java.time.OffsetDateTime .要与TIMESTAMP WITH TIME ZONE类型的 DB2 列交换数据,请使用java.time.OffsetDateTime

Never use the flawed legacy class java.sql.Timestamp .永远不要使用有缺陷的遗留类java.sql.Timestamp

👉 Your hour difference is likely resulting from that class adjusting for time zone, which is problematic because the TIMESTAMP column ( TIMESTAMP WITHOUT TIME ZONE column) in DB2 has no time zone or offset. 👉 您的小时差异可能是由于该类针对时区进行了调整,这是有问题的,因为 DB2 中的TIMESTAMP列( TIMESTAMP WITHOUT TIME ZONE列)没有时区或偏移量。

Details细节

Format of Timestamp in DB2 is: 2022-05-25-11:10:44.662000 DB2中时间戳的格式为:2022-05-25-11:10:44.662000

No, a TIMESTAMP type in DB2 does not have a format.不,DB2 中的TIMESTAMP类型没有格式。 That type does not contain text.该类型不包含文本。 That type uses its own internally-defined data for tracking a date-time value.该类型使用自己内部定义的数据来跟踪日期时间值。

The matching type in Java for a DB2 column of type TIMESTAMP WITHOUT TIME ZONE is java.time.LocalDateTime . Java 中类型为TIMESTAMP WITHOUT TIME ZONE的 DB2 列的匹配类型是java.time.LocalDateTime

but in java.sql.Timestamp但在 java.sql.Timestamp

Never use the Timestamp class.永远不要使用Timestamp类。 That class is part of the legacy date-time classes that were tragically flawed in their design.该类是遗留日期时间类的一部分,它们的设计存在可悲的缺陷。 They were years ago supplanted by the modern java.time classes defined in JSR 310. The Timestamp class was specifically replaced by java.time.Instant , though for interacting with a database you would use OffsetDateTime class.它们在几年前被 JSR 310 中定义的现代java.time类所取代。 Timestamp类被专门替换为java.time.Instant ,但要与数据库交互,您将使用OffsetDateTime类。

JDBC 4.2 and later requires all JDBC drivers to support an appropriate subset of the java.time classes. JDBC 4.2 及更高版本要求所有 JDBC 驱动程序支持适当的java.time类子集。

Moment versus not-a-moment片刻与非片刻

Another issue is that TIMESTAMP in DB2 (short for TIMESTAMP WITHOUT TIME ZONE ) purposely lacks the context of an offset-from-UTC or time zone.另一个问题是 DB2 中的TIMESTAMPTIMESTAMP WITHOUT TIME ZONE的缩写)故意缺少与 UTC 或时区偏移的上下文。 Without an offset or zone, that type cannot be used to represent a moment, a specific point on the timeline.如果没有偏移或区域,则该类型不能用于表示时刻、时间轴上的特定点。

In contrast, the java.sql.Timestamp class does represent a moment, a specific point on the timeline.相比之下, java.sql.Timestamp确实代表了一个时刻,即时间线上的一个特定点。

So TIMESTAMP in DB2 does not match up to java.sql.Timestamp .所以 DB2 中的TIMESTAMPjava.sql.Timestamp不匹配。

👉 Instead, for exchanging values with a TIMESTAMP column in DB2, use the java.time.LocalDateTime class. 👉 相反,要与 DB2 中的TIMESTAMP列交换值,请使用java.time.LocalDateTime类。 Like the DB2 type, that class purposely lacks the context of an offset or zone.与 DB2 类型一样,该类故意缺少偏移或区域的上下文。

LocalDateTime ldt = LocalDateTime.parse( "2022-05-25T11:10:44.662000" ) ;

See this code run live at Ideone.com .请参阅在 Ideone.com 上实时运行的代码

ldt.toString() is 2022-05-25T11:10:44.662 ldt.toString() 是 2022-05-25T11:10:44.662

Writing.写作。

myPreparedStatement.setObject( … , ldt ) ;

Retrieval.恢复。

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;

Resolution解析度

The TIMESTAMP type in DB2 resolves to the very FINE resolution of picoseconds. DB2 中的TIMESTAMP类型解析为非常精细的皮秒分辨率。 To quote the manual:引用手册:

The number of digits in the fractional seconds portion is specified using an attribute in the range 0 - 12 with a default of 6使用 0 - 12 范围内的属性指定小数秒部分中的位数,默认值为 6

A nanosecond , a billionth of a second, is a fractional second of nine digits.纳秒,十亿分之一秒,是九位数的小数秒。 Twelve digits represent a picosecond , a trillionth of a second.十二位数字代表一皮秒,即万亿分之一秒。

The java.time classes have a resolution of nanoseconds. java.time类的分辨率为纳秒。

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

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