@@ -13,6 +13,7 @@ import (
13
13
"log/slog"
14
14
"os"
15
15
"path/filepath"
16
+ "strings"
16
17
"time"
17
18
18
19
lru "github.com/hashicorp/golang-lru/v2"
@@ -278,6 +279,26 @@ func initialize(schema string) (filename string, err error) {
278
279
return schemaFilename , nil
279
280
}
280
281
282
+ // SQLiteTimestampFormats is timestamp formats understood by both this module
283
+ // and SQLite. The first format in the slice will be used when saving time
284
+ // values into the database. When parsing a string from a timestamp or datetime
285
+ // column, the formats are tried in order.
286
+ //
287
+ // Reference: https://github.com/mattn/go-sqlite3/blob/348128fdcf102af8b9f51fb26ae41c4d7438f1ca/sqlite3.go#L224C1-L240C2
288
+ var SQLiteTimestampFormats = []string {
289
+ // By default, store timestamps with whatever timezone they come with.
290
+ // When parsed, they will be returned with the same timezone.
291
+ "2006-01-02 15:04:05.999999999-07:00" ,
292
+ "2006-01-02T15:04:05.999999999-07:00" ,
293
+ "2006-01-02 15:04:05.999999999" ,
294
+ "2006-01-02T15:04:05.999999999" ,
295
+ "2006-01-02 15:04:05" ,
296
+ "2006-01-02T15:04:05" ,
297
+ "2006-01-02 15:04" ,
298
+ "2006-01-02T15:04" ,
299
+ "2006-01-02" ,
300
+ }
301
+
281
302
func parseSqliteDate (d any ) (* time.Time , error ) {
282
303
if date , ok := d .(* time.Time ); ok {
283
304
return date , nil
@@ -288,14 +309,20 @@ func parseSqliteDate(d any) (*time.Time, error) {
288
309
return nil , fmt .Errorf ("invalid date type: %T" , d )
289
310
}
290
311
291
- t , err := time .Parse ("2006-01-02 15:04:05" , dateStr )
292
- if err == nil {
293
- return & t , nil
294
- }
312
+ var t time.Time // the parsed time value
313
+ var timeVal time.Time // temp variable to store the parsed time value
314
+ var err error
295
315
296
- t , err = time .Parse ("2006-01-02" , dateStr )
297
- if err == nil {
298
- return & t , nil
316
+ s := strings .TrimSuffix (dateStr , "Z" )
317
+ for _ , format := range SQLiteTimestampFormats {
318
+ if timeVal , err = time .ParseInLocation (format , s , time .UTC ); err == nil {
319
+ t = timeVal
320
+ break
321
+ }
322
+ }
323
+ if err != nil {
324
+ // The column is a time value, so return the zero time on parse failure.
325
+ t = time.Time {}
299
326
}
300
327
301
328
return & t , nil
0 commit comments