Skip to content

Conversation

ymmt2005
Copy link
Contributor

Description

parseTime=true cannot parse TIMESTAMP columns and has a subtle limitation.
mysql.NullTime is a great alternative to that option, so I think it is worth mentioning.

Checklist

  • Code compiles correctly
  • Created tests which fail without the change (if possible)
  • All tests passing
  • Extended the README / documentation, if necessary
  • Added myself / the copyright holder to the AUTHORS file

`parseTime=true` cannot parse `TIMESTAMP` columns and has a subtle limitation.
`mysql.NullTime` is a great alternative to that option, so I think it is worth mentioning.
@shogo82148
Copy link
Contributor

mysql.NullTime will be deprecated, so I recommend using sql.NullTime and the parseTime=true DSN option.

mysql/nulltime_go113.go

Lines 32 to 34 in e246959

// Deprecated: NullTime doesn't honor the loc DSN parameter.
// NullTime.Scan interprets a time as UTC, not the loc DSN parameter.
// Use sql.NullTime instead.

parseTime=true cannot parse TIMESTAMP columns and has a subtle limitation.

Can you show me some examples about it ?
The driver can parse TIMESTAMP and it is tested.

mysql/driver_test.go

Lines 1551 to 1588 in 4d5208a

func TestTimezoneConversion(t *testing.T) {
zones := []string{"UTC", "US/Central", "US/Pacific", "Local"}
// Regression test for timezone handling
tzTest := func(dbt *DBTest) {
// Create table
dbt.mustExec("CREATE TABLE test (ts TIMESTAMP)")
// Insert local time into database (should be converted)
usCentral, _ := time.LoadLocation("US/Central")
reftime := time.Date(2014, 05, 30, 18, 03, 17, 0, time.UTC).In(usCentral)
dbt.mustExec("INSERT INTO test VALUE (?)", reftime)
// Retrieve time from DB
rows := dbt.mustQuery("SELECT ts FROM test")
defer rows.Close()
if !rows.Next() {
dbt.Fatal("did not get any rows out")
}
var dbTime time.Time
err := rows.Scan(&dbTime)
if err != nil {
dbt.Fatal("Err", err)
}
// Check that dates match
if reftime.Unix() != dbTime.Unix() {
dbt.Errorf("times do not match.\n")
dbt.Errorf(" Now(%v)=%v\n", usCentral, reftime)
dbt.Errorf(" Now(UTC)=%v\n", dbTime)
}
}
for _, tz := range zones {
runTests(t, dsn+"&parseTime=true&loc="+url.QueryEscape(tz), tzTest)
}
}

@ymmt2005
Copy link
Contributor Author

ymmt2005 commented Mar 30, 2021

@shogo82148
Thank you for letting me know.

I couldn't notice the deprecation because it is noted only for Go 1.13.
With Go 1.16 (and pkg.go.dev), NullTime doesn't show the deprecation notice.

Anyway, I'm closing this.

$ go version
go version go1.16.2 linux/amd64

$ go doc github.com/go-sql-driver/mysql.NullTime
package mysql // import "github.com/go-sql-driver/mysql"

type NullTime sql.NullTime
    NullTime represents a time.Time that may be NULL. NullTime implements the
    Scanner interface so it can be used as a scan destination:

        var nt NullTime
        err := db.QueryRow("SELECT time FROM foo WHERE id=?", id).Scan(&nt)
        ...
        if nt.Valid {
           // use nt.Time
        } else {
           // NULL value
        }

    This NullTime implementation is not driver-specific

func (nt *NullTime) Scan(value interface{}) (err error)
func (nt NullTime) Value() (driver.Value, error)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants