package convert import ( "fmt" "strconv" "strings" "time" ) var defaultNullTimeLayouts = []string{ time.RFC3339Nano, time.RFC3339, "2006-01-02 15:04:05", "2006-01-02", } // ToInt64 converts any value to int64. func ToInt64(val interface{}) int64 { switch v := val.(type) { case nil: return 0 case int: return int64(v) case int32: return int64(v) case int64: return v case uint64: return int64(v) case float32: return int64(v) case float64: return int64(v) case string: result, _ := strconv.ParseInt(v, 10, 64) return result case bool: if v { return 1 } return 0 case time.Time: return v.Unix() case []byte: result, _ := strconv.ParseInt(string(v), 10, 64) return result default: return 0 } } // ToUint64 converts any value to uint64. func ToUint64(val interface{}) uint64 { switch v := val.(type) { case nil: return 0 case int: return uint64(v) case int32: return uint64(v) case int64: return uint64(v) case uint64: return v case float32: return uint64(v) case float64: return uint64(v) case string: result, _ := strconv.ParseUint(v, 10, 64) return result case bool: if v { return 1 } return 0 case time.Time: return uint64(v.Unix()) case []byte: result, _ := strconv.ParseUint(string(v), 10, 64) return result default: return 0 } } // ToFloat64 converts any value to float64. func ToFloat64(val interface{}) float64 { switch v := val.(type) { case nil: return 0 case int: return float64(v) case int32: return float64(v) case int64: return float64(v) case uint64: return float64(v) case float32: return float64(v) case float64: return v case string: result, _ := strconv.ParseFloat(v, 64) return result case bool: if v { return 1 } return 0 case time.Time: return float64(v.Unix()) case []byte: result, _ := strconv.ParseFloat(string(v), 64) return result default: return 0 } } // ToBool converts any value to bool. func ToBool(val interface{}) bool { switch v := val.(type) { case nil: return false case bool: return v case int: return v != 0 case int32: return v != 0 case int64: return v != 0 case uint64: return v != 0 case float32: return v != 0 case float64: return v != 0 case string: result, _ := strconv.ParseBool(v) return result case []byte: result, _ := strconv.ParseBool(string(v)) return result default: return false } } // ToTime converts any value to time.Time. func ToTime(val interface{}, layout string) time.Time { switch v := val.(type) { case nil: return time.Time{} case time.Time: return v case int: return time.Unix(int64(v), 0) case int32: return time.Unix(int64(v), 0) case int64: return time.Unix(v, 0) case uint64: return time.Unix(int64(v), 0) case float32: sec := int64(v) nsec := int64((v - float32(sec)) * 1e9) return time.Unix(sec, nsec) case float64: sec := int64(v) nsec := int64((v - float64(sec)) * 1e9) return time.Unix(sec, nsec) case string: result, _ := time.Parse(layout, v) return result case []byte: result, _ := time.Parse(layout, string(v)) return result default: return time.Time{} } } // ToInt64Safe converts any value to int64 with error handling. func ToInt64Safe(val interface{}) (int64, error) { switch v := val.(type) { case nil: return 0, nil case int: return int64(v), nil case int32: return int64(v), nil case int64: return v, nil case uint64: return int64(v), nil case float32: return int64(v), nil case float64: return int64(v), nil case string: return strconv.ParseInt(v, 10, 64) case bool: if v { return 1, nil } return 0, nil case time.Time: return v.Unix(), nil case []byte: return strconv.ParseInt(string(v), 10, 64) default: return 0, fmt.Errorf("cannot convert %T to int64", val) } } // ToStringSafe converts any value to string with error handling. func ToStringSafe(val interface{}) (string, error) { switch v := val.(type) { case nil: return "", nil case string: return v, nil case int: return strconv.Itoa(v), nil case int32: return strconv.FormatInt(int64(v), 10), nil case int64: return strconv.FormatInt(v, 10), nil case float32: return strconv.FormatFloat(float64(v), 'f', -1, 32), nil case float64: return strconv.FormatFloat(v, 'f', -1, 64), nil case bool: return strconv.FormatBool(v), nil case time.Time: return v.String(), nil case []byte: return string(v), nil default: return "", fmt.Errorf("cannot convert %T to string", val) } } // ToFloat64Safe converts any value to float64 with error handling. func ToFloat64Safe(val interface{}) (float64, error) { switch v := val.(type) { case nil: return 0, nil case float64: return v, nil case float32: return float64(v), nil case int, int32, int64, uint64: intVal, err := ToInt64Safe(v) return float64(intVal), err case string: return strconv.ParseFloat(v, 64) case []byte: return strconv.ParseFloat(string(v), 64) default: return 0, fmt.Errorf("cannot convert %T to float64", val) } } // ToBoolSafe converts any value to bool with error handling. func ToBoolSafe(val interface{}) (bool, error) { switch v := val.(type) { case nil: return false, nil case bool: return v, nil case int: return v != 0, nil case int8: return v != 0, nil case int16: return v != 0, nil case int32: return v != 0, nil case int64: return v != 0, nil case uint: return v != 0, nil case uint8: return v != 0, nil case uint16: return v != 0, nil case uint32: return v != 0, nil case uint64: return v != 0, nil case float32: return v != 0, nil case float64: return v != 0, nil case string: return ParseBoolString(v) case []byte: return ParseBoolString(string(v)) default: return false, fmt.Errorf("cannot convert %T to bool", val) } } // ParseBoolString parses string-like bool values. func ParseBoolString(raw string) (bool, error) { normalized := strings.TrimSpace(strings.ToLower(raw)) switch normalized { case "", "0", "false", "f", "off", "no", "n": return false, nil case "1", "true", "t", "on", "yes", "y": return true, nil default: return false, fmt.Errorf("cannot parse bool value: %q", raw) } } // ToTimeSafe converts any value to time.Time with error handling. func ToTimeSafe(val interface{}) (time.Time, error) { switch v := val.(type) { case nil: return time.Time{}, nil case time.Time: return v, nil case int: return time.Unix(int64(v), 0), nil case int64: return time.Unix(v, 0), nil case string: return ParseTimeValue(v) case []byte: return ParseTimeValue(string(v)) default: return time.Time{}, fmt.Errorf("cannot convert %T to time.Time", val) } } // ParseTimeValue parses common SQL date-time formats and unix timestamp. func ParseTimeValue(raw string) (time.Time, error) { trimmed := strings.TrimSpace(raw) if trimmed == "" { return time.Time{}, nil } for _, layout := range defaultNullTimeLayouts { if t, err := time.Parse(layout, trimmed); err == nil { return t, nil } } if ts, err := strconv.ParseInt(trimmed, 10, 64); err == nil { return time.Unix(ts, 0), nil } return time.Time{}, fmt.Errorf("cannot parse time value: %q", raw) }