Skip to content

Commit

Permalink
Add EPOCH_DAY as possible date storage format
Browse files Browse the repository at this point in the history
  • Loading branch information
gwenn committed Apr 27, 2024
1 parent 2269f05 commit 3f766bc
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 12 deletions.
14 changes: 11 additions & 3 deletions src/main/java/org/sqlite/driver/DateUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.temporal.ChronoField;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
Expand All @@ -23,9 +24,16 @@
import java.util.TimeZone;

final class DateUtil {
static final int DATE_CONFIG = 0;
public static final String DATE_FORMAT = "date_format";
static final int TIME_CONFIG = 1;
public static final String TIME_FORMAT = "time_format";
static final int TIMESTAMP_CONFIG = 2;
public static final String TIMESTAMP_FORMAT = "timestamp_format";
/**
* {@link ChronoField#EPOCH_DAY}
*/
public static final String EPOCH_DAY = "epochday";
public static final String JULIANDAY = "julianday";
public static final String UNIXEPOCH = "unixepoch";
public static final String YYYY_MM_DD = "yyyy-MM-dd"; // See java.sql.Date.toString()
Expand All @@ -43,9 +51,9 @@ static String[] config(Properties info) {
return new String[]{YYYY_MM_DD, HH_MM_SS, DEFAULT_FORMAT};
}
final String[] config = new String[3];
config[0] = info.getProperty(DATE_FORMAT, YYYY_MM_DD);
config[1] = info.getProperty(TIME_FORMAT, HH_MM_SS);
config[2] = info.getProperty(TIMESTAMP_FORMAT, DEFAULT_FORMAT);
config[DATE_CONFIG] = info.getProperty(DATE_FORMAT, YYYY_MM_DD);
config[TIME_CONFIG] = info.getProperty(TIME_FORMAT, HH_MM_SS);
config[TIMESTAMP_CONFIG] = info.getProperty(TIMESTAMP_FORMAT, DEFAULT_FORMAT);
return config;
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/sqlite/driver/JDBC.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
encoding.choices = new String[]{"UTF-8", "UTF-16", "UTF-16le", "UTF-16be"};

final DriverPropertyInfo df = new DriverPropertyInfo(DateUtil.DATE_FORMAT, info == null ? null : info.getProperty(DateUtil.DATE_FORMAT));
df.description = "Specify the format used to persist date ('" + DateUtil.JULIANDAY + "', '" + DateUtil.UNIXEPOCH + "', 'yyyy-MM-dd', '...').";
df.description = "Specify the format used to persist date ('" + DateUtil.EPOCH_DAY + "', '" + DateUtil.JULIANDAY + "', '" + DateUtil.UNIXEPOCH + "', 'yyyy-MM-dd', '...').";
final DriverPropertyInfo tf = new DriverPropertyInfo(DateUtil.TIME_FORMAT, info == null ? null : info.getProperty(DateUtil.TIME_FORMAT));
tf.description = "Specify the format used to persist time ('" + DateUtil.JULIANDAY + "', '" + DateUtil.UNIXEPOCH + "', 'HH:mm:ss.SSSXXX', '...').";
final DriverPropertyInfo tsf = new DriverPropertyInfo(DateUtil.TIMESTAMP_FORMAT, info == null ? null : info.getProperty(DateUtil.TIMESTAMP_FORMAT));
Expand Down
15 changes: 9 additions & 6 deletions src/main/java/org/sqlite/driver/PrepStmt.java
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ public void setBytes(String parameterName, byte[] x) throws SQLException {

@Override
public void setDate(int parameterIndex, Date x) throws SQLException {
bindDate(parameterIndex, x, 0);
bindDate(parameterIndex, x, DateUtil.DATE_CONFIG);
}
@Override
public void setDate(String parameterName, Date x) throws SQLException {
Expand All @@ -261,10 +261,13 @@ private void bindDate(int parameterIndex, java.util.Date x, int cfgIdx) throws S
bindNull(parameterIndex);
} else {
final String fmt = conn().dateTimeConfig[cfgIdx];
if (fmt == null || DateUtil.UNIXEPOCH.equals(fmt)) {
bindLong(parameterIndex, cfgIdx == 0 ? DateUtil.normalizeDate(x.getTime(), null) : x.getTime());
final boolean sqlDate = cfgIdx == DateUtil.DATE_CONFIG;
if (sqlDate && DateUtil.EPOCH_DAY.equals(fmt)) {
bindLong(parameterIndex, ((java.sql.Date)x).toLocalDate().toEpochDay());
} else if (fmt == null || DateUtil.UNIXEPOCH.equals(fmt)) {
bindLong(parameterIndex, sqlDate ? DateUtil.normalizeDate(x.getTime(), null) : x.getTime());
} else if (DateUtil.JULIANDAY.equals(fmt)) {
final long unixepoch = cfgIdx == 0 ? DateUtil.normalizeDate(x.getTime(), null) : x.getTime();
final long unixepoch = sqlDate ? DateUtil.normalizeDate(x.getTime(), null) : x.getTime();
bindDouble(parameterIndex, DateUtil.toJulianDay(unixepoch));
} else {
bindText(parameterIndex, DateUtil.formatDate(x, fmt, null));
Expand All @@ -274,7 +277,7 @@ private void bindDate(int parameterIndex, java.util.Date x, int cfgIdx) throws S

@Override
public void setTime(int parameterIndex, Time x) throws SQLException {
bindDate(parameterIndex, x, 1);
bindDate(parameterIndex, x, DateUtil.TIME_CONFIG);
}
@Override
public void setTime(String parameterName, Time x) throws SQLException {
Expand All @@ -283,7 +286,7 @@ public void setTime(String parameterName, Time x) throws SQLException {

@Override
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
bindDate(parameterIndex, x, 2);
bindDate(parameterIndex, x, DateUtil.TIMESTAMP_CONFIG);
}
@Override
public void setTimestamp(String parameterName, Timestamp x) throws SQLException {
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/org/sqlite/driver/Rows.java
Original file line number Diff line number Diff line change
Expand Up @@ -905,8 +905,11 @@ public Date getDate(int columnIndex, Calendar cal) throws SQLException {
final String txt = stmt.getColumnText(fixCol(columnIndex));
return DateUtil.toDate(txt, cal);
case ColTypes.SQLITE_INTEGER:
final long unixepoch = stmt.getColumnLong(fixCol(columnIndex));
return DateUtil.toDate(unixepoch, cal);
final long l = stmt.getColumnLong(fixCol(columnIndex));
if (cal == null && DateUtil.EPOCH_DAY.equals(s.conn().dateTimeConfig[DateUtil.DATE_CONFIG])) {
return Date.valueOf(LocalDate.ofEpochDay(l));
}
return DateUtil.toDate(l, cal);
case ColTypes.SQLITE_FLOAT: // does not work as expected if column affinity is REAL but inserted value was an integer
final double jd = stmt.getColumnDouble(fixCol(columnIndex));
return DateUtil.toDate(jd, cal);
Expand Down

0 comments on commit 3f766bc

Please sign in to comment.