Java 将oracle.sql.TIMESTAMPTZ转换为字符串值时出现问题

Java 将oracle.sql.TIMESTAMPTZ转换为字符串值时出现问题,java,json,oracle,timestamp-with-timezone,Java,Json,Oracle,Timestamp With Timezone,我尝试从oracledb获取一些数据,将这些数据放在json中并在其他地方使用,但在转换timestamptz时遇到了问题。Oracle以字符串格式为我提供带时区的时间戳,如“23.10.14 18:34:16000000亚洲/新西伯利亚”。这里是我的一些代码 public void loadFromDb(ResultSet resultSet, Connection oc) throws SQLException { ResultSetMetaData metaData = resul

我尝试从oracledb获取一些数据,将这些数据放在json中并在其他地方使用,但在转换timestamptz时遇到了问题。Oracle以字符串格式为我提供带时区的时间戳,如“23.10.14 18:34:16000000亚洲/新西伯利亚”。这里是我的一些代码

public void loadFromDb(ResultSet resultSet, Connection oc) throws SQLException {
    ResultSetMetaData metaData = resultSet.getMetaData();
    int columnCount = metaData.getColumnCount();
    for (int i = 1; i <= columnCount; i++) {
        Object obj = resultSet.getObject(i);
        if (obj == null)
            continue;
        if (obj instanceof TIMESTAMPTZ) {
            TIMESTAMPTZ ts = (TIMESTAMPTZ) obj;
            if (oc != null) {
                super.setValue(metaData.getColumnName(i), ts.stringValue(oc));
            } else {
                super.setValue(metaData.getColumnName(i), ts.stringValue());
            }
    }
}
顺便说一句,之前我得到的时区是数字格式的,比如'XX:XX',这段代码不太管用,但可以使用这个神奇的
super.setValue(metaData.getColumnName(i),ts.stringValue(null))
现在这样就可以使用nullpointerexception了。
请帮助我,因为我尝试了在javadocs中找到的所有内容。

时间戳
不是字符串,反之亦然。您需要使用
to_CHAR
和所需格式将其转换为字符串

SQL> SELECT SYSTIMESTAMP
  2  FROM   dual
  3  /

SYSTIMESTAMP
---------------------------------------------------------------------------
24-OCT-14 11.14.55.116000 AM +05:30

SQL>
SQL> SELECT TO_CHAR(systimestamp, 'DD-MON-YYYY HH24:MI:SS.FF TZH:TZM') tm
  2  FROM dual
  3  /

TM
-------------------------------------
24-OCT-2014 11:14:55.163000 +05:30

SQL> SELECT to_timestamp_tz('24-OCT-2014 11:07:40.348000 +05:30','DD-MON-YYYY HH24:MI:SS.FF TZH:TZM') tm
  2  FROM dual
  3  /

TM
---------------------------------------------------------------------------
24-OCT-14 11.07.40.348000000 AM +05:30

SQL> SELECT TO_TIMESTAMP('24-OCT-2014', 'DD-MON-YYYY')
  2  FROM dual
  3  /

TO_TIMESTAMP('24-OCT-2014','DD-MON-YYYY')
---------------------------------------------------------------------------
24-OCT-14 12.00.00.000000000 AM
让我们验证一下

SQL> set serveroutput on;
SQL> DECLARE
  2    tm_stamp  TIMESTAMP;
  3    tm_string VARCHAR2(30);
  4  BEGIN
  5    SELECT SYSTIMESTAMP INTO tm_stamp FROM dual;
  6    dbms_output.put_line(tm_stamp);
  7    SELECT SYSTIMESTAMP INTO tm_string FROM dual;
  8    dbms_output.put_line(tm_string);
  9  END;
 10  /
24-OCT-14 11.17.35.180000 AM
DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 7


SQL>
因此,tm_字符串不能存储时间戳,因为tm_stamp是字符串类型而不是时间戳

正确的方法是显式地将其转换为字符串

SQL> DECLARE
  2    tm_stamp  TIMESTAMP;
  3    tm_string VARCHAR2(50);
  4  BEGIN
  5    SELECT TO_CHAR(systimestamp, 'DD-MON-YYYY HH24:MI:SS.FF TZH:TZM') INTO tm_string FROM dual;
  6    dbms_output.put_line(tm_string);
  7  END;
  8  /
24-OCT-2014 11:25:20.060000 +05:30

PL/SQL procedure successfully completed.

SQL>

TIMESTAMPTZ
的格式为。我们目前使用


如果您使用的是JavaSE8和ojdbc8,那么可以使用
getObject(int,OffsetDateTime.class)
。如果您使用
getObject(int,ZonedDateTime.class)
您可能会受到影响。

您的jdbc驱动程序可能存在一些问题+您读过这篇文章吗?我认为解决这个问题最简单的方法是检索带有时区的时间戳的字符串表示形式(如果您的情况可能的话)@Multisync可能我不理解您的意思,但这是我的问题-获取带有时区的时间戳的字符串表示形式我的意思是选择字符(col_timestamp_带有时区,'format')。。。你需要哪种格式?@Multisync我在数据库端什么都做不了。我只调用返回一些结果集的过程。感谢您的链接,我认为#4(write own toString())是解决我的情况的一种可能的方法……谢谢,但是我限制了java的资源,因为我不能在db端做任何事情。我只调用返回一些结果集的过程。
SQL> DECLARE
  2    tm_stamp  TIMESTAMP;
  3    tm_string VARCHAR2(50);
  4  BEGIN
  5    SELECT TO_CHAR(systimestamp, 'DD-MON-YYYY HH24:MI:SS.FF TZH:TZM') INTO tm_string FROM dual;
  6    dbms_output.put_line(tm_string);
  7  END;
  8  /
24-OCT-2014 11:25:20.060000 +05:30

PL/SQL procedure successfully completed.

SQL>