【问题标题】:Convert timestamp to string without formatter在没有格式化程序的情况下将时间戳转换为字符串
【发布时间】:2021-12-14 18:52:12
【问题描述】:

我从 Oracle DB 中得到一个 TIMESTAMP,格式如下:yyyy-MM-dd hh:mm:ss.SSS,并希望转换为像 dd.MM 这样的字符串。年年。我执行了字符串操作,结果按预期正确。这种方法是正确还是错误?还是用作格式化程序更有效? 如果 Oracle 由于 NLS_LANG 设置不同而在将来返回不同的字符串,我是否必须使用格式化程序?

String date = data.toString().substring(0,10).replace("-","."); // data is received from DB 
String day = datum.substring(8,10); 
String month = datum.substring(4,8); 
String year = datum.substring(0,4); 
String myDate = new StringBuilder().append(day).append(month).append(year).toString();

【问题讨论】:

  • “我从 Oracle DB 中获得了这种格式的 TIMESTAMP:” 那么您似乎并没有真正获得 TIMESTAMP,或者您不了解您实际上是什么得到。我这样说是因为 oracle 数据类型 TIMESTAMP 和 DATE don_not_ 具有 any 人类可读的格式。它们是 oracle 的内部二进制格式。当它们从 TO_CHAR 函数返回时,它们只会变成 'yyyy-mm-dd' 或 'dd-mon-yyyy' 或 'ddmmyyyy' 或任何其他人类可读的格式。

标签: java string oracle timestamp formatter


【解决方案1】:

我从 Oracle DB 中得到一个 TIMESTAMP,格式如下:yyyy-MM-dd hh:mm:ss.SSS

通过此语句,您已经进入了字符串处理的世界。您不想去那里的原因之一是时区。

所以实际上通过您的 JDBC 驱动程序,您应该已经收到了 ResultSet。可能您使用了其中一个 getString() 方法并考虑下一步。

或者,您可以使用 getTimestamp() 甚至 getDate(),这将使进一步的转换更容易甚至过时。

【讨论】:

    【解决方案2】:

    java.time

    ANSI SQL 类型与java.time 类型的映射在this Oracle's article 中描述如下:

    ANSI SQL Java SE 8
    DATE LocalDate
    TIME LocalTime
    TIMESTAMP LocalDateTime
    TIME WITH TIMEZONE OffsetTime
    TIMESTAMP WITH TIMEZONE OffsetDateTime

    下面是从columnfoo 检索LocalDateTime 的示例代码:

    Statement st = conn.createStatement();
    ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE <some condition>");
    while (rs.next()) {
        // Assuming the column index of columnfoo is 1
        LocalDateTime ldt = rs.getObject(1, LocalDateTime.class));
        System.out.println(ldt);
    }
    rs.close();
    st.close();
    

    如何格式化LocalDateTime

    您可以使用DateTimeFormatter 格式化LocalDateTime

    演示:

    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Locale;
    
    public class Main {
        public static void main(String[] args) {
            // This is a dummy LocalDateTime for the purpose of demo. You will retrieve
            // LocalDateTime from the DB as shown above
            LocalDateTime ldt = LocalDateTime.now();
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd.MM.uuuu", Locale.ENGLISH);
            String formatted = ldt.format(dtf);
            System.out.println(formatted);
        }
    }
    

    输出:

    29.10.2021
    

    ONLINE DEMO

    通过 Trail: Date Time 了解有关 modern date-time API* 的更多信息。


    * 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring。请注意,Android 8.0 Oreo 已经提供了support for java.time

    【讨论】:

      【解决方案3】:

      我不懂 Java,但是 - 从我的 Oracle 角度来看,正确的方法是使用 to_char 函数:

      SQL> create table test as
        2  select systimestamp ts from dual;
      
      Table created.
      
      SQL> desc test
       Name                                      Null?    Type
       ----------------------------------------- -------- ----------------------------
       TS                                                 TIMESTAMP(6) WITH TIME ZONE
      
      SQL> select * from test;
      
      TS
      ---------------------------------------------------------------------------
      29.10.21 20:26:17,934000 +02:00
      

      这就是我在 Oracle 中的做法:

      SQL> select to_char(ts, 'dd.mm.yyyy') result
        2  from test;
      
      RESULT
      ----------
      29.10.2021
      
      SQL>
      

      如果您不能从 Java 中使用它,自定义函数可以吗?它接受时间戳并返回您想要的格式的字符串;然后你会从 Java 中调用该函数:

      SQL> create or replace function f_format_ts (par_ts in timestamp) return char
        2  is
        3  begin
        4    return to_char(par_ts, 'dd.mm.yyyy');
        5  end;
        6  /
      
      Function created.
      
      SQL> select f_format_ts(a.ts) from test a;
      
      F_FORMAT_TS(A.TS)
      --------------------------------------------------------------------------------
      29.10.2021
      
      SQL>
      

      【讨论】:

        【解决方案4】:

        您似乎没有从数据库中获得TIMESTAMP 值;您正在从数据库中获取一个字符串值(恰好包含日期/时间数据)。当您可以将TIMESTAMP 作为二进制值获取时,请不要这样做,您可以轻松地对其进行格式化。

        如果你想得到一个时间戳,那么retrieve it as a LocalDateTime:

        LocalDateTime datetime = resultSet.getObject(columnIndex, LocalDateTime.class);
        

        您可以使用LocalDateTime.format(formatter) 将其格式化为您想要的任何格式。

        由于您只需要日期组件,因此您甚至可以使用 LocalDate 而不是 LocalDateTime

        【讨论】:

          猜你喜欢
          • 2012-04-19
          • 2020-04-09
          • 2011-12-29
          • 2015-07-02
          • 1970-01-01
          • 2020-09-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多