This is an automated email from the ASF dual-hosted git repository.

doebele pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/empire-db.git


The following commit(s) were added to refs/heads/master by this push:
     new ca5ffbc8 EMPIREDB-470 Use DateTimeFormatter instead of SimpleDateFormat
     new 4bc57ce7 Merge branch 'master' of 
https://gitbox.apache.org/repos/asf/empire-db
ca5ffbc8 is described below

commit ca5ffbc81995e0304b90f90dcaa40f3686743c24
Author: Rainer Döbele <doeb...@apache.org>
AuthorDate: Thu Jul 10 16:41:09 2025 +0200

    EMPIREDB-470
    Use DateTimeFormatter instead of SimpleDateFormat
---
 .../org/apache/empire/commons/StringUtils.java     | 10 ++++++-
 .../java/org/apache/empire/db/DBSQLBuilder.java    | 32 ++++++++++++----------
 .../java/org/apache/empire/dbms/DBSqlPhrase.java   | 10 ++++---
 .../apache/empire/dbms/derby/DBMSHandlerDerby.java |  6 ++--
 .../org/apache/empire/dbms/h2/DBMSHandlerH2.java   |  4 ---
 .../apache/empire/dbms/hsql/DBMSHandlerHSql.java   |  4 ---
 .../apache/empire/dbms/mysql/DBMSHandlerMySQL.java |  4 ---
 .../empire/dbms/oracle/DBMSHandlerOracle.java      |  4 ---
 .../dbms/postgresql/DBMSHandlerPostgreSQL.java     |  4 ---
 .../empire/dbms/sqlite/DBMSHandlerSQLite.java      |  4 ---
 .../empire/dbms/sqlserver/DBMSHandlerMSSQL.java    |  4 ---
 11 files changed, 35 insertions(+), 51 deletions(-)

diff --git a/empire-db/src/main/java/org/apache/empire/commons/StringUtils.java 
b/empire-db/src/main/java/org/apache/empire/commons/StringUtils.java
index 972f90f0..3abdeec3 100644
--- a/empire-db/src/main/java/org/apache/empire/commons/StringUtils.java
+++ b/empire-db/src/main/java/org/apache/empire/commons/StringUtils.java
@@ -640,9 +640,17 @@ public class StringUtils
     public static String concat(String... parts)
     {
         int totalLength=0;
+        int singleIndex=-1;
         for (int i=0; i<parts.length; i++)
-            if (parts[i]!=null)
+            if (parts[i]!=null && parts[i].length()>0) {
                 totalLength+=parts[i].length();
+                singleIndex=(singleIndex==-1 ? i : -2); 
+            }
+        // optimize
+        if (totalLength==0)
+            return EMPTY;
+        if (singleIndex>=0)
+            return parts[singleIndex];
         // concat now
         StringBuilder b = new StringBuilder(totalLength);
         for (int i=0; i<parts.length; i++)
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java 
b/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
index 192fe1e8..61f4b5bb 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
@@ -19,13 +19,14 @@
 package org.apache.empire.db;
 
 import java.sql.Timestamp;
-import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
 import java.util.Collection;
 import java.util.Date;
 
+import org.apache.empire.commons.DateUtils;
 import org.apache.empire.commons.ObjectUtils;
 import org.apache.empire.commons.StringUtils;
 import org.apache.empire.data.DataType;
@@ -363,33 +364,35 @@ public abstract class DBSQLBuilder implements Appendable
         if (DBDatabase.SYSDATE.equals(value))
             return dbms.getSQLPhrase(sqlCurrentDate);
         // Format the date (ymd)
-        Timestamp ts; 
+        LocalDateTime ts; 
+        int nanos = 0;
         if ((value instanceof Timestamp)) 
-        {   // We have a timestamp
-            ts = (Timestamp)value;
+        {   // Convert Timestamp
+            ts = ((Timestamp)value).toLocalDateTime();
+            nanos = (((Timestamp)value).getNanos() % 1000000);
         }
         else if ((value instanceof Date))
-        {   // Convert Date to Timestamp
-            ts = new Timestamp(((Date)value).getTime());
+        {   // Convert Date
+            ts = DateUtils.toLocalDateTime((Date)value);
         }
         else if ((value instanceof LocalDate))
-        {   // Convert LocalDate to Timestamp
-            ts = java.sql.Timestamp.valueOf(((LocalDate)value).atStartOfDay());
+        {   // Convert LocalDate
+            ts = ((LocalDate)value).atStartOfDay();
         }
         else if ((value instanceof LocalDateTime))
         {   // Convert LocalDateTime to Timestamp
-            ts = java.sql.Timestamp.valueOf((LocalDateTime)value);
+            ts = ((LocalDateTime)value);
         }
         else if ((value instanceof LocalTime))
         {   // Convert LocalTime to Timestamp with current date
-            ts = 
java.sql.Timestamp.valueOf(((LocalTime)value).atDate(LocalDate.now()));
+            ts = ((LocalTime)value).atDate(LocalDate.now());
         }
         else 
         {   // "Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]"
             String dtValue = value.toString().trim();
             try
             {   // parse timestamp
-                ts = Timestamp.valueOf(dtValue);
+                ts = Timestamp.valueOf(dtValue).toLocalDateTime();
             } catch (Throwable e) {
                 // Invalid date
                 log.error("Unable to parse date value "+dtValue, e);
@@ -398,16 +401,17 @@ public abstract class DBSQLBuilder implements Appendable
         }
         // Convert to String
         String pattern = dbms.getSQLPhrase(sqlPattern);
-        SimpleDateFormat sqlFormat = new 
SimpleDateFormat(dbms.getSQLPhrase(sqlPattern));
+        DateTimeFormatter sqlFormat = DateTimeFormatter.ofPattern(pattern);
         String datetime = sqlFormat.format(ts);
         // Add micro / nanoseconds
-        int nanos = (ts.getNanos() % 1000000);
         if (pattern.endsWith(".SSS") && nanos>0)
         {   // Add nanoseconds
             if (((nanos) % 100)>0)
                 datetime += String.format("%06d", nanos);
-            else
+            else if (((nanos) % 1000)>0)
                 datetime += String.format("%04d",(nanos/100));
+            else
+                datetime += String.format("%03d",(nanos/1000));
         }
         // Now Build String
         String template = dbms.getSQLPhrase(sqlTemplate);
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/DBSqlPhrase.java 
b/empire-db/src/main/java/org/apache/empire/dbms/DBSqlPhrase.java
index 879e7fe9..8efc281f 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/DBSqlPhrase.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/DBSqlPhrase.java
@@ -42,17 +42,19 @@ public enum DBSqlPhrase
     SQL_BOOLEAN_TRUE        ("1"),          // Oracle Y
     SQL_BOOLEAN_FALSE       ("0"),          // Oracle N
     SQL_CURRENT_DATE        ("CURRENT_DATE"), 
-    SQL_DATE_PATTERN        ("yyyy-MM-dd"),   // SimpleDateFormat
     SQL_DATE_TEMPLATE       ("TO_DATE('{0}', 'YYYY-MM-DD')"),  // MSSql: 
convert(date, '{0}', 111)
     SQL_CURRENT_TIME        ("CURRENT_TIME"), // MSSql: CONVERT(time, 
getdate());
-    SQL_TIME_PATTERN        ("HH:mm:ss"),     // SimpleDateFormat
     SQL_TIME_TEMPLATE       ("'{0}'"),        // MSSql: convert(time, '{0}')
-    SQL_DATETIME_PATTERN    ("yyyy-MM-dd HH:mm:ss.SSS"), // SimpleDateFormat   
     
     SQL_DATETIME_TEMPLATE   ("TO_DATE('{0}', 'YYYY-MM-DD HH24:MI:SS')"), // 
Oracle
     SQL_CURRENT_TIMESTAMP   ("systimestamp"),                   // Oracle
-    SQL_TIMESTAMP_PATTERN   ("yyyy-MM-dd HH:mm:ss.SSS"),        // 
SimpleDateFormat
     SQL_TIMESTAMP_TEMPLATE  ("TO_TIMESTAMP('{0}', 'YYYY.MM.DD 
HH24:MI:SS.FF')"), // Oracle
 
+    // DateTimeFormatter patterns
+    SQL_DATE_PATTERN        ("yyyy-MM-dd"),   
+    SQL_TIME_PATTERN        ("HH:mm:ss"),
+    SQL_DATETIME_PATTERN    ("yyyy-MM-dd HH:mm:ss"),        
+    SQL_TIMESTAMP_PATTERN   ("yyyy-MM-dd HH:mm:ss.SSS"), // or "yyyy-MM-dd 
HH:mm:ss.SSS " in order to limit to 3 fractions
+    
     // functions
     SQL_FUNC_COALESCE       ("coalesce(?, {0})"),       // Oracle: nvl(?, {0})
     SQL_FUNC_SUBSTRING      ("substring(?, {0:INTEGER})"),
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/derby/DBMSHandlerDerby.java 
b/empire-db/src/main/java/org/apache/empire/dbms/derby/DBMSHandlerDerby.java
index 5d91d41a..43d3d881 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/derby/DBMSHandlerDerby.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/derby/DBMSHandlerDerby.java
@@ -167,16 +167,14 @@ public class DBMSHandlerDerby extends DBMSHandlerBase
             case SQL_BOOLEAN_TRUE:            return "1";
             case SQL_BOOLEAN_FALSE:           return "0";
             case SQL_CURRENT_DATE:            return "CURRENT_DATE";
-            case SQL_DATE_PATTERN:            return "yyyy-MM-dd";
             case SQL_DATE_TEMPLATE:           return "'{0}'";
             case SQL_CURRENT_TIME:            return "CURRENT_TIME";
-            case SQL_TIME_PATTERN:            return "HH:mm:ss";
             case SQL_TIME_TEMPLATE:           return "'{0}'";            
-            case SQL_DATETIME_PATTERN:        return "yyyy-MM-dd HH:mm:ss";
             case SQL_DATETIME_TEMPLATE:       return "'{0}'";
             case SQL_CURRENT_TIMESTAMP:       return "CURRENT_TIMESTAMP";
-            case SQL_TIMESTAMP_PATTERN:       return "yyyy-MM-dd HH:mm:ss";
             case SQL_TIMESTAMP_TEMPLATE:      return "'{0}'";
+            // DateTimeFormatter
+            case SQL_TIMESTAMP_PATTERN:       return "yyyy-MM-dd HH:mm:ss.SSS 
";  // limit to 3 fractions
             // functions
             case SQL_FUNC_COALESCE:           return "coalesce(?, {0})";
             case SQL_FUNC_SUBSTRING:          return "substr(?, {0})";
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java 
b/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java
index 9abafc99..fe20168d 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java
@@ -242,15 +242,11 @@ public class DBMSHandlerH2 extends DBMSHandlerBase
             case SQL_BOOLEAN_TRUE:            return "1";
             case SQL_BOOLEAN_FALSE:           return "0";
             case SQL_CURRENT_DATE:            return "CURRENT_DATE";
-            case SQL_DATE_PATTERN:            return "yyyy-MM-dd";
             case SQL_DATE_TEMPLATE:           return "'{0}'";
             case SQL_CURRENT_TIME:            return "CURRENT_TIME";
-            case SQL_TIME_PATTERN:            return "HH:mm:ss";
             case SQL_TIME_TEMPLATE:           return "'{0}'";
-            case SQL_DATETIME_PATTERN:        return "yyyy-MM-dd HH:mm:ss";
             case SQL_DATETIME_TEMPLATE:       return "'{0}'";
             case SQL_CURRENT_TIMESTAMP:       return "NOW()";
-            case SQL_TIMESTAMP_PATTERN:       return "yyyy-MM-dd HH:mm:ss";
             case SQL_TIMESTAMP_TEMPLATE:      return "'{0}'";
             // functions
             case SQL_FUNC_COALESCE:           return "coalesce(?, {0})";
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBMSHandlerHSql.java 
b/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBMSHandlerHSql.java
index fd3abcc8..3a7fdd15 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBMSHandlerHSql.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBMSHandlerHSql.java
@@ -120,15 +120,11 @@ public class DBMSHandlerHSql extends DBMSHandlerBase
             case SQL_BOOLEAN_TRUE:      return String.valueOf(Boolean.TRUE);
             case SQL_BOOLEAN_FALSE:     return String.valueOf(Boolean.FALSE);
             case SQL_CURRENT_DATE:      return "CURRENT_DATE";
-            case SQL_DATE_PATTERN:      return "yyyy-MM-dd";
             case SQL_DATE_TEMPLATE:     return "TO_DATE('{0}', 'YYYY-MM-DD')";
             case SQL_CURRENT_TIME:      return "CURRENT_TIME";
-            case SQL_TIME_PATTERN:      return "HH:mm:ss";
             case SQL_TIME_TEMPLATE:     return "'{0}'";
-            case SQL_DATETIME_PATTERN:  return "yyyy-MM-dd HH:mm:ss.S";
             case SQL_DATETIME_TEMPLATE: return "TO_DATE('{0}', 'YYYY-MM-DD 
HH24:MI:SS')";
             case SQL_CURRENT_TIMESTAMP: return "CURRENT_TIMESTAMP";
-            case SQL_TIMESTAMP_PATTERN: return "yyyy-MM-dd HH:mm:ss.S";
             case SQL_TIMESTAMP_TEMPLATE:return "TO_TIMESTAMP('{0}', 
'YYYY-MM-DD HH24:MI:SS.FF')";
             // functions
             case SQL_FUNC_COALESCE:     return "coalesce(?, {0})";
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java 
b/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java
index 382bc8ba..a9a92f5a 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java
@@ -452,15 +452,11 @@ public class DBMSHandlerMySQL extends DBMSHandlerBase
             case SQL_BOOLEAN_TRUE:            return "1";
             case SQL_BOOLEAN_FALSE:           return "0";
             case SQL_CURRENT_DATE:            return "CURRENT_DATE()";
-            case SQL_DATE_PATTERN:            return "yyyy-MM-dd";
             case SQL_DATE_TEMPLATE:           return 
"STR_TO_DATE('{0}','%Y-%m-%d')";
             case SQL_CURRENT_TIME:            return "CURRENT_TIME()";
-            case SQL_TIME_PATTERN:            return "HH:mm:ss";
             case SQL_TIME_TEMPLATE:           return 
"STR_TO_DATE('{0}','%H:%i:%s')";
-            case SQL_DATETIME_PATTERN:        return "yyyy-MM-dd HH:mm:ss";
             case SQL_DATETIME_TEMPLATE:       return 
"STR_TO_DATE('{0}','%Y-%m-%d %H:%i:%s')";
             case SQL_CURRENT_TIMESTAMP:       return "CURRENT_TIMESTAMP()";
-            case SQL_TIMESTAMP_PATTERN:       return "yyyy-MM-dd HH:mm:ss.SSS";
             case SQL_TIMESTAMP_TEMPLATE:      return 
"STR_TO_DATE('{0}','%Y-%m-%d %H:%i:%s.%f')";
             // functions
             case SQL_FUNC_COALESCE:           return "coalesce(?, {0})";
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java 
b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java
index 459824fc..56a6a533 100644
--- 
a/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java
+++ 
b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java
@@ -186,15 +186,11 @@ public class DBMSHandlerOracle extends DBMSHandlerBase
             case SQL_BOOLEAN_TRUE:              return 
(booleanType==BooleanType.CHAR) ? "'Y'" : "1";
             case SQL_BOOLEAN_FALSE:             return 
(booleanType==BooleanType.CHAR) ? "'N'" : "0";
             case SQL_CURRENT_DATE:              return "sysdate";
-            case SQL_DATE_PATTERN:              return "YYYY-MM-DD";
             case SQL_DATE_TEMPLATE:             return "TO_DATE('{0}', 
'YYYY-MM-DD')";
-            case SQL_DATETIME_PATTERN:          return "YYYY-MM-DD HH24:MI:SS";
             case SQL_DATETIME_TEMPLATE:         return "TO_DATE('{0}', 
'YYYY-MM-DD HH24:MI:SS')";
             case SQL_CURRENT_TIME:              return 
"TO_DATE('2000-01-01'||TO_CHAR(sysdate, 'HH24:MI:SS'), 'YYYY-MM-DD 
HH24:MI:SS')";
-            case SQL_TIME_PATTERN:              return "HH24:MI:SS";
             case SQL_TIME_TEMPLATE:             return "TO_DATE('2000-01-01 
{0}'), 'YYYY-MM-DD HH24:MI:SS')";
             case SQL_CURRENT_TIMESTAMP:         return "systimestamp";
-            case SQL_TIMESTAMP_PATTERN:         return "YYYY-MM-DD 
HH24:MI:SS.FF";
             case SQL_TIMESTAMP_TEMPLATE:        return "TO_TIMESTAMP('{0}', 
'YYYY-MM-DD HH24:MI:SS.FF')";
             // functions
             case SQL_FUNC_COALESCE:             return "nvl(?, {0})";
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java
 
b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java
index f561cf44..ab6e1e6e 100644
--- 
a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java
+++ 
b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java
@@ -189,15 +189,11 @@ public class DBMSHandlerPostgreSQL extends DBMSHandlerBase
             case SQL_BOOLEAN_TRUE:            return "TRUE";
             case SQL_BOOLEAN_FALSE:           return "FALSE";
             case SQL_CURRENT_DATE:            return "CURRENT_DATE";
-            case SQL_DATE_PATTERN:            return "yyyy-MM-dd";
             case SQL_DATE_TEMPLATE:           return "'{0}'";
             case SQL_CURRENT_TIME:            return "CURRENT_TIME";
-            case SQL_TIME_PATTERN:            return "HH:mm:ss";
             case SQL_TIME_TEMPLATE:           return "'{0}'";
-            case SQL_DATETIME_PATTERN:        return "yyyy-MM-dd HH:mm:ss.SSS";
             case SQL_DATETIME_TEMPLATE:       return "'{0}'";
             case SQL_CURRENT_TIMESTAMP:       return "NOW()";
-            case SQL_TIMESTAMP_PATTERN:       return "yyyy-MM-dd HH:mm:ss.SSS";
             case SQL_TIMESTAMP_TEMPLATE:      return "'{0}'";
             // functions
             case SQL_FUNC_COALESCE:           return "coalesce(?, {0})";
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/sqlite/DBMSHandlerSQLite.java 
b/empire-db/src/main/java/org/apache/empire/dbms/sqlite/DBMSHandlerSQLite.java
index 0772aa57..c2c272ef 100644
--- 
a/empire-db/src/main/java/org/apache/empire/dbms/sqlite/DBMSHandlerSQLite.java
+++ 
b/empire-db/src/main/java/org/apache/empire/dbms/sqlite/DBMSHandlerSQLite.java
@@ -191,14 +191,10 @@ public class DBMSHandlerSQLite extends DBMSHandlerBase
             case SQL_BOOLEAN_TRUE:          return "1";
             case SQL_BOOLEAN_FALSE:         return "0";
             case SQL_CURRENT_DATE:          return "date('now','localtime');";
-            case SQL_DATE_PATTERN:          return "yyyy-MM-dd";
             case SQL_DATE_TEMPLATE:         return "date('{0}')";
             case SQL_CURRENT_TIME:          return "time('now');";
-            case SQL_TIME_TEMPLATE:         return "time('{0}')";
-            case SQL_DATETIME_PATTERN:      return "yyyy-MM-dd hh:mm:ss.sss";
             case SQL_DATETIME_TEMPLATE:     return "'{0}'";
             case SQL_CURRENT_TIMESTAMP:     return "NOW()";
-            case SQL_TIMESTAMP_PATTERN:     return "yyyy-MM-dd hh:mm:ss.sss";
             case SQL_TIMESTAMP_TEMPLATE:    return "'{0}'";
             // functions
             case SQL_FUNC_COALESCE:         return "coalesce(?, {0})";
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java
 
b/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java
index 2c0bcd11..bc835ddf 100644
--- 
a/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java
+++ 
b/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java
@@ -395,16 +395,12 @@ public class DBMSHandlerMSSQL extends DBMSHandlerBase
             case SQL_BOOLEAN_TRUE:            return "1";
             case SQL_BOOLEAN_FALSE:           return "0";
             case SQL_CURRENT_DATE:            return "convert(char, getdate(), 
111)";
-            case SQL_DATE_PATTERN:            return "yyyy-MM-dd";
             case SQL_DATE_TEMPLATE:           return "convert(date, '{0}', 
111)";
             case SQL_CURRENT_TIME:            return "convert(time, 
getdate())";
-            case SQL_TIME_PATTERN:            return "HH:mm:ss";
             case SQL_TIME_TEMPLATE:           return "convert(time, '{0}')";
-            case SQL_DATETIME_PATTERN:        return "yyyy-MM-dd HH:mm:ss.SSS";
             case SQL_DATETIME_TEMPLATE:       return isUseDateTime2() ? 
"convert(datetime2, '{0}', 121)"
                                                                       : 
"convert(datetime,  '{0}', 121)";
             case SQL_CURRENT_TIMESTAMP:       return "getdate()";
-            case SQL_TIMESTAMP_PATTERN:       return "yyyy-MM-dd HH:mm:ss.SSS";
             case SQL_TIMESTAMP_TEMPLATE:      return isUseDateTime2() ? 
"convert(datetime2, '{0}', 121)"
                                                                       : 
"convert(datetime,  '{0}', 121)";
             // functions

Reply via email to