{"id":"966cc21fab4a54e9","repo":"go-sql-driver/mysql","slug":"can-t-convert-t-to-time-time","errorCode":null,"errorMessage":"can't convert %T to time.Time","messagePattern":"can't convert %T to time\\.Time","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nulltime.go","lineNumber":62,"sourceCode":"\t\treturn\n\t}\n\n\tswitch v := value.(type) {\n\tcase time.Time:\n\t\tnt.Time, nt.Valid = v, true\n\t\treturn\n\tcase []byte:\n\t\tnt.Time, err = parseDateTime(v, time.UTC)\n\t\tnt.Valid = (err == nil)\n\t\treturn\n\tcase string:\n\t\tnt.Time, err = parseDateTime([]byte(v), time.UTC)\n\t\tnt.Valid = (err == nil)\n\t\treturn\n\t}\n\n\tnt.Valid = false\n\treturn fmt.Errorf(\"can't convert %T to time.Time\", value)\n}\n\n// Value implements the driver Valuer interface.\nfunc (nt NullTime) Value() (driver.Value, error) {\n\tif !nt.Valid {\n\t\treturn nil, nil\n\t}\n\treturn nt.Time, nil\n}\n","sourceCodeStart":44,"sourceCodeEnd":72,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/c426bd93799de0f0e094c8f0582872c529d0ed0a/nulltime.go#L44-L72","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Switch the scan target to the standard library sql.NullTime, which integrates with the driver's parseTime path.","Set parseTime=true in the DSN so TIME/DATETIME columns are delivered as time.Time.","If the source is a numeric epoch, scan into an int64/sql.NullInt64 and convert to time manually."],"exampleFix":"// before\nvar nt mysql.NullTime\ndb.QueryRow(\"SELECT created_at FROM t WHERE id=?\", id).Scan(&nt)\n\n// after — standard library type, works with parseTime=true\nvar nt sql.NullTime\ndb.QueryRow(\"SELECT created_at FROM t WHERE id=?\", id).Scan(&nt)","handlingStrategy":"type-guard","validationCode":"// ensure the DSN decodes time columns to time.Time\ndb, err := sql.Open(\"mysql\", \"user:pass@/db?parseTime=true\")\nif err != nil { return err }","typeGuard":"switch value.(type) {\ncase time.Time, []byte, string, nil:\n    var nt mysql.NullTime\n    _ = nt.Scan(value) // accepted by Scan\ndefault:\n    return fmt.Errorf(\"NullTime.Scan does not accept %T\", value)\n}","tryCatchPattern":"var nt mysql.NullTime\nif err := rows.Scan(&nt); err != nil {\n    if strings.Contains(err.Error(), \"can't convert\") {\n        // source column is not a time/[]byte/string; scan into a matching type instead\n    }\n}","preventionTips":["Prefer the standard sql.NullTime over mysql.NullTime.","Set parseTime=true in the DSN for any TIME/DATETIME columns.","Match the Scan destination type to the actual column type."],"tags":["types","time","scan","deprecated"],"analyzedSha":"c426bd93799de0f0e094c8f0582872c529d0ed0a","analyzedAt":"2026-08-04T21:52:59.219Z","schemaVersion":2}