From fdc3fcd3e2ff133f187186a49cf9c4f22bfe74db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20Prante?= <joergprante@gmail.com>
Date: Tue, 18 Mar 2025 21:07:25 +0100
Subject: [PATCH] add java.time.LocalTime

---
 .../org/xbib/jdbc/query/DatabaseImpl.java     |   4 +
 .../main/java/org/xbib/jdbc/query/Row.java    |  38 ++----
 .../java/org/xbib/jdbc/query/RowsAdapter.java |  82 +++++++++----
 .../java/org/xbib/jdbc/query/SqlArgs.java     | 116 +++++++++++++++---
 .../java/org/xbib/jdbc/query/SqlInsert.java   |  13 +-
 .../org/xbib/jdbc/query/SqlInsertImpl.java    |  17 ++-
 .../java/org/xbib/jdbc/query/SqlSelect.java   |  13 +-
 .../org/xbib/jdbc/query/SqlSelectImpl.java    |  11 ++
 .../java/org/xbib/jdbc/query/SqlUpdate.java   |  19 +--
 .../org/xbib/jdbc/query/SqlUpdateImpl.java    |  15 ++-
 .../org/xbib/jdbc/query/StatementAdapter.java |   5 +
 11 files changed, 242 insertions(+), 91 deletions(-)

diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/DatabaseImpl.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/DatabaseImpl.java
index 8f25bf4..f388bd8 100644
--- a/jdbc-query/src/main/java/org/xbib/jdbc/query/DatabaseImpl.java
+++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/DatabaseImpl.java
@@ -12,6 +12,7 @@ import java.sql.Timestamp;
 import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -497,6 +498,7 @@ public class DatabaseImpl implements Database {
                 case Long l -> sql.argLong(k, l);
                 case Boolean b -> sql.argBoolean(k, b);
                 case LocalDate localDate -> sql.argLocalDate(k, localDate);
+                case LocalTime localTime -> sql.argLocalTime(k, localTime);
                 case LocalDateTime localDateTime -> sql.argLocalDateTime(k, localDateTime);
                 case OffsetDateTime offsetDateTime -> sql.argOffsetDateTime(k, offsetDateTime);
                 case null -> sql.argNull(k);
@@ -517,6 +519,7 @@ public class DatabaseImpl implements Database {
                 case Long l -> sql.argLong(k, l);
                 case Boolean b -> sql.argBoolean(k, b);
                 case LocalDate localDate -> sql.argLocalDate(k, localDate);
+                case LocalTime localTime -> sql.argLocalTime(k, localTime);
                 case LocalDateTime localDateTime -> sql.argLocalDateTime(k, localDateTime);
                 case OffsetDateTime offsetDateTime -> sql.argOffsetDateTime(k, offsetDateTime);
                 case null -> sql.argNull(k);
@@ -542,6 +545,7 @@ public class DatabaseImpl implements Database {
                     case "java.lang.Boolean" -> row.add(rows.getBooleanOrFalse(i + 1));
                     case "java.sql.Clob", "oracle.jdbc.OracleClob" -> row.add(rows.getClobStringOrEmpty(i + 1));
                     case "java.sql.Date" -> row.add(rows.getLocalDateOrNull(i + 1));
+                    case "java.sql.Time" -> row.add(rows.getLocalTimeOrNull(i + 1));
                     case "oracle.sql.TIMESTAMPTZ" -> row.add(rows.getOffsetDateTimeOrNull(i + 1));
                     case "java.sql.Timestamp", "oracle.sql.TIMESTAMP" -> row.add(rows.getLocalDateTimeOrNull(i + 1));
                     case "java.math.BigDecimal" -> row.add(rows.getBigDecimalOrNull(i + 1));
diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/Row.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/Row.java
index 9d75ac9..85a1d88 100644
--- a/jdbc-query/src/main/java/org/xbib/jdbc/query/Row.java
+++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/Row.java
@@ -6,6 +6,7 @@ import java.math.BigDecimal;
 import java.sql.ResultSetMetaData;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.OffsetDateTime;
 
 /**
@@ -355,6 +356,18 @@ public interface Row {
    
     InputStream getBlobInputStreamOrEmpty(String columnName);
 
+    LocalDate getLocalDateOrNull();
+
+    LocalDate getLocalDateOrNull(int columnOneBased);
+
+    LocalDate getLocalDateOrNull(String columnName);
+
+    LocalTime getLocalTimeOrNull();
+
+    LocalTime getLocalTimeOrNull(int columnOneBased);
+
+    LocalTime getLocalTimeOrNull(String columnName);
+
     LocalDateTime getLocalDateTimeOrNull();
 
     LocalDateTime getLocalDateTimeOrNull(int columnOneBased);
@@ -366,29 +379,4 @@ public interface Row {
     OffsetDateTime getOffsetDateTimeOrNull(int columnOneBase);
 
     OffsetDateTime getOffsetDateTimeOrNull(String columnName);
-
-    /**
-     * Retrieve column as LocalDate, .i.e, date with no time.
-     *
-     * @return LocalDate of the database column value
-     */
-    LocalDate getLocalDateOrNull();
-
-    /**
-     * Get the Date field, with no timestamp
-     *
-     * @param columnOneBased column number starting at 1, not 0
-     * @return LocalDate of the column value
-     */
-    
-    LocalDate getLocalDateOrNull(int columnOneBased);
-
-    /**
-     * Get the Date field, with no timestamp
-     *
-     * @param columnName column name to retrieve
-     * @return LocalDate of the column value
-     */
-    
-    LocalDate getLocalDateOrNull(String columnName);
 }
diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/RowsAdapter.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/RowsAdapter.java
index 8bb4484..df698a4 100644
--- a/jdbc-query/src/main/java/org/xbib/jdbc/query/RowsAdapter.java
+++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/RowsAdapter.java
@@ -11,6 +11,7 @@ import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.OffsetDateTime;
 
 /**
@@ -654,6 +655,60 @@ class RowsAdapter implements Rows {
         return result;
     }
 
+    @Override
+    public LocalDate getLocalDateOrNull() {
+        return getLocalDateOrNull(column++);
+    }
+
+    @Override
+    public LocalDate getLocalDateOrNull(int columnOneBased) {
+        try {
+            column = columnOneBased + 1;
+            java.sql.Date val = rs.getDate(columnOneBased);
+            return val == null ? null : val.toLocalDate();
+        } catch (SQLException e) {
+            throw new DatabaseException(e);
+        }
+    }
+
+    @Override
+    public LocalDate getLocalDateOrNull(String columnName) {
+        try {
+            column = rs.findColumn(columnName) + 1;
+            java.sql.Date val = rs.getDate(columnName);
+            return val == null ? null : val.toLocalDate();
+        } catch (SQLException e) {
+            throw new DatabaseException(e);
+        }
+    }
+
+    @Override
+    public LocalTime getLocalTimeOrNull() {
+        return getLocalTimeOrNull(column++);
+    }
+
+    @Override
+    public LocalTime getLocalTimeOrNull(int columnOneBased) {
+        try {
+            column = columnOneBased + 1;
+            java.sql.Time val = rs.getTime(columnOneBased);
+            return val == null ? null : val.toLocalTime();
+        } catch (SQLException e) {
+            throw new DatabaseException(e);
+        }
+    }
+
+    @Override
+    public LocalTime getLocalTimeOrNull(String columnName) {
+        try {
+            column = rs.findColumn(columnName) + 1;
+            java.sql.Time val = rs.getTime(columnName);
+            return val == null ? null : val.toLocalTime();
+        } catch (SQLException e) {
+            throw new DatabaseException(e);
+        }
+    }
+
     @Override
     public LocalDateTime getLocalDateTimeOrNull() {
         return getLocalDateTimeOrNull(column++);
@@ -679,33 +734,6 @@ class RowsAdapter implements Rows {
         }
     }
 
-    @Override
-    public LocalDate getLocalDateOrNull() {
-        return getLocalDateOrNull(column++);
-    }
-    
-    @Override
-    public LocalDate getLocalDateOrNull(int columnOneBased) {
-        try {
-            column = columnOneBased + 1;
-            java.sql.Date val = rs.getDate(columnOneBased);
-            return val == null ? null : val.toLocalDate();
-        } catch (SQLException e) {
-            throw new DatabaseException(e);
-        }
-    }
-    
-    @Override
-    public LocalDate getLocalDateOrNull(String columnName) {
-        try {
-            column = rs.findColumn(columnName) + 1;
-            java.sql.Date val = rs.getDate(columnName);
-            return val == null ? null : val.toLocalDate();
-        } catch (SQLException e) {
-            throw new DatabaseException(e);
-        }
-    }
-
     @Override
     public OffsetDateTime getOffsetDateTimeOrNull() {
         return getOffsetDateTimeOrNull(column++);
diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlArgs.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlArgs.java
index 021ae4b..99c52c9 100644
--- a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlArgs.java
+++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlArgs.java
@@ -8,6 +8,8 @@ import java.sql.SQLException;
 import java.sql.Types;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -133,7 +135,28 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
         invocations.add(new Invocation(ColumnType.String, argName, arg));
         return this;
     }
-    
+
+
+    public SqlArgs argLocalDate(LocalDate arg) {
+        invocations.add(new Invocation(ColumnType.LocalDate, null, arg));
+        return this;
+    }
+
+    public SqlArgs argLocalDate(String argName, LocalDate arg) {
+        invocations.add(new Invocation(ColumnType.LocalDate, argName, arg));
+        return this;
+    }
+
+    public SqlArgs argLocalTime(LocalTime arg) {
+        invocations.add(new Invocation(ColumnType.LocalTime, null, arg));
+        return this;
+    }
+
+    public SqlArgs argLocalTime(String argName, LocalTime arg) {
+        invocations.add(new Invocation(ColumnType.LocalTime, argName, arg));
+        return this;
+    }
+
     public SqlArgs argLocalDateTime(LocalDateTime arg) {
         invocations.add(new Invocation(ColumnType.LocalDateTime, null, arg));
         return this;
@@ -143,14 +166,14 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
         invocations.add(new Invocation(ColumnType.LocalDateTime, argName, arg));
         return this;
     }
-    
-    public SqlArgs argLocalDate(LocalDate arg) {
-        invocations.add(new Invocation(ColumnType.LocalDate, null, arg));
+
+    public SqlArgs argOffsetDateTime(OffsetDateTime arg) {
+        invocations.add(new Invocation(ColumnType.OffsetDateTime, null, arg));
         return this;
     }
-    
-    public SqlArgs argLocalDate(String argName, LocalDate arg) {
-        invocations.add(new Invocation(ColumnType.LocalDate, argName, arg));
+
+    public SqlArgs argOffsetDateTime(String argName, OffsetDateTime arg) {
+        invocations.add(new Invocation(ColumnType.OffsetDateTime, argName, arg));
         return this;
     }
 
@@ -163,7 +186,17 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
         invocations.add(new Invocation(ColumnType.LocalDateTimeNowPerDb, argName, null));
         return this;
     }
-    
+
+    public SqlArgs argOffsetDateTimeNowPerDb() {
+        invocations.add(new Invocation(ColumnType.OffsetDateTimeNowPerDb, null, null));
+        return this;
+    }
+
+    public SqlArgs argOffsetDateTimeNowPerDb(String argName) {
+        invocations.add(new Invocation(ColumnType.OffsetDateTimeNowPerDb, argName, null));
+        return this;
+    }
+
     public SqlArgs argBlobBytes(byte[] arg) {
         invocations.add(new Invocation(ColumnType.BlobBytes, null, arg));
         return this;
@@ -283,12 +316,6 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
                     }
                     break;
                 case String:
-                    if (i.argName == null) {
-                        select.argString((String) i.arg);
-                    } else {
-                        select.argString(i.argName, (String) i.arg);
-                    }
-                    break;
                 case ClobString:
                     if (i.argName == null) {
                         select.argString((String) i.arg);
@@ -299,7 +326,6 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
                 case ClobStream:
                     throw new DatabaseException("Don't use Clob stream parameters with select statements");
                 case BlobBytes:
-                    throw new DatabaseException("Don't use Blob parameters with select statements");
                 case BlobStream:
                     throw new DatabaseException("Don't use Blob parameters with select statements");
                 case LocalDate:
@@ -309,6 +335,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
                         select.argLocalDate(i.argName, (LocalDate) i.arg);
                     }
                     break;
+                case LocalTime:
+                    if (i.argName == null) {
+                        select.argLocalTime((LocalTime) i.arg);
+                    } else {
+                        select.argLocalTime(i.argName, (LocalTime) i.arg);
+                    }
+                    break;
                 case LocalDateTime:
                     if (i.argName == null) {
                         select.argLocalDateTime((LocalDateTime) i.arg);
@@ -316,6 +349,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
                         select.argLocalDateTime(i.argName, (LocalDateTime) i.arg);
                     }
                     break;
+                case OffsetDateTime:
+                    if (i.argName == null) {
+                        select.argOffsetDateTime((OffsetDateTime) i.arg);
+                    } else {
+                        select.argOffsetDateTime(i.argName, (OffsetDateTime) i.arg);
+                    }
+                    break;
                 case LocalDateTimeNowPerDb:
                     if (i.argName == null) {
                         select.argLocalDateTimeNowPerDb();
@@ -323,6 +363,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
                         select.argLocalDateTimeNowPerDb(i.argName);
                     }
                     break;
+                case OffsetDateTimeNowPerDb:
+                    if (i.argName == null) {
+                        select.argOffsetDateTimeNowPerDb();
+                    } else {
+                        select.argOffsetDateTimeNowPerDb(i.argName);
+                    }
+                    break;
             }
         }
     }
@@ -416,6 +463,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
                         insert.argLocalDate(i.argName, (LocalDate) i.arg);
                     }
                     break;
+                case LocalTime:
+                    if (i.argName == null) {
+                        insert.argLocalTime((LocalTime) i.arg);
+                    } else {
+                        insert.argLocalTime(i.argName, (LocalTime) i.arg);
+                    }
+                    break;
                 case LocalDateTime:
                     if (i.argName == null) {
                         insert.argLocalDateTime((LocalDateTime) i.arg);
@@ -430,6 +484,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
                         insert.argLocalDateTimeNowPerDb(i.argName);
                     }
                     break;
+                case OffsetDateTimeNowPerDb:
+                    if (i.argName == null) {
+                        insert.argOffsetDateTimeNowPerDb();
+                    } else {
+                        insert.argOffsetDateTimeNowPerDb(i.argName);
+                    }
+                    break;
             }
         }
     }
@@ -523,6 +584,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
                         update.argLocalDate(i.argName, (LocalDate) i.arg);
                     }
                     break;
+                case LocalTime:
+                    if (i.argName == null) {
+                        update.argLocalTime((LocalTime) i.arg);
+                    } else {
+                        update.argLocalTime(i.argName, (LocalTime) i.arg);
+                    }
+                    break;
                 case LocalDateTime:
                     if (i.argName == null) {
                         update.argLocalDateTime((LocalDateTime) i.arg);
@@ -537,6 +605,13 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
                         update.argLocalDateTimeNowPerDb(i.argName);
                     }
                     break;
+                case OffsetDateTimeNowPerDb:
+                    if (i.argName == null) {
+                        update.argOffsetDateTimeNowPerDb();
+                    } else {
+                        update.argOffsetDateTimeNowPerDb(i.argName);
+                    }
+                    break;
             }
         }
     }
@@ -572,8 +647,11 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
         BlobBytes,
         BlobStream,
         LocalDate,
+        LocalTime,
         LocalDateTime,
-        LocalDateTimeNowPerDb
+        LocalDateTimeNowPerDb,
+        OffsetDateTime,
+        OffsetDateTimeNowPerDb
     }
 
     private static class Invocation {
@@ -691,15 +769,15 @@ public class SqlArgs implements SqlInsert.Apply, SqlUpdate.Apply, SqlSelect.Appl
                         args.argLocalDate(names[i], r.getLocalDateOrNull());
                         break;
                     case Types.TIMESTAMP:
-                    case Types.TIMESTAMP_WITH_TIMEZONE:
                         if (this.scale[i] == 0) {
-                            // If the scale is 0, this is a LocalDate (no time/timezone).
-                            // Anything with a time will have a non-zero scale
                             args.argLocalDate(names[i], r.getLocalDateOrNull());
                         } else {
                             args.argLocalDateTime(names[i], r.getLocalDateTimeOrNull());
                         }
                         break;
+                    case Types.TIMESTAMP_WITH_TIMEZONE:
+                        args.argOffsetDateTime(names[i], r.getOffsetDateTimeOrNull());
+                        break;
                     case Types.NVARCHAR:
                     case Types.VARCHAR:
                     case Types.CHAR:
diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsert.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsert.java
index a5a3cf0..732a374 100644
--- a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsert.java
+++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsert.java
@@ -5,6 +5,7 @@ import java.io.Reader;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.OffsetDateTime;
 
 /**
@@ -40,6 +41,14 @@ public interface SqlInsert {
 
     SqlInsert argString( String argName, String arg);
 
+    SqlInsert argLocalDate(LocalDate arg);
+
+    SqlInsert argLocalDate(String argName, LocalDate arg);
+
+    SqlInsert argLocalTime(LocalTime arg);
+
+    SqlInsert argLocalTime(String argName, LocalTime arg);
+
     SqlInsert argLocalDateTime(LocalDateTime arg);
 
     SqlInsert argLocalDateTime(String argName, LocalDateTime arg);
@@ -48,10 +57,6 @@ public interface SqlInsert {
 
     SqlInsert argOffsetDateTime(String argName, OffsetDateTime arg);
 
-    SqlInsert argLocalDate(LocalDate arg);
-
-    SqlInsert argLocalDate( String argName, LocalDate arg);
-
     SqlInsert argLocalDateTimeNowPerDb();
 
     SqlInsert argLocalDateTimeNowPerDb(String argName);
diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsertImpl.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsertImpl.java
index 33ad160..b8817d5 100644
--- a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsertImpl.java
+++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlInsertImpl.java
@@ -1,6 +1,7 @@
 package org.xbib.jdbc.query;
 
 import java.sql.Types;
+import java.time.LocalTime;
 import org.xbib.jdbc.query.util.DebugSql;
 import org.xbib.jdbc.query.util.InternalStringReader;
 import org.xbib.jdbc.query.util.Metric;
@@ -152,13 +153,23 @@ public class SqlInsertImpl implements SqlInsert {
     }
 
     @Override
-    public SqlInsert argLocalDate( String argName, LocalDate arg) {
+    public SqlInsert argLocalDate(LocalDate arg) {
+        return positionalArg(adaptor.nullLocalDate(arg));
+    }
+
+    @Override
+    public SqlInsert argLocalDate(String argName, LocalDate arg) {
         return namedArg(argName, adaptor.nullLocalDate(arg));
     }
 
     @Override
-    public SqlInsert argLocalDate(LocalDate arg) {
-        return positionalArg(adaptor.nullLocalDate(arg));
+    public SqlInsert argLocalTime(LocalTime arg) {
+        return positionalArg(adaptor.nullLocalTime(arg));
+    }
+
+    @Override
+    public SqlInsert argLocalTime(String argName, LocalTime arg) {
+        return namedArg(argName, adaptor.nullLocalTime(arg));
     }
 
     @Override
diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlSelect.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlSelect.java
index 5e43590..563384f 100644
--- a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlSelect.java
+++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlSelect.java
@@ -3,6 +3,7 @@ package org.xbib.jdbc.query;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.OffsetDateTime;
 import java.util.List;
 
@@ -39,6 +40,14 @@ public interface SqlSelect {
 
     SqlSelect argString( String argName, String arg);
 
+    SqlSelect argLocalDate(LocalDate arg);
+
+    SqlSelect argLocalDate(String argName, LocalDate arg);
+
+    SqlSelect argLocalTime(LocalTime arg);
+
+    SqlSelect argLocalTime(String argName, LocalTime arg);
+
     SqlSelect argLocalDateTime(LocalDateTime arg);
 
     SqlSelect argLocalDateTime(String argName, LocalDateTime arg);
@@ -47,10 +56,6 @@ public interface SqlSelect {
 
     SqlSelect argOffsetDateTime(String argName, OffsetDateTime arg);
 
-    SqlSelect argLocalDate(LocalDate arg);
-
-    SqlSelect argLocalDate(String argName, LocalDate arg);
-
     SqlSelect argLocalDateTimeNowPerDb();
 
     SqlSelect argLocalDateTimeNowPerDb(String argName);
diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlSelectImpl.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlSelectImpl.java
index fa8b713..0262b2c 100644
--- a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlSelectImpl.java
+++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlSelectImpl.java
@@ -1,5 +1,6 @@
 package org.xbib.jdbc.query;
 
+import java.time.LocalTime;
 import org.xbib.jdbc.query.util.DebugSql;
 import org.xbib.jdbc.query.util.Metric;
 import org.xbib.jdbc.query.util.RewriteArg;
@@ -165,6 +166,16 @@ public class SqlSelectImpl implements SqlSelect {
         return namedArg(argName, adaptor.nullLocalDate(arg));
     }
 
+    @Override
+    public SqlSelect argLocalTime(LocalTime arg) {
+        return positionalArg(adaptor.nullLocalTime(arg));
+    }
+
+    @Override
+    public SqlSelect argLocalTime(String argName, LocalTime arg) {
+        return namedArg(argName, adaptor.nullLocalTime(arg));
+    }
+
     @Override
     public SqlSelect argLocalDateTimeNowPerDb() {
         if (options.useClientClock()) {
diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlUpdate.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlUpdate.java
index d1f75cd..eb75278 100644
--- a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlUpdate.java
+++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlUpdate.java
@@ -5,6 +5,7 @@ import java.io.Reader;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.OffsetDateTime;
 
 /**
@@ -39,7 +40,15 @@ public interface SqlUpdate {
     SqlUpdate argString(String arg);
     
     SqlUpdate argString(String argName, String arg);
-    
+
+    SqlUpdate argLocalDate(LocalDate arg);
+
+    SqlUpdate argLocalDate(String argName, LocalDate arg);
+
+    SqlUpdate argLocalTime(LocalTime arg);
+
+    SqlUpdate argLocalTime(String argName, LocalTime arg);
+
     SqlUpdate argLocalDateTime(LocalDateTime arg);
     
     SqlUpdate argLocalDateTime(String argName, LocalDateTime arg);
@@ -48,17 +57,13 @@ public interface SqlUpdate {
 
     SqlUpdate argOffsetDateTime(String argName, OffsetDateTime arg);
 
-    SqlUpdate argLocalDate(LocalDate arg);
-
-    SqlUpdate argLocalDate(String argName, LocalDate arg);
-
     SqlUpdate argLocalDateTimeNowPerDb();
 
     SqlUpdate argLocalDateTimeNowPerDb(String argName);
 
-    SqlUpdate argOffsetDateTimePerDb();
+    SqlUpdate argOffsetDateTimeNowPerDb();
 
-    SqlUpdate argOffsetDateTimePerDb(String argName);
+    SqlUpdate argOffsetDateTimeNowPerDb(String argName);
 
     SqlUpdate argBlobBytes(byte[] arg);
 
diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlUpdateImpl.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlUpdateImpl.java
index 0b4c6e1..377a20b 100644
--- a/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlUpdateImpl.java
+++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/SqlUpdateImpl.java
@@ -2,6 +2,7 @@ package org.xbib.jdbc.query;
 
 import java.sql.Statement;
 import java.sql.Types;
+import java.time.LocalTime;
 import java.time.OffsetDateTime;
 import org.xbib.jdbc.query.util.DebugSql;
 import org.xbib.jdbc.query.util.InternalStringReader;
@@ -151,6 +152,16 @@ public class SqlUpdateImpl implements SqlUpdate {
         return namedArg(argName, adaptor.nullLocalDate(arg));
     }
 
+    @Override
+    public SqlUpdate argLocalTime(LocalTime arg) {
+        return positionalArg(adaptor.nullLocalTime(arg));
+    }
+
+    @Override
+    public SqlUpdate argLocalTime(String argName, LocalTime arg) {
+        return namedArg(argName, adaptor.nullLocalTime(arg));
+    }
+
     @Override
     public SqlUpdate argLocalDateTimeNowPerDb() {
         if (options.useClientClock()) {
@@ -168,7 +179,7 @@ public class SqlUpdateImpl implements SqlUpdate {
     }
 
     @Override
-    public SqlUpdate argOffsetDateTimePerDb() {
+    public SqlUpdate argOffsetDateTimeNowPerDb() {
         if (options.useClientClock()) {
             return positionalArg(adaptor.nullOffsetDateTime(OffsetDateTime.now()));
         }
@@ -176,7 +187,7 @@ public class SqlUpdateImpl implements SqlUpdate {
     }
 
     @Override
-    public SqlUpdate argOffsetDateTimePerDb(String argName) {
+    public SqlUpdate argOffsetDateTimeNowPerDb(String argName) {
         if (options.useClientClock()) {
             return namedArg(argName, adaptor.nullOffsetDateTime(OffsetDateTime.now()));
         }
diff --git a/jdbc-query/src/main/java/org/xbib/jdbc/query/StatementAdapter.java b/jdbc-query/src/main/java/org/xbib/jdbc/query/StatementAdapter.java
index c5c350b..a090fcd 100644
--- a/jdbc-query/src/main/java/org/xbib/jdbc/query/StatementAdapter.java
+++ b/jdbc-query/src/main/java/org/xbib/jdbc/query/StatementAdapter.java
@@ -13,6 +13,7 @@ import java.sql.Timestamp;
 import java.sql.Types;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.OffsetDateTime;
 import java.time.ZoneId;
 import java.util.Date;
@@ -106,6 +107,10 @@ public class StatementAdapter {
         return arg == null ? new SqlNull(Types.DATE) : java.sql.Date.valueOf(arg);
     }
 
+    public Object nullLocalTime(LocalTime arg) {
+        return arg == null ? new SqlNull(Types.TIME) : java.sql.Time.valueOf(arg);
+    }
+
     public Object nullNumeric(Number arg) {
         if (arg == null) {
             return new SqlNull(Types.NUMERIC);