go-sql-driver/mysql · error

can't convert %T to time.Time

Error message

can't convert %T to time.Time

What it means

Returned by the deprecated NullTime.Scan (nulltime.go:62) when the scanned value is not time.Time, []byte, or string. NullTime is deprecated in favor of sql.NullTime; its Scan only accepts those three types and interprets times as UTC, ignoring the loc DSN parameter. Any other concrete type (e.g. an int64 epoch value) reaches the final fmt.Errorf.

Source

Thrown at nulltime.go:62

		return
	}

	switch v := value.(type) {
	case time.Time:
		nt.Time, nt.Valid = v, true
		return
	case []byte:
		nt.Time, err = parseDateTime(v, time.UTC)
		nt.Valid = (err == nil)
		return
	case string:
		nt.Time, err = parseDateTime([]byte(v), time.UTC)
		nt.Valid = (err == nil)
		return
	}

	nt.Valid = false
	return fmt.Errorf("can't convert %T to time.Time", value)
}

// Value implements the driver Valuer interface.
func (nt NullTime) Value() (driver.Value, error) {
	if !nt.Valid {
		return nil, nil
	}
	return nt.Time, nil
}

View on GitHub (pinned to c426bd9379)

Solutions

  1. Switch the scan target to the standard library sql.NullTime, which integrates with the driver's parseTime path.
  2. Set parseTime=true in the DSN so TIME/DATETIME columns are delivered as time.Time.
  3. If the source is a numeric epoch, scan into an int64/sql.NullInt64 and convert to time manually.

Example fix

// before
var nt mysql.NullTime
db.QueryRow("SELECT created_at FROM t WHERE id=?", id).Scan(&nt)

// after — standard library type, works with parseTime=true
var nt sql.NullTime
db.QueryRow("SELECT created_at FROM t WHERE id=?", id).Scan(&nt)
Defensive patterns

Strategy: type-guard

Validate before calling

// ensure the DSN decodes time columns to time.Time
db, err := sql.Open("mysql", "user:pass@/db?parseTime=true")
if err != nil { return err }

Type guard

switch value.(type) {
case time.Time, []byte, string, nil:
    var nt mysql.NullTime
    _ = nt.Scan(value) // accepted by Scan
default:
    return fmt.Errorf("NullTime.Scan does not accept %T", value)
}

Try / catch

var nt mysql.NullTime
if err := rows.Scan(&nt); err != nil {
    if strings.Contains(err.Error(), "can't convert") {
        // source column is not a time/[]byte/string; scan into a matching type instead
    }
}

Prevention

When it happens

Trigger: Scanning into a mysql.NullTime when the source column arrives as int64/float64 (e.g. a BIGINT timestamp column) rather than a time/[]byte/string; scanning a raw numeric or sql.Null* value into NullTime.

Common situations: Using mysql.NullTime instead of sql.NullTime; a column type changed from DATETIME to BIGINT; DSN lacks parseTime=true so a TIME column arrives as a non-time type that still is not one of the three accepted types.

Related errors


AI-assisted analysis of go-sql-driver/mysql@c426bd9379 (2026-08-04). Data as JSON: /data/errors/966cc21fab4a54e9.json. Report an issue: GitHub.