@@ -13,6 +13,7 @@ import (
1313 "log/slog"
1414 "os"
1515 "path/filepath"
16+ "strings"
1617 "time"
1718
1819 lru "github.com/hashicorp/golang-lru/v2"
@@ -278,6 +279,26 @@ func initialize(schema string) (filename string, err error) {
278279 return schemaFilename , nil
279280}
280281
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+
281302func parseSqliteDate (d any ) (* time.Time , error ) {
282303 if date , ok := d .(* time.Time ); ok {
283304 return date , nil
@@ -288,14 +309,20 @@ func parseSqliteDate(d any) (*time.Time, error) {
288309 return nil , fmt .Errorf ("invalid date type: %T" , d )
289310 }
290311
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
295315
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 {}
299326 }
300327
301328 return & t , nil
0 commit comments