Skip to content

Commit

Permalink
Normalize source string when parsing 2 (#620)
Browse files Browse the repository at this point in the history
* Normalize source string when parsing 

The regex used to parse dates does not account for the fact that new dates created by SQLite's CURRENT_TIMESTAMP do not include millisecond information. The regex used by the date parser tries to find a string matching "yyyy-MM-dd HH:mm:ss.SSS" but the dates created by SQLite do not include the milliseconds (.SSS) so the date strings are not matching and this is causing the parser to return null. The solution is to detect this exact case (string length is exactly 19) and then append .000 to the source string. This causes the regex to match on the string. allowing the date string to be parsed, and the Date object to be returned. The source object is not mutated, and the extra characters do not change the DATETIME represented by the date string, so I think this is a safe fix.

* Add unit test for default datetime

* Bug fix to newly added StatementTest unit test

* Update StatementTest.java
  • Loading branch information
davidjpfeiffer committed Jun 29, 2021
1 parent 7d72e04 commit ad37c52
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/main/java/org/sqlite/date/FastDateParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -288,15 +288,16 @@ public Object parseObject(final String source) throws ParseException {
* @see org.apache.commons.lang3.time.DateParser#parse(java.lang.String)
*/
public Date parse(final String source) throws ParseException {
final Date date= parse(source, new ParsePosition(0));
String normalizedSource = source.length() == 19 ? (source + ".000") : source;
final Date date= parse(normalizedSource, new ParsePosition(0));
if(date==null) {
// Add a note re supported date range
if (locale.equals(JAPANESE_IMPERIAL)) {
throw new ParseException(
"(The " +locale + " locale does not support dates before 1868 AD)\n" +
"Unparseable date: \""+source+"\" does not match "+parsePattern.pattern(), 0);
"Unparseable date: \""+normalizedSource+"\" does not match "+parsePattern.pattern(), 0);
}
throw new ParseException("Unparseable date: \""+source+"\" does not match "+parsePattern.pattern(), 0);
throw new ParseException("Unparseable date: \""+normalizedSource+"\" does not match "+parsePattern.pattern(), 0);
}
return date;
}
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/org/sqlite/StatementTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,18 @@ public void dateTimeTest() throws SQLException {
Date d = rs.getDate(1);
assertEquals(day.getTime(), d.getTime());
}

@Test
public void defaultDateTimeTest() throws SQLException {
stat.executeUpdate("create table daywithdefaultdatetime (id integer, datetime datatime default current_timestamp)");
PreparedStatement prep = conn.prepareStatement("insert into daywithdefaultdatetime (id) values (?)");
prep.setInt(1, 1);
prep.executeUpdate();
ResultSet rs = stat.executeQuery("select * from daywithdefaultdatetime");
assertTrue(rs.next());
Date d = rs.getDate(2);
assertTrue(d != null);
}

@Test
public void maxRows() throws SQLException {
Expand Down

0 comments on commit ad37c52

Please sign in to comment.